From 676722f4522c8de62242f8f4b984afe16e07f2e8 Mon Sep 17 00:00:00 2001 From: Anton Averchenkov <84287187+averche@users.noreply.github.com> Date: Fri, 12 Aug 2022 23:29:42 +0000 Subject: [PATCH] backport of commit c8c138f952ad4e72ebbf0fba61d42405c415746b --- .circleci/config.yml | 80 +- .circleci/config/commands/go_test.yml | 2 +- .circleci/config/commands/setup-semgrep.yml | 14 + .circleci/config/executors/@executors.yml | 29 +- .circleci/config/jobs/semgrep.yml | 3 +- .../config/jobs/test-ui-browserstack.yml | 13 + .circleci/config/jobs/test-ui.yml | 12 + .circleci/config/workflows/ci.yml | 12 +- .github/workflows/build.yml | 13 +- .github/workflows/changelog-checker.yml | 8 +- .github/workflows/oss.yml | 128 -- CHANGELOG.md | 404 +--- CODEOWNERS | 4 - Makefile | 21 +- README.md | 8 +- api/auth/approle/go.mod | 2 +- api/auth/approle/go.sum | 18 +- api/auth/aws/go.mod | 2 +- api/auth/aws/go.sum | 18 +- api/auth/azure/go.mod | 2 +- api/auth/azure/go.sum | 18 +- api/auth/gcp/go.mod | 2 +- api/auth/gcp/go.sum | 18 +- api/auth/kubernetes/go.mod | 2 +- api/auth/kubernetes/go.sum | 18 +- api/auth/ldap/go.mod | 2 +- api/auth/ldap/go.sum | 18 +- api/auth/userpass/go.mod | 2 +- api/auth/userpass/go.sum | 18 +- api/client.go | 76 +- api/client_test.go | 94 +- api/kv.go | 8 +- api/kv_v1.go | 8 +- api/kv_v2.go | 437 +--- api/output_string.go | 10 +- audit/format_json_test.go | 2 +- audit/format_jsonx_test.go | 2 +- builtin/credential/approle/path_login.go | 36 - builtin/credential/approle/path_login_test.go | 89 - builtin/credential/aws/backend_test.go | 4 +- builtin/credential/aws/path_login.go | 347 ++- builtin/credential/aws/path_login_test.go | 100 - builtin/credential/aws/path_role.go | 4 +- builtin/credential/aws/pkcs7/encrypt_test.go | 1 + builtin/credential/aws/pkcs7/pkcs7_test.go | 43 + builtin/credential/aws/pkcs7/sign.go | 4 +- builtin/credential/aws/pkcs7/sign_test.go | 9 +- ...{verify_dsa_test.go => verify_test_dsa.go} | 0 builtin/credential/cert/path_login.go | 18 - builtin/credential/cert/path_login_test.go | 199 -- builtin/credential/ldap/backend.go | 2 +- builtin/credential/ldap/backend_test.go | 10 +- builtin/logical/aws/path_roles.go | 2 +- builtin/logical/aws/path_user.go | 2 +- .../logical/cassandra/path_creds_create.go | 2 +- builtin/logical/cassandra/util.go | 2 +- builtin/logical/consul/backend_test.go | 9 +- builtin/logical/database/backend.go | 209 +- builtin/logical/database/backend_test.go | 89 +- .../database/path_config_connection.go | 10 +- .../database/path_rotate_credentials.go | 13 +- builtin/logical/database/rollback_test.go | 6 +- builtin/logical/database/rotation.go | 21 +- builtin/logical/database/rotation_test.go | 1 - .../logical/database/versioning_large_test.go | 4 +- builtin/logical/mssql/util.go | 2 +- builtin/logical/mysql/secret_creds.go | 4 +- builtin/logical/mysql/util.go | 2 +- builtin/logical/nomad/backend_test.go | 150 -- builtin/logical/nomad/path_config_access.go | 2 - builtin/logical/pki/backend_test.go | 363 ++-- builtin/logical/pki/ca_test.go | 1 - builtin/logical/pki/ca_util.go | 41 +- builtin/logical/pki/cert_util.go | 118 +- builtin/logical/pki/cert_util_test.go | 5 - builtin/logical/pki/chain_test.go | 28 +- builtin/logical/pki/chain_util.go | 13 +- builtin/logical/pki/config_util.go | 23 +- builtin/logical/pki/crl_test.go | 62 +- builtin/logical/pki/crl_util.go | 33 +- builtin/logical/pki/fields.go | 7 - builtin/logical/pki/integation_test.go | 5 - builtin/logical/pki/key_util.go | 9 +- builtin/logical/pki/path_config_ca.go | 18 +- builtin/logical/pki/path_config_crl.go | 2 +- builtin/logical/pki/path_config_urls.go | 21 +- builtin/logical/pki/path_fetch.go | 3 +- builtin/logical/pki/path_fetch_issuers.go | 151 +- builtin/logical/pki/path_fetch_keys.go | 26 +- builtin/logical/pki/path_intermediate.go | 18 +- builtin/logical/pki/path_issue_sign.go | 27 +- builtin/logical/pki/path_manage_issuers.go | 29 +- builtin/logical/pki/path_manage_keys.go | 10 +- builtin/logical/pki/path_manage_keys_test.go | 14 +- builtin/logical/pki/path_revoke.go | 2 +- builtin/logical/pki/path_roles.go | 195 +- builtin/logical/pki/path_roles_test.go | 103 +- builtin/logical/pki/path_root.go | 53 +- builtin/logical/pki/path_sign_issuers.go | 43 +- builtin/logical/pki/storage.go | 258 +-- builtin/logical/pki/storage_migrations.go | 13 +- .../logical/pki/storage_migrations_test.go | 22 +- builtin/logical/pki/storage_test.go | 61 +- builtin/logical/pki/test_helpers.go | 4 - builtin/logical/pki/util.go | 15 +- builtin/logical/postgresql/query.go | 2 +- builtin/logical/rabbitmq/backend_test.go | 2 +- builtin/logical/ssh/backend.go | 1 - builtin/logical/ssh/backend_test.go | 286 +-- builtin/logical/ssh/path_issue.go | 183 -- builtin/logical/ssh/path_issue_sign.go | 554 ----- builtin/logical/ssh/path_roles.go | 12 - builtin/logical/ssh/path_sign.go | 524 ++++- builtin/logical/ssh/util.go | 2 +- builtin/logical/transit/backend_test.go | 6 +- builtin/logical/transit/path_hmac_test.go | 4 +- builtin/logical/transit/path_import_test.go | 74 +- builtin/logical/transit/path_restore_test.go | 2 +- builtin/plugin/backend.go | 61 +- changelog/11904.txt | 3 - changelog/11969.txt | 3 - changelog/14399.txt | 3 - changelog/15552.txt | 6 - changelog/15561.txt | 3 - changelog/15583.txt | 3 - changelog/15638.txt | 3 - changelog/15681.txt | 3 - changelog/15735.txt | 3 - changelog/15742.txt | 3 - changelog/15809.txt | 3 - changelog/15835.txt | 3 - changelog/15852.txt | 3 - changelog/15866.txt | 3 - changelog/15898.txt | 3 - changelog/15900.txt | 3 - changelog/15912.txt | 3 - changelog/15989.txt | 3 - changelog/15996.txt | 3 - changelog/15998.txt | 3 - changelog/16000.txt | 3 - changelog/16063.txt | 4 - changelog/16115.txt | 3 - changelog/16124.txt | 3 - changelog/16140.txt | 3 - changelog/16146.txt | 3 - changelog/16162.txt | 3 - changelog/16181.txt | 3 - changelog/16184.txt | 3 - changelog/16240.txt | 3 - changelog/16274.txt | 3 - changelog/16351.txt | 3 - changelog/16353.txt | 3 - changelog/16379.txt | 3 - changelog/16386.txt | 3 - changelog/16409.txt | 3 - changelog/16421.txt | 3 - changelog/16435.txt | 3 - changelog/16441.txt | 3 - changelog/16447.txt | 3 - changelog/16455.txt | 3 - changelog/16487.txt | 3 - changelog/16489.txt | 3 - changelog/16494.txt | 3 - changelog/16519.txt | 3 - changelog/16523.txt | 3 + changelog/16525.txt | 6 - changelog/16526.txt | 3 + changelog/16539.txt | 3 - changelog/16567.txt | 3 - changelog/16609.txt | 3 - changelog/16631.txt | 3 - changelog/16721.txt | 3 + changelog/README.md | 55 +- changelog/_go-ver-1111.txt | 3 + changelog/_go-ver-1120.txt | 3 - changelog/go-ver-1110.txt | 2 +- command/agent.go | 2 +- command/agent/alicloud_end_to_end_test.go | 2 +- command/agent/auth/jwt/jwt.go | 76 +- command/agent/auth/jwt/jwt_test.go | 67 +- command/agent/config/config_test.go | 4 +- command/agent_test.go | 6 +- command/audit_enable.go | 2 +- command/audit_enable_test.go | 2 +- command/base.go | 16 +- command/base_helpers.go | 16 - command/base_helpers_test.go | 46 - command/commands.go | 5 - command/debug.go | 4 +- command/login.go | 4 +- command/namespace.go | 4 - command/namespace_create.go | 21 +- command/namespace_patch.go | 137 -- command/operator_init.go | 53 +- command/operator_init_test.go | 2 +- command/operator_migrate.go | 4 +- command/operator_raft_join.go | 2 +- command/server.go | 133 +- command/server/config.go | 80 +- command/server/config_test.go | 4 - command/server/config_test_helpers.go | 44 - command/server/tls_util.go | 162 -- command/server_test.go | 4 +- command/server_util.go | 9 +- command/token/helper_external.go | 2 +- go.mod | 114 +- go.sum | 469 ++-- helper/forwarding/types.pb.go | 2 +- helper/hostutil/hostinfo.go | 78 +- helper/hostutil/hostinfo_util.go | 110 +- helper/identity/mfa/types.pb.go | 2 +- helper/identity/types.pb.go | 2 +- helper/metricsutil/gauge_process.go | 71 +- helper/metricsutil/gauge_process_test.go | 40 +- helper/metricsutil/metricsutil.go | 2 +- helper/metricsutil/wrapped_metrics.go | 21 +- helper/namespace/namespace.go | 10 +- helper/pgpkeys/flag_test.go | 2 +- helper/storagepacker/types.pb.go | 2 +- helper/testhelpers/consul/consulhelper.go | 4 +- helper/testhelpers/logical/testing.go | 2 +- .../teststorage/teststorage_reusable.go | 1 + http/logical.go | 2 - http/logical_test.go | 31 +- http/sys_init.go | 46 - http/sys_init_test.go | 66 - http/sys_raft.go | 2 +- http/util.go | 15 +- make.bat | 4 +- physical/foundationdb/foundationdb.go | 8 +- physical/postgresql/postgresql.go | 8 +- physical/postgresql/postgresql_test.go | 4 +- physical/raft/bolt_linux.go | 2 +- physical/raft/raft.go | 2 +- physical/raft/types.pb.go | 2 +- physical/spanner/spanner.go | 2 +- physical/swift/swift_test.go | 2 +- plugins/database/hana/hana.go | 38 +- plugins/database/hana/hana_test.go | 94 +- plugins/database/mysql/mysql.go | 6 +- plugins/database/postgresql/postgresql.go | 2 +- scripts/build.sh | 49 +- scripts/cross/Dockerfile | 1 + scripts/docker/Dockerfile | 9 +- scripts/docker/Dockerfile.ui | 9 +- scripts/windows/build.bat | 14 +- sdk/database/dbplugin/database.pb.go | 2 +- sdk/database/dbplugin/databasemiddleware.go | 4 +- sdk/database/dbplugin/v5/middleware.go | 4 +- sdk/database/dbplugin/v5/proto/database.pb.go | 2 +- sdk/database/helper/dbutil/dbutil.go | 2 +- sdk/database/helper/dbutil/quoteidentifier.go | 2 +- sdk/framework/backend.go | 9 +- sdk/framework/openapi.go | 25 +- sdk/framework/openapi_test.go | 10 +- sdk/framework/path.go | 2 +- sdk/helper/certutil/helpers.go | 77 +- sdk/helper/certutil/types.go | 5 - sdk/helper/custommetadata/custom_metadata.go | 103 - .../custommetadata/custom_metadata_test.go | 85 - sdk/helper/dbtxn/dbtxn.go | 2 +- sdk/helper/keysutil/policy.go | 23 +- sdk/helper/keysutil/policy_test.go | 62 - sdk/helper/keysutil/util.go | 115 - sdk/helper/pathmanager/pathmanager_test.go | 12 +- sdk/helper/pluginutil/multiplexing.pb.go | 2 +- sdk/logical/identity.pb.go | 2 +- sdk/logical/plugin.pb.go | 2 +- sdk/logical/request.go | 1 - sdk/logical/response.go | 9 - sdk/plugin/pb/backend.pb.go | 2 +- sdk/version/version_base.go | 4 +- tools/tools.go | 3 + ui/.browserslistrc | 7 +- ui/.eslintrc.js | 7 +- ui/README.md | 20 +- ui/app/adapters/cluster.js | 4 +- .../{pki/cert.js => pki-certificate.js} | 2 +- ui/app/adapters/{pki => }/pki-config.js | 2 +- .../adapters/{pki/pki-role.js => role-pki.js} | 2 +- ui/app/components/alert-popup.js | 25 +- ui/app/components/auth-form.js | 59 +- ui/app/components/auth-jwt.js | 1 - ui/app/components/block-error.js | 2 + ui/app/components/{pki => }/config-pki-ca.js | 0 ui/app/components/{pki => }/config-pki.js | 0 .../components/database-role-setting-form.js | 6 +- ui/app/components/generate-credentials.js | 2 +- ui/app/components/generated-item-list.js | 43 +- ui/app/components/home-link.js | 19 +- ui/app/components/hover-copy-button.js | 31 +- ui/app/components/logo-splash.js | 1 + ui/app/components/{mfa => }/mfa-form.js | 2 +- .../{mfa => }/mfa-login-enforcement-form.js | 17 +- .../{mfa => }/mfa-login-enforcement-header.js | 0 .../{mfa => }/mfa-setup-step-one.js | 0 .../{mfa => }/mfa-setup-step-two.js | 0 ui/app/components/mount-backend-form.js | 285 +-- ui/app/components/okta-number-challenge.js | 24 - ui/app/components/pki-cert-popup.js | 17 + ui/app/components/{pki => }/pki-cert-show.js | 2 +- ui/app/components/pki/pki-cert-popup.js | 24 - ui/app/components/{pki => }/role-pki-edit.js | 2 +- ui/app/components/selectable-card.js | 44 +- ui/app/components/splash-page.js | 40 +- ui/app/components/status-menu.js | 53 +- ui/app/components/wizard-section.js | 9 + ui/app/controllers/vault/cluster/auth.js | 4 - ui/app/helpers/-date-base.js | 5 - ui/app/helpers/options-for-backend.js | 8 +- ui/app/models/pki-ca-certificate.js | 2 +- ui/app/models/pki-certificate-sign.js | 2 +- .../{pki/cert.js => pki-certificate.js} | 0 ui/app/models/{pki => }/pki-config.js | 0 .../models/{pki/pki-role.js => role-pki.js} | 0 .../vault/cluster/secrets/backend/list.js | 6 +- .../vault/cluster/secrets/backend/overview.js | 1 - .../cluster/secrets/backend/secret-edit.js | 4 +- .../configure-secret-backend/section.js | 12 +- .../{pki/cert.js => pki-certificate.js} | 2 +- ui/app/serializers/{pki => }/pki-config.js | 0 .../{pki/pki-role.js => role-pki.js} | 2 +- ui/app/services/auth.js | 17 - ui/app/templates/components/alert-popup.hbs | 2 +- ui/app/templates/components/auth-form.hbs | 332 ++- .../components/{pki => }/config-pki-ca.hbs | 0 .../components/{pki => }/config-pki.hbs | 0 .../{pki => }/configure-pki-secret.hbs | 0 .../components/database-connection.hbs | 3 +- .../components/generated-item-list.hbs | 4 +- ui/app/templates/components/home-link.hbs | 4 +- .../components/hover-copy-button.hbs | 36 +- .../templates/components/keymgmt/key-edit.hbs | 1 + .../components/{mfa => }/mfa-form.hbs | 0 .../{mfa => }/mfa-login-enforcement-form.hbs | 0 .../mfa-login-enforcement-header.hbs | 0 .../{mfa => }/mfa-setup-step-one.hbs | 0 .../{mfa => }/mfa-setup-step-two.hbs | 0 .../templates/components/mfa/method-form.hbs | 1 + .../components/mount-backend-form.hbs | 14 +- .../components/okta-number-challenge.hbs | 38 - .../components/{pki => }/pki-cert-popup.hbs | 8 +- .../components/{pki => }/pki-cert-show.hbs | 2 +- .../components/{pki => }/role-pki-edit.hbs | 0 .../components/secret-list/pki-cert-item.hbs | 2 +- .../templates/components/selectable-card.hbs | 46 +- ui/app/templates/components/splash-page.hbs | 4 +- ui/app/templates/components/status-menu.hbs | 13 +- ui/app/templates/components/tool-lookup.hbs | 5 +- ui/app/templates/components/tool-rewrap.hbs | 5 +- ui/app/templates/components/tool-unwrap.hbs | 5 +- ui/app/templates/components/tool-wrap.hbs | 2 +- .../templates/components/wizard-section.hbs | 18 +- .../components/wizard/tools-unwrapped.hbs | 2 +- .../vault/cluster/access/method/item/list.hbs | 1 + .../access/mfa/enforcements/create.hbs | 4 +- .../mfa/enforcements/enforcement/edit.hbs | 4 +- .../cluster/access/mfa/methods/create.hbs | 4 +- ui/app/templates/vault/cluster/auth.hbs | 12 +- ui/app/templates/vault/cluster/mfa-setup.hbs | 4 +- .../vault/cluster/secrets/backend/list.hbs | 4 +- .../cluster/secrets/backend/overview.hbs | 4 +- .../settings/configure-secret-backend.hbs | 2 +- .../configure-secret-backend/section.hbs | 4 +- ui/app/utils/validators.js | 7 +- ui/ember-cli-build.js | 7 +- .../addon/components/confirmation-modal.js | 41 +- ui/lib/core/addon/components/form-field.hbs | 3 +- .../components/info-table-item-array.hbs | 59 - .../addon/components/info-table-item-array.js | 88 +- .../core/addon/components/info-table-row.js | 1 + ui/lib/core/addon/components/linkable-item.js | 7 +- .../addon/components/linkable-item/content.js | 7 +- .../addon/components/linkable-item/menu.js | 7 +- ui/lib/core/addon/components/modal.js | 59 +- ui/lib/core/addon/components/read-more.js | 12 +- .../components/search-select-with-modal.hbs | 104 - .../components/search-select-with-modal.js | 217 -- ui/lib/core/addon/components/search-select.js | 2 +- ui/lib/core/addon/components/string-list.hbs | 56 - ui/lib/core/addon/components/string-list.js | 189 +- .../components/confirmation-modal.hbs | 18 +- .../components/info-table-item-array.hbs | 57 + .../templates/components/masked-input.hbs | 1 - .../{ => templates}/components/modal.hbs | 8 +- .../components/replication-action-demote.hbs | 1 + .../components/replication-action-disable.hbs | 1 + .../templates/components/string-list.hbs | 42 + .../addon/utils/search-select-has-many.js | 33 - .../components/search-select-with-modal.js | 1 - ui/lib/core/package.json | 1 - ui/package.json | 10 +- ui/scripts/start-vault.js | 17 +- ui/testem.browserstack.js | 92 + ui/tests/acceptance/enterprise-kmip-test.js | 4 +- .../acceptance/enterprise-replication-test.js | 6 +- .../secrets/backend/database/secret-test.js | 2 +- .../secrets/backend/kv/secret-test.js | 1 + .../secrets/backend/pki/cert-test.js | 16 +- .../{pki => }/config-pki-ca-test.js | 6 +- .../components/{pki => }/config-pki-test.js | 6 +- .../components/confirmation-modal-test.js | 28 +- .../components/hover-copy-button-test.js | 19 +- .../components/info-table-row-test.js | 2 +- .../integration/components/mfa-form-test.js | 16 +- .../mfa-login-enforcement-form-test.js | 12 +- .../mfa-login-enforcement-header-test.js | 4 +- .../components/mfa/method-form-test.js | 4 +- ui/tests/integration/components/modal-test.js | 22 +- .../components/okta-number-challenge-test.js | 69 - .../search-select-with-modal-test.js | 175 -- .../components/selectable-card-test.js | 7 +- .../components/string-list-test.js | 46 +- .../components/token-expire-warning-test.js | 10 +- .../components/{pki => }/config-pki-ca.js | 2 +- .../pages/components/{pki => }/config-pki.js | 2 +- .../pki/section-cert.js | 2 +- .../configure-secret-backends/pki/section.js | 2 +- ui/tests/unit/adapters/cluster-test.js | 4 +- ui/tests/unit/utils/validators-test.js | 17 - ui/yarn.lock | 1931 ++++------------- vault/acl.go | 8 +- vault/acl_test.go | 27 +- vault/activity/activity_log.pb.go | 2 +- vault/activity_log.go | 747 ++++--- vault/activity_log_test.go | 29 - vault/activity_log_util_common.go | 253 --- vault/activity_log_util_common_test.go | 128 -- vault/core.go | 39 +- vault/core_util.go | 13 +- vault/core_util_common.go | 11 - vault/counters_test.go | 2 +- vault/diagnose/os_common.go | 2 +- vault/diagnose/tls_verification.go | 4 +- vault/expiration.go | 105 +- vault/expiration_test.go | 234 +- .../api/api_integration_test.go | 1 - vault/external_tests/api/kv_helpers_test.go | 464 +--- vault/external_tests/identity/aliases_test.go | 529 ----- .../identity/login_mfa_totp_test.go | 15 +- vault/external_tests/quotas/quotas_test.go | 3 - vault/identity_store.go | 4 +- vault/identity_store_aliases.go | 61 +- vault/identity_store_entities.go | 138 +- vault/identity_store_entities_test.go | 28 +- vault/identity_store_groups.go | 6 +- vault/identity_store_groups_test.go | 93 +- vault/identity_store_oidc_provider.go | 68 +- vault/identity_store_oidc_provider_test.go | 250 +-- vault/identity_store_test.go | 1 + vault/identity_store_util.go | 9 +- vault/logical_raw.go | 18 +- vault/logical_system.go | 45 +- vault/logical_system_activity.go | 12 +- vault/logical_system_paths.go | 6 - vault/logical_system_quotas.go | 43 +- vault/logical_system_test.go | 65 +- vault/login_mfa.go | 15 +- vault/mount.go | 9 - vault/policy.go | 12 +- vault/quotas/quotas.go | 261 +-- vault/quotas/quotas_rate_limit.go | 13 +- vault/quotas/quotas_rate_limit_test.go | 105 +- vault/quotas/quotas_test.go | 56 +- vault/request_forwarding_service.pb.go | 2 +- vault/request_handling.go | 46 +- vault/request_handling_util.go | 6 +- vault/rollback.go | 2 +- vault/router.go | 2 +- vault/testing.go | 8 +- vault/token_store_test.go | 44 +- vault/tokens/token.pb.go | 2 +- vault/wrapping.go | 2 +- website/content/api-docs/auth/jwt.mdx | 2 +- website/content/api-docs/relatedtools.mdx | 1 - website/content/api-docs/secret/ad.mdx | 3 - website/content/api-docs/secret/azure.mdx | 5 +- website/content/api-docs/secret/consul.mdx | 43 +- .../api-docs/secret/databases/hanadb.mdx | 2 - website/content/api-docs/secret/gcp.mdx | 6 +- .../api-docs/secret/identity/entity.mdx | 11 +- .../api-docs/secret/identity/mfa/totp.mdx | 2 +- .../secret/identity/oidc-provider.mdx | 53 +- .../api-docs/secret/identity/tokens.mdx | 6 +- .../content/api-docs/secret/kubernetes.mdx | 48 +- website/content/api-docs/secret/kv/kv-v2.mdx | 14 +- .../content/api-docs/secret/mongodbatlas.mdx | 9 +- website/content/api-docs/secret/nomad.mdx | 8 +- website/content/api-docs/secret/openldap.mdx | 17 +- website/content/api-docs/secret/pki.mdx | 77 +- website/content/api-docs/secret/ssh.mdx | 99 +- website/content/api-docs/secret/terraform.mdx | 8 +- website/content/api-docs/secret/transform.mdx | 21 +- website/content/api-docs/secret/transit.mdx | 6 +- website/content/api-docs/system/auth.mdx | 6 +- website/content/api-docs/system/init.mdx | 3 +- .../api-docs/system/internal-counters.mdx | 13 - .../system/internal-specs-openapi.mdx | 7 +- .../api-docs/system/lease-count-quotas.mdx | 56 +- .../content/api-docs/system/namespaces.mdx | 56 +- .../api-docs/system/rate-limit-quotas.mdx | 20 +- website/content/docs/agent/autoauth/index.mdx | 9 +- .../docs/agent/autoauth/methods/jwt.mdx | 4 - website/content/docs/agent/index.mdx | 2 +- website/content/docs/agent/template.mdx | 2 +- website/content/docs/audit/index.mdx | 4 - .../docs/auth/jwt/oidc-providers/index.mdx | 3 +- .../auth/jwt/oidc-providers/secureauth.mdx | 34 - website/content/docs/auth/kubernetes.mdx | 2 +- website/content/docs/commands/auth/enable.mdx | 2 +- website/content/docs/commands/kv/metadata.mdx | 6 +- website/content/docs/commands/kv/put.mdx | 10 +- website/content/docs/commands/login.mdx | 2 +- website/content/docs/commands/namespace.mdx | 14 +- .../content/docs/commands/operator/init.mdx | 4 +- .../content/docs/commands/secrets/tune.mdx | 3 +- website/content/docs/commands/server.mdx | 6 - .../content/docs/commands/token/create.mdx | 17 +- .../content/docs/concepts/duration-format.mdx | 39 - .../content/docs/concepts/oidc-provider.mdx | 4 +- website/content/docs/concepts/policies.mdx | 3 +- .../content/docs/concepts/resource-quotas.mdx | 21 +- website/content/docs/configuration/index.mdx | 17 +- .../content/docs/configuration/telemetry.mdx | 4 +- .../docs/enterprise/lease-count-quotas.mdx | 28 +- .../content/docs/enterprise/license/faq.mdx | 41 +- .../content/docs/enterprise/replication.mdx | 2 +- .../content/docs/internals/architecture.mdx | 1 + .../content/docs/internals/replication.mdx | 70 +- .../docs/platform/k8s/csi/configurations.mdx | 2 +- website/content/docs/platform/k8s/index.mdx | 2 +- .../docs/plugins/plugin-architecture.mdx | 6 +- website/content/docs/secrets/ad.mdx | 6 +- website/content/docs/secrets/consul.mdx | 13 +- .../content/docs/secrets/databases/index.mdx | 2 +- .../docs/secrets/identity/identity-token.mdx | 4 +- .../content/docs/secrets/identity/index.mdx | 2 +- website/content/docs/secrets/kubernetes.mdx | 23 - website/content/docs/secrets/kv/kv-v2.mdx | 10 +- .../docs/secrets/transform/tokenization.mdx | 4 +- .../{transit/index.mdx => transit.mdx} | 3 - .../secrets/transit/key-wrapping-guide.mdx | 164 -- .../plugin-file-permissions-check.mdx | 8 +- .../partials/x509-sha1-deprecation.mdx | 2 +- website/data/docs-nav-data.json | 19 +- 545 files changed, 4959 insertions(+), 14781 deletions(-) create mode 100644 .circleci/config/commands/setup-semgrep.yml create mode 100644 .circleci/config/jobs/test-ui-browserstack.yml delete mode 100644 .github/workflows/oss.yml rename builtin/credential/aws/pkcs7/{verify_dsa_test.go => verify_test_dsa.go} (100%) delete mode 100644 builtin/credential/cert/path_login_test.go delete mode 100644 builtin/logical/ssh/path_issue.go delete mode 100644 builtin/logical/ssh/path_issue_sign.go delete mode 100644 changelog/11904.txt delete mode 100644 changelog/11969.txt delete mode 100644 changelog/14399.txt delete mode 100644 changelog/15552.txt delete mode 100644 changelog/15561.txt delete mode 100644 changelog/15583.txt delete mode 100644 changelog/15638.txt delete mode 100644 changelog/15681.txt delete mode 100644 changelog/15735.txt delete mode 100644 changelog/15742.txt delete mode 100644 changelog/15809.txt delete mode 100644 changelog/15835.txt delete mode 100644 changelog/15852.txt delete mode 100644 changelog/15866.txt delete mode 100644 changelog/15898.txt delete mode 100644 changelog/15900.txt delete mode 100644 changelog/15912.txt delete mode 100644 changelog/15989.txt delete mode 100644 changelog/15996.txt delete mode 100644 changelog/15998.txt delete mode 100644 changelog/16000.txt delete mode 100644 changelog/16063.txt delete mode 100644 changelog/16115.txt delete mode 100644 changelog/16124.txt delete mode 100644 changelog/16140.txt delete mode 100644 changelog/16146.txt delete mode 100644 changelog/16162.txt delete mode 100644 changelog/16181.txt delete mode 100644 changelog/16184.txt delete mode 100644 changelog/16240.txt delete mode 100644 changelog/16274.txt delete mode 100644 changelog/16351.txt delete mode 100644 changelog/16353.txt delete mode 100644 changelog/16379.txt delete mode 100644 changelog/16386.txt delete mode 100644 changelog/16409.txt delete mode 100644 changelog/16421.txt delete mode 100644 changelog/16435.txt delete mode 100644 changelog/16441.txt delete mode 100644 changelog/16447.txt delete mode 100644 changelog/16455.txt delete mode 100644 changelog/16487.txt delete mode 100644 changelog/16489.txt delete mode 100644 changelog/16494.txt delete mode 100644 changelog/16519.txt create mode 100644 changelog/16523.txt delete mode 100644 changelog/16525.txt create mode 100644 changelog/16526.txt delete mode 100644 changelog/16539.txt delete mode 100644 changelog/16567.txt delete mode 100644 changelog/16609.txt delete mode 100644 changelog/16631.txt create mode 100644 changelog/16721.txt create mode 100644 changelog/_go-ver-1111.txt delete mode 100644 changelog/_go-ver-1120.txt delete mode 100644 command/namespace_patch.go delete mode 100644 command/server/tls_util.go delete mode 100644 sdk/helper/custommetadata/custom_metadata.go delete mode 100644 sdk/helper/custommetadata/custom_metadata_test.go delete mode 100644 sdk/helper/keysutil/util.go rename ui/app/adapters/{pki/cert.js => pki-certificate.js} (97%) rename ui/app/adapters/{pki => }/pki-config.js (98%) rename ui/app/adapters/{pki/pki-role.js => role-pki.js} (97%) create mode 100644 ui/app/components/block-error.js rename ui/app/components/{pki => }/config-pki-ca.js (100%) rename ui/app/components/{pki => }/config-pki.js (100%) create mode 100644 ui/app/components/logo-splash.js rename ui/app/components/{mfa => }/mfa-form.js (98%) rename ui/app/components/{mfa => }/mfa-login-enforcement-form.js (90%) rename ui/app/components/{mfa => }/mfa-login-enforcement-header.js (100%) rename ui/app/components/{mfa => }/mfa-setup-step-one.js (100%) rename ui/app/components/{mfa => }/mfa-setup-step-two.js (100%) delete mode 100644 ui/app/components/okta-number-challenge.js create mode 100644 ui/app/components/pki-cert-popup.js rename ui/app/components/{pki => }/pki-cert-show.js (79%) delete mode 100644 ui/app/components/pki/pki-cert-popup.js rename ui/app/components/{pki => }/role-pki-edit.js (76%) create mode 100644 ui/app/components/wizard-section.js rename ui/app/models/{pki/cert.js => pki-certificate.js} (100%) rename ui/app/models/{pki => }/pki-config.js (100%) rename ui/app/models/{pki/pki-role.js => role-pki.js} (100%) rename ui/app/serializers/{pki/cert.js => pki-certificate.js} (97%) rename ui/app/serializers/{pki => }/pki-config.js (100%) rename ui/app/serializers/{pki/pki-role.js => role-pki.js} (51%) rename ui/app/templates/components/{pki => }/config-pki-ca.hbs (100%) rename ui/app/templates/components/{pki => }/config-pki.hbs (100%) rename ui/app/templates/components/{pki => }/configure-pki-secret.hbs (100%) rename ui/app/templates/components/{mfa => }/mfa-form.hbs (100%) rename ui/app/templates/components/{mfa => }/mfa-login-enforcement-form.hbs (100%) rename ui/app/templates/components/{mfa => }/mfa-login-enforcement-header.hbs (100%) rename ui/app/templates/components/{mfa => }/mfa-setup-step-one.hbs (100%) rename ui/app/templates/components/{mfa => }/mfa-setup-step-two.hbs (100%) delete mode 100644 ui/app/templates/components/okta-number-challenge.hbs rename ui/app/templates/components/{pki => }/pki-cert-popup.hbs (73%) rename ui/app/templates/components/{pki => }/pki-cert-show.hbs (98%) rename ui/app/templates/components/{pki => }/role-pki-edit.hbs (100%) delete mode 100644 ui/lib/core/addon/components/info-table-item-array.hbs delete mode 100644 ui/lib/core/addon/components/search-select-with-modal.hbs delete mode 100644 ui/lib/core/addon/components/search-select-with-modal.js delete mode 100644 ui/lib/core/addon/components/string-list.hbs rename ui/lib/core/addon/{ => templates}/components/confirmation-modal.hbs (65%) create mode 100644 ui/lib/core/addon/templates/components/info-table-item-array.hbs rename ui/lib/core/addon/{ => templates}/components/modal.hbs (76%) create mode 100644 ui/lib/core/addon/templates/components/string-list.hbs delete mode 100644 ui/lib/core/addon/utils/search-select-has-many.js delete mode 100644 ui/lib/core/app/components/search-select-with-modal.js create mode 100644 ui/testem.browserstack.js rename ui/tests/integration/components/{pki => }/config-pki-ca-test.js (91%) rename ui/tests/integration/components/{pki => }/config-pki-test.js (91%) delete mode 100644 ui/tests/integration/components/okta-number-challenge-test.js delete mode 100644 ui/tests/integration/components/search-select-with-modal-test.js rename ui/tests/pages/components/{pki => }/config-pki-ca.js (98%) rename ui/tests/pages/components/{pki => }/config-pki.js (93%) delete mode 100644 vault/activity_log_util_common.go delete mode 100644 vault/activity_log_util_common_test.go delete mode 100644 website/content/docs/auth/jwt/oidc-providers/secureauth.mdx delete mode 100644 website/content/docs/concepts/duration-format.mdx rename website/content/docs/secrets/{transit/index.mdx => transit.mdx} (98%) delete mode 100644 website/content/docs/secrets/transit/key-wrapping-guide.mdx diff --git a/.circleci/config.yml b/.circleci/config.yml index c4fde02e760a9..858df5a5b425e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,9 +7,7 @@ version: 2 jobs: install-ui-dependencies: docker: - - environment: - JOBS: 2 - image: docker.mirror.hashicorp.services/circleci/node:14-browsers + - image: docker.mirror.hashicorp.services/node:14-buster shell: /usr/bin/env bash -euo pipefail -c working_directory: /home/circleci/go/src/github.com/hashicorp/vault steps: @@ -30,9 +28,7 @@ jobs: - ui/node_modules test-ui: docker: - - environment: - JOBS: 2 - image: docker.mirror.hashicorp.services/circleci/node:14-browsers + - image: docker.mirror.hashicorp.services/node:14-buster shell: /usr/bin/env bash -euo pipefail -c working_directory: /home/circleci/go/src/github.com/hashicorp/vault resource_class: xlarge @@ -59,6 +55,18 @@ jobs: at: . - run: command: | + set -x + + # Install Chrome + wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub \ + | apt-key add - + echo "deb http://dl.google.com/linux/chrome/deb/ stable main" \ + | tee /etc/apt/sources.list.d/google-chrome.list + apt-get update + apt-get -y install google-chrome-stable + rm /etc/apt/sources.list.d/google-chrome.list + rm -rf /var/lib/apt/lists/* /var/cache/apt/* + # Add ./bin to the PATH so vault binary can be run by Ember tests export PATH="${PWD}/bin:${PATH}" @@ -71,6 +79,25 @@ jobs: path: ui/test-results - store_test_results: path: ui/test-results + test-ui-browserstack: + docker: + - image: docker.mirror.hashicorp.services/node:14-buster + shell: /usr/bin/env bash -euo pipefail -c + working_directory: /home/circleci/go/src/github.com/hashicorp/vault + resource_class: xlarge + steps: + - checkout + - restore_cache: + key: yarn-lock-v7-{{ checksum "ui/yarn.lock" }} + name: Restore yarn cache + - attach_workspace: + at: . + - run: + command: | + # Add ./bin to the PATH so vault binary can be found. + export PATH="${PWD}"/bin:${PATH} + make test-ui-browserstack + name: Run Browserstack Tests build-go-dev: machine: image: ubuntu-2004:202201-02 @@ -120,12 +147,12 @@ jobs: environment: - CIRCLECI_CLI_VERSION: 0.1.5546 - GO_TAGS: '' - - GO_VERSION: 1.18.4 + - GO_VERSION: 1.17.12 - GOFUMPT_VERSION: 0.2.1 - GOTESTSUM_VERSION: 0.5.2 test-go-remote-docker: docker: - - image: docker.mirror.hashicorp.services/cimg/go:1.18.4 + - image: docker.mirror.hashicorp.services/cimg/go:1.17.12 resource_class: medium working_directory: /home/circleci/go/src/github.com/hashicorp/vault parallelism: 8 @@ -258,7 +285,7 @@ jobs: -e NO_PROXY \ -e VAULT_TEST_LOG_DIR=/tmp/testlogs \ --network vaulttest --name \ - testcontainer docker.mirror.hashicorp.services/cimg/go:1.18.4 \ + testcontainer docker.mirror.hashicorp.services/cimg/go:1.17.12 \ tail -f /dev/null # Run tests @@ -359,12 +386,12 @@ jobs: environment: - CIRCLECI_CLI_VERSION: 0.1.5546 - GO_TAGS: '' - - GO_VERSION: 1.18.4 + - GO_VERSION: 1.17.12 - GOFUMPT_VERSION: 0.2.1 - GOTESTSUM_VERSION: 0.5.2 test-go-race: docker: - - image: docker.mirror.hashicorp.services/cimg/go:1.18.4 + - image: docker.mirror.hashicorp.services/cimg/go:1.17.12 resource_class: xlarge working_directory: /home/circleci/go/src/github.com/hashicorp/vault parallelism: 8 @@ -493,7 +520,7 @@ jobs: -e NO_PROXY \ -e VAULT_TEST_LOG_DIR=/tmp/testlogs \ --network vaulttest --name \ - testcontainer docker.mirror.hashicorp.services/cimg/go:1.18.4 \ + testcontainer docker.mirror.hashicorp.services/cimg/go:1.17.12 \ tail -f /dev/null # Run tests @@ -551,7 +578,7 @@ jobs: - GO_TAGS: '' test-go: docker: - - image: docker.mirror.hashicorp.services/cimg/go:1.18.4 + - image: docker.mirror.hashicorp.services/cimg/go:1.17.12 resource_class: large working_directory: /home/circleci/go/src/github.com/hashicorp/vault parallelism: 8 @@ -680,7 +707,7 @@ jobs: -e NO_PROXY \ -e VAULT_TEST_LOG_DIR=/tmp/testlogs \ --network vaulttest --name \ - testcontainer docker.mirror.hashicorp.services/cimg/go:1.18.4 \ + testcontainer docker.mirror.hashicorp.services/cimg/go:1.17.12 \ tail -f /dev/null # Run tests @@ -738,10 +765,20 @@ jobs: - GO_TAGS: '' semgrep: docker: - - image: docker.mirror.hashicorp.services/returntocorp/semgrep:0.106.0 + - image: docker.mirror.hashicorp.services/alpine:3.13 shell: /bin/sh working_directory: /home/circleci/go/src/github.com/hashicorp/vault steps: + - run: + command: | + apk add --no-cache python3 py3-pip make + python3 -m pip install --user semgrep==0.86.5 + export PATH="$HOME/.local/bin:$PATH" + + echo "$ semgrep --version" + semgrep --version + name: Setup Semgrep + working_directory: ~/ - checkout - attach_workspace: at: . @@ -839,12 +876,12 @@ jobs: environment: - CIRCLECI_CLI_VERSION: 0.1.5546 - GO_TAGS: '' - - GO_VERSION: 1.18.4 + - GO_VERSION: 1.17.12 - GOFUMPT_VERSION: 0.2.1 - GOTESTSUM_VERSION: 0.5.2 test-go-race-remote-docker: docker: - - image: docker.mirror.hashicorp.services/cimg/go:1.18.4 + - image: docker.mirror.hashicorp.services/cimg/go:1.17.12 resource_class: medium working_directory: /home/circleci/go/src/github.com/hashicorp/vault parallelism: 8 @@ -977,7 +1014,7 @@ jobs: -e NO_PROXY \ -e VAULT_TEST_LOG_DIR=/tmp/testlogs \ --network vaulttest --name \ - testcontainer docker.mirror.hashicorp.services/cimg/go:1.18.4 \ + testcontainer docker.mirror.hashicorp.services/cimg/go:1.17.12 \ tail -f /dev/null # Run tests @@ -1054,6 +1091,13 @@ workflows: requires: - install-ui-dependencies - build-go-dev + - test-ui-browserstack: + filters: + branches: + ignore: /pull\/[0-9]+/ + requires: + - install-ui-dependencies + - build-go-dev - test-go: requires: - pre-flight-checks diff --git a/.circleci/config/commands/go_test.yml b/.circleci/config/commands/go_test.yml index 874a76dbc8578..36aaad4474a4d 100644 --- a/.circleci/config/commands/go_test.yml +++ b/.circleci/config/commands/go_test.yml @@ -14,7 +14,7 @@ parameters: default: false go_image: type: string - default: "docker.mirror.hashicorp.services/cimg/go:1.18.4" + default: "docker.mirror.hashicorp.services/cimg/go:1.17.12" use_docker: type: boolean default: false diff --git a/.circleci/config/commands/setup-semgrep.yml b/.circleci/config/commands/setup-semgrep.yml new file mode 100644 index 0000000000000..b34307d3bc223 --- /dev/null +++ b/.circleci/config/commands/setup-semgrep.yml @@ -0,0 +1,14 @@ +--- +description: > + Ensure semgrep is installed. +steps: + - run: + working_directory: ~/ + name: Setup Semgrep + command: | + apk add --no-cache python3 py3-pip make + python3 -m pip install --user semgrep==0.86.5 + export PATH="$HOME/.local/bin:$PATH" + + echo "$ semgrep --version" + semgrep --version diff --git a/.circleci/config/executors/@executors.yml b/.circleci/config/executors/@executors.yml index 89e158788b4ed..82d7eccf8130b 100644 --- a/.circleci/config/executors/@executors.yml +++ b/.circleci/config/executors/@executors.yml @@ -3,18 +3,15 @@ go-machine: image: ubuntu-2004:202201-02 shell: /usr/bin/env bash -euo pipefail -c environment: - CIRCLECI_CLI_VERSION: 0.1.5546 # Pin CircleCI CLI to patch version (ex: 1.2.3) - GO_VERSION: 1.18.4 # Pin Go to patch version (ex: 1.2.3) - GOTESTSUM_VERSION: 0.5.2 # Pin gotestsum to patch version (ex: 1.2.3) - GOFUMPT_VERSION: 0.2.1 # Pin gofumpt to patch version (ex: 1.2.3) + CIRCLECI_CLI_VERSION: 0.1.5546 # Pin CircleCI CLI to patch version (ex: 1.2.3) + GO_VERSION: 1.17.12 # Pin Go to patch version (ex: 1.2.3) + GOTESTSUM_VERSION: 0.5.2 # Pin gotestsum to patch version (ex: 1.2.3) + GOFUMPT_VERSION: 0.2.1 # Pin gofumpt to patch version (ex: 1.2.3) GO_TAGS: "" working_directory: /home/circleci/go/src/github.com/hashicorp/vault node: docker: - - image: docker.mirror.hashicorp.services/circleci/node:14-browsers - environment: - # See https://git.io/vdao3 for details. - JOBS: 2 + - image: docker.mirror.hashicorp.services/node:14-buster shell: /usr/bin/env bash -euo pipefail -c working_directory: /home/circleci/go/src/github.com/hashicorp/vault python: @@ -22,32 +19,32 @@ python: - image: docker.mirror.hashicorp.services/python:3-alpine shell: /usr/bin/env bash -euo pipefail -c working_directory: /home/circleci/go/src/github.com/hashicorp/vault -semgrep: +alpine: docker: - - image: docker.mirror.hashicorp.services/returntocorp/semgrep:0.106.0 + - image: docker.mirror.hashicorp.services/alpine:3.13 shell: /bin/sh working_directory: /home/circleci/go/src/github.com/hashicorp/vault docker-env-go-test-remote-docker: resource_class: medium docker: - - image: "docker.mirror.hashicorp.services/cimg/go:1.18.4" + - image: "docker.mirror.hashicorp.services/cimg/go:1.17.12" environment: - CIRCLECI_CLI_VERSION: 0.1.5546 # Pin CircleCI CLI to patch version (ex: 1.2.3) + CIRCLECI_CLI_VERSION: 0.1.5546 # Pin CircleCI CLI to patch version (ex: 1.2.3) GO_TAGS: "" working_directory: /home/circleci/go/src/github.com/hashicorp/vault docker-env-go-test: resource_class: large docker: - - image: "docker.mirror.hashicorp.services/cimg/go:1.18.4" + - image: "docker.mirror.hashicorp.services/cimg/go:1.17.12" environment: - CIRCLECI_CLI_VERSION: 0.1.5546 # Pin CircleCI CLI to patch version (ex: 1.2.3) + CIRCLECI_CLI_VERSION: 0.1.5546 # Pin CircleCI CLI to patch version (ex: 1.2.3) GO_TAGS: "" working_directory: /home/circleci/go/src/github.com/hashicorp/vault docker-env-go-test-race: resource_class: xlarge docker: - - image: "docker.mirror.hashicorp.services/cimg/go:1.18.4" + - image: "docker.mirror.hashicorp.services/cimg/go:1.17.12" environment: - CIRCLECI_CLI_VERSION: 0.1.5546 # Pin CircleCI CLI to patch version (ex: 1.2.3) + CIRCLECI_CLI_VERSION: 0.1.5546 # Pin CircleCI CLI to patch version (ex: 1.2.3) GO_TAGS: "" working_directory: /home/circleci/go/src/github.com/hashicorp/vault diff --git a/.circleci/config/jobs/semgrep.yml b/.circleci/config/jobs/semgrep.yml index 3994da9d6f4e8..1f6d5dd1f5adb 100644 --- a/.circleci/config/jobs/semgrep.yml +++ b/.circleci/config/jobs/semgrep.yml @@ -1,6 +1,7 @@ --- -executor: semgrep +executor: alpine steps: + - setup-semgrep - checkout - attach_workspace: at: . diff --git a/.circleci/config/jobs/test-ui-browserstack.yml b/.circleci/config/jobs/test-ui-browserstack.yml new file mode 100644 index 0000000000000..7640f83135a83 --- /dev/null +++ b/.circleci/config/jobs/test-ui-browserstack.yml @@ -0,0 +1,13 @@ +executor: node +resource_class: xlarge +steps: + - checkout + - restore_yarn_cache + - attach_workspace: + at: . + - run: + name: Run Browserstack Tests + command: | + # Add ./bin to the PATH so vault binary can be found. + export PATH="${PWD}"/bin:${PATH} + make test-ui-browserstack diff --git a/.circleci/config/jobs/test-ui.yml b/.circleci/config/jobs/test-ui.yml index f2aa19b0508d2..271e809a04005 100644 --- a/.circleci/config/jobs/test-ui.yml +++ b/.circleci/config/jobs/test-ui.yml @@ -9,6 +9,18 @@ steps: - run: name: Test UI command: | + set -x + + # Install Chrome + wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub \ + | apt-key add - + echo "deb http://dl.google.com/linux/chrome/deb/ stable main" \ + | tee /etc/apt/sources.list.d/google-chrome.list + apt-get update + apt-get -y install google-chrome-stable + rm /etc/apt/sources.list.d/google-chrome.list + rm -rf /var/lib/apt/lists/* /var/cache/apt/* + # Add ./bin to the PATH so vault binary can be run by Ember tests export PATH="${PWD}/bin:${PATH}" diff --git a/.circleci/config/workflows/ci.yml b/.circleci/config/workflows/ci.yml index 5e99293d7ea37..3af59741a66b5 100644 --- a/.circleci/config/workflows/ci.yml +++ b/.circleci/config/workflows/ci.yml @@ -14,6 +14,14 @@ jobs: # Only main, UI, release and merge branches need to run UI tests. # We don't filter here however because test-ui is configured in github as # required so it must run, instead we short-circuit within test-ui. + - test-ui-browserstack: + requires: + - install-ui-dependencies + - build-go-dev + filters: + branches: + # Forked pull requests have CIRCLE_BRANCH set to pull/XXX + ignore: /pull\/[0-9]+/ - test-go: requires: - pre-flight-checks @@ -31,5 +39,5 @@ jobs: requires: - pre-flight-checks - semgrep: - requires: - - pre-flight-checks + requires: + - pre-flight-checks diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 12e1f94f99a12..01222c413b24e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,11 +1,6 @@ name: build -on: - workflow_dispatch: - push: - branches-ignore: - - docs/** - - backport/docs/** +on: [ workflow_dispatch, push ] env: PKG_NAME: "vault" @@ -66,7 +61,7 @@ jobs: matrix: goos: [ freebsd, windows, netbsd, openbsd, solaris ] goarch: [ "386", "amd64", "arm" ] - go: [ "1.18.4" ] + go: [ "1.17.12" ] exclude: - goos: solaris goarch: 386 @@ -118,7 +113,7 @@ jobs: matrix: goos: [linux] goarch: ["arm", "arm64", "386", "amd64"] - go: ["1.18.4"] + go: ["1.17.12"] fail-fast: true name: Go ${{ matrix.go }} ${{ matrix.goos }} ${{ matrix.goarch }} build @@ -195,7 +190,7 @@ jobs: matrix: goos: [ darwin ] goarch: [ "amd64", "arm64" ] - go: [ "1.18.4" ] + go: [ "1.17.12" ] fail-fast: true name: Go ${{ matrix.go }} ${{ matrix.goos }} ${{ matrix.goarch }} build steps: diff --git a/.github/workflows/changelog-checker.yml b/.github/workflows/changelog-checker.yml index d8a380270b263..9addf91761b0c 100644 --- a/.github/workflows/changelog-checker.yml +++ b/.github/workflows/changelog-checker.yml @@ -39,11 +39,11 @@ jobs: if [ -z "$changelog_files" ]; then echo "Not found." - echo "looking for changelog file matching changelog/_go-ver-*.txt" + echo "looking for changelog file matching changelog/go-ver-*.txt" # If we do not find a file matching the PR # in changelog/, we fail the check # unless we did a Go toolchain version update, in which case we check the # alternative name. - toolchain_files=$(git --no-pager diff --name-only HEAD "$(git merge-base HEAD "origin/${{ github.event.pull_request.base.ref }}")" -- 'changelog/_go-ver-*.txt') + toolchain_files=$(git --no-pager diff --name-only HEAD "$(git merge-base HEAD "origin/${{ github.event.pull_request.base.ref }}")" -- 'changelog/go-ver-*.txt') if [ -z "$toolchain_files" ]; then echo "Not found." echo "" @@ -82,8 +82,8 @@ jobs: exit 1 elif grep -q '^core: Bump Go version' "$changelog_files"; then echo "Don't use PR numbered changelog entries for Go version bumps!" - echo "Please use the format changelog/_go-ver-.txt instead." - echo "Example: _go-ver-1110.txt for Vault 1.11.0" + echo "Please use the format changelog/go-ver-.txt instead." + echo "Example: go-ver-1110.txt for Vault 1.11.0" exit 1 else echo "Found changelog entry in PR!" diff --git a/.github/workflows/oss.yml b/.github/workflows/oss.yml deleted file mode 100644 index 4e03b9761ba41..0000000000000 --- a/.github/workflows/oss.yml +++ /dev/null @@ -1,128 +0,0 @@ -# Open Source Community Workflows - -name: Project triage -on: - pull_request: - types: [opened, reopened] - # Runs on PRs to main - branches: - - main - - issues: - types: [opened, reopened] - -jobs: - add-to-projects: - # exclude internal PRs - if: github.event.pull_request.head.repo.owner.login != 'hashicorp' && ((github.event.action == 'reopened') || (github.event.action == 'opened')) - name: Add issue or PR to projects - runs-on: ubuntu-latest - steps: - - if: github.event.pull_request != null - uses: actions/checkout@v3 - - if: github.event.pull_request != null - uses: dorny/paths-filter@v2 - id: changes - with: - # derived from CODEOWNERS - filters: | - cryptosec: - - 'builtin/logical/pki/**' - - 'builtin/logical/ssh/**' - - 'builtin/logical/totp/**' - - 'builtin/logical/transit/**' - ecosystem: - - 'builtin/credential/aws/**' - - 'builtin/credential/github/**' - - 'builtin/credential/ldap/**' - - 'builtin/credential/okta/**' - - 'builtin/logical/aws/**' - - 'builtin/logical/cassandra/**' - - 'builtin/logical/consul/**' - - 'builtin/logical/database/**' - - 'builtin/logical/mongodb/**' - - 'builtin/logical/mssql/**' - - 'builtin/logical/mysql/**' - - 'builtin/logical/nomad/**' - - 'builtin/logical/postgresql/**' - - 'builtin/logical/rabbitmq/**' - - 'command/agent/**' - - 'plugins/**' - - 'vault/plugin_catalog.go' - - 'ui/app/components/auth-jwt.js' - - 'ui/app/routes/vault/cluster/oidc-*.js' - devex: - - 'api/**' - - 'command/**' - ui: - - 'ui/**' - - - name: "Default to core board" - run: echo "PROJECT=170" >> $GITHUB_ENV - - if: github.event.pull_request != null && steps.changes.outputs.cryptosec == 'true' - run: echo "PROJECT=172" >> $GITHUB_ENV - - if: github.event.pull_request != null && steps.changes.outputs.ecosystem == 'true' - run: echo "PROJECT=169" >> $GITHUB_ENV - - if: github.event.pull_request != null && steps.changes.outputs.devex == 'true' - run: echo "PROJECT=176" >> $GITHUB_ENV - - if: github.event.pull_request != null && steps.changes.outputs.ui == 'true' - run: echo "PROJECT=171" >> $GITHUB_ENV - - - uses: actions/add-to-project@v0.3.0 - with: - project-url: https://github.com/orgs/hashicorp/projects/${{ env.PROJECT }} - github-token: ${{ secrets.TRIAGE_GITHUB_TOKEN }} - - # example of something more complicated: deleting an issue or PR automatically (though this is done in the project workflows already) - # we have to use the GraphQL API for anything involving projects. - # - # get-project: - # name: Get project data - # runs-on: ubuntu-latest - # if: github.event.action == 'closed' || github.event.action == 'deleted' - # outputs: - # project_id: ${{ steps.get-project.outputs.project_id }} - # steps: - # - id: get-project - # name: Get project data - # env: - # GITHUB_TOKEN: ${{ secrets.TRIAGE_GITHUB_TOKEN }} - # ORGANIZATION: hashicorp - # PROJECT_NUMBER: 169 - # run: | - # gh api graphql -f query=' - # query($org: String!, $number: Int!) { - # organization(login: $org){ - # projectV2(number: $number) { - # id - # } - # } - # }' -f org=$ORGANIZATION -F number=$PROJECT_NUMBER > project_data.json - # echo "::set-output name=project_id::$(jq '.data.organization.projectV2.id' project_data.json)" - - # delete-from-project: - # name: Remove issue or PR from project - # needs: [get-project] - # if: github.event.action == 'closed' || github.event.action == 'deleted' - # runs-on: ubuntu-latest - # steps: - # - name: Remove issue or PR - # env: - # GITHUB_TOKEN: ${{ secrets.TRIAGE_GITHUB_TOKEN }} - # run: | - # PROJECT_ID=${{ needs.get-project.outputs.project_id }} - # item_id=${{ github.event.issue.node_id }} - # if [ -z "$item_id" ]; then - # item_id=${{ github.event.pull_request.node_id }} - # fi - # gh api graphql -f query=' - # mutation($project_id: ID!, $item_id: ID!) { - # deleteProjectV2Item( - # input: { - # projectId: $project_id - # itemId: $item_id - # } - # ) { - # deletedItemId - # } - # }' -f project_id=$PROJECT_ID -f item_id=$item_id || true \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ad49739acb95..5dd2225a1233d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,195 +1,34 @@ -## 1.12.0 -### Unreleased - -CHANGES: - -* core: Bump Go version to 1.18.4. -* identity: a request to `/identity/group` that includes `member_group_ids` that contains a cycle will now be responded to with a 400 rather than 500 [[GH-15912](https://github.com/hashicorp/vault/pull/15912)] -* licensing (enterprise): Terminated licenses will no longer result in shutdown. Instead, upgrades -will not be allowed if the license termination time is before the build date of the binary. - -IMPROVEMENTS: - -* activity (enterprise): Added new clients unit tests to test accuracy of estimates -* agent: Added `disable_idle_connections` configuration to disable leaving idle connections open in auto-auth, caching and templating. [[GH-15986](https://github.com/hashicorp/vault/pull/15986)] -* agent: Added `disable_keep_alives` configuration to disable keep alives in auto-auth, caching and templating. [[GH-16479](https://github.com/hashicorp/vault/pull/16479)] -* agent: JWT auto auth now supports a `remove_jwt_after_reading` config option which defaults to true. [[GH-11969](https://github.com/hashicorp/vault/pull/11969)] -* auth/aws: PKCS7 signatures will now use SHA256 by default in prep for Go 1.18 [[GH-16455](https://github.com/hashicorp/vault/pull/16455)] -* auth/gcp: Add support for GCE regional instance groups [[GH-16435](https://github.com/hashicorp/vault/pull/16435)] -* auth/jwt: Adds support for Microsoft US Gov L4 to the Azure provider for groups fetching. [[GH-16525](https://github.com/hashicorp/vault/pull/16525)] -* auth/jwt: Improves detection of Windows Subsystem for Linux (WSL) for CLI-based logins. [[GH-16525](https://github.com/hashicorp/vault/pull/16525)] -* auth/oidc: Adds support for group membership parsing when using SecureAuth as an OIDC provider. [[GH-16274](https://github.com/hashicorp/vault/pull/16274)] -* cli: CLI commands will print a warning if flags will be ignored because they are passed after positional arguments. [[GH-16441](https://github.com/hashicorp/vault/pull/16441)] -* command/audit: Improve missing type error message [[GH-16409](https://github.com/hashicorp/vault/pull/16409)] -* command/server: add `-dev-tls` and `-dev-tls-cert-dir` subcommands to create a Vault dev server with generated certificates and private key. [[GH-16421](https://github.com/hashicorp/vault/pull/16421)] -* core (enterprise): Add check to `vault server` command to ensure configured storage backend is supported. -* core/activity: generate hyperloglogs containing clientIds for each month during precomputation [[GH-16146](https://github.com/hashicorp/vault/pull/16146)] -* core/activity: refactor activity log api to reuse partial api functions in activity endpoint when current month is specified [[GH-16162](https://github.com/hashicorp/vault/pull/16162)] -* core/activity: use monthly hyperloglogs to calculate new clients approximation for current month [[GH-16184](https://github.com/hashicorp/vault/pull/16184)] -* core/quotas (enterprise): Added ability to add path suffixes for lease-count resource quotas -* core/quotas (enterprise): Added ability to add role information for lease-count resource quotas, to limit login requests on auth mounts made using that role -* core/quotas: Added ability to add path suffixes for rate-limit resource quotas [[GH-15989](https://github.com/hashicorp/vault/pull/15989)] -* core/quotas: Added ability to add role information for rate-limit resource quotas, to limit login requests on auth mounts made using that role [[GH-16115](https://github.com/hashicorp/vault/pull/16115)] -* core: Add `sys/loggers` and `sys/loggers/:name` endpoints to provide ability to modify logging verbosity [[GH-16111](https://github.com/hashicorp/vault/pull/16111)] -* core: Limit activity log client count usage by namespaces [[GH-16000](https://github.com/hashicorp/vault/pull/16000)] -* core: remove gox [[GH-16353](https://github.com/hashicorp/vault/pull/16353)] -* docs: Clarify the behaviour of local mounts in the context of DR replication [[GH-16218](https://github.com/hashicorp/vault/pull/16218)] -* identity/oidc: allows filtering the list providers response by an allowed_client_id [[GH-16181](https://github.com/hashicorp/vault/pull/16181)] -* identity: Prevent possibility of data races on entity creation. [[GH-16487](https://github.com/hashicorp/vault/pull/16487)] -* physical/postgresql: pass context to queries to propagate timeouts and cancellations on requests. [[GH-15866](https://github.com/hashicorp/vault/pull/15866)] -* secret/nomad: allow reading CA and client auth certificate from /nomad/config/access [[GH-15809](https://github.com/hashicorp/vault/pull/15809)] -* secret/pki: Add signature_bits to sign-intermediate, sign-verbatim endpoints [[GH-16124](https://github.com/hashicorp/vault/pull/16124)] -* secret/pki: Allow issuing certificates with non-domain, non-email Common Names from roles, sign-verbatim, and as issuers (`cn_validations`). [[GH-15996](https://github.com/hashicorp/vault/pull/15996)] -* secret/transit: Allow importing Ed25519 keys from PKCS#8 with inner RFC 5915 ECPrivateKey blobs (NSS-wrapped keys). [[GH-15742](https://github.com/hashicorp/vault/pull/15742)] -* secrets/ad: set config default length only if password_policy is missing [[GH-16140](https://github.com/hashicorp/vault/pull/16140)] -* secrets/kubernetes: Add allowed_kubernetes_namespace_selector to allow selecting Kubernetes namespaces with a label selector when configuring roles. [[GH-16240](https://github.com/hashicorp/vault/pull/16240)] -* secrets/ssh: Allow additional text along with a template definition in defaultExtension value fields. [[GH-16018](https://github.com/hashicorp/vault/pull/16018)] -* secrets/ssh: Allow the use of Identity templates in the `default_user` field [[GH-16351](https://github.com/hashicorp/vault/pull/16351)] -* ssh: Addition of an endpoint `ssh/issue/:role` to allow the creation of signed key pairs [[GH-15561](https://github.com/hashicorp/vault/pull/15561)] -* ui: Changed the tokenBoundCidrs tooltip content to clarify that comma separated values are not accepted in this field. [[GH-15852](https://github.com/hashicorp/vault/pull/15852)] -* ui: Removed deprecated version of core-js 2.6.11 [[GH-15898](https://github.com/hashicorp/vault/pull/15898)] -* ui: Renamed labels under Tools for wrap, lookup, rewrap and unwrap with description. [[GH-16489](https://github.com/hashicorp/vault/pull/16489)] -* website/docs: Update replication docs to mention Integrated Storage [[GH-16063](https://github.com/hashicorp/vault/pull/16063)] - -BUG FIXES: - -* activity: Add timestamp to current month calculation and remove deduplication for current month [[GH-16447](https://github.com/hashicorp/vault/pull/16447)] -* agent/template: Fix parsing error for the exec stanza [[GH-16231](https://github.com/hashicorp/vault/pull/16231)] -* agent: Update consul-template for pkiCert bug fixes [[GH-16087](https://github.com/hashicorp/vault/pull/16087)] -* api/sys/internal/specs/openapi: support a new "dynamic" query parameter to generate generic mountpaths [[GH-15835](https://github.com/hashicorp/vault/pull/15835)] -* api: Fixed issue with internal/ui/mounts and internal/ui/mounts/(?P.+) endpoints where it was not properly handling /auth/ [[GH-15552](https://github.com/hashicorp/vault/pull/15552)] -* api: properly handle switching to/from unix domain socket when changing client address [[GH-11904](https://github.com/hashicorp/vault/pull/11904)] -* core (enterprise): Fix bug where wrapping token lookup does not work within namespaces. [[GH-15583](https://github.com/hashicorp/vault/pull/15583)] -* core (enterprise): Fix creation of duplicate entities via alias metadata changes on local auth mounts. -* core/auth: Return a 403 instead of a 500 for a malformed SSCT [[GH-16112](https://github.com/hashicorp/vault/pull/16112)] -* core/identity: Replicate member_entity_ids and policies in identity/group across nodes identically [[GH-16088](https://github.com/hashicorp/vault/pull/16088)] -* core/quotas: Added globbing functionality on the end of path suffix quota paths [[GH-16386](https://github.com/hashicorp/vault/pull/16386)] -* core/replication (enterprise): Don't flush merkle tree pages to disk after losing active duty -* core/seal: Fix possible keyring truncation when using the file backend. [[GH-15946](https://github.com/hashicorp/vault/pull/15946)] -* core: Fixes parsing boolean values for ha_storage backends in config [[GH-15900](https://github.com/hashicorp/vault/pull/15900)] -* core: Increase the allowed concurrent gRPC streams over the cluster port. [[GH-16327](https://github.com/hashicorp/vault/pull/16327)] -* core: Validate input parameters for vault operator init command [[GH-16379](https://github.com/hashicorp/vault/pull/16379)] -* database: Invalidate queue should cancel context first to avoid deadlock [[GH-15933](https://github.com/hashicorp/vault/pull/15933)] -* debug: Fix panic when capturing debug bundle on Windows [[GH-14399](https://github.com/hashicorp/vault/pull/14399)] -* identity (enterprise): Fix a data race when creating an entity for a local alias. -* openapi: Fixed issue where information about /auth/token endpoints was not present with explicit policy permissions [[GH-15552](https://github.com/hashicorp/vault/pull/15552)] -* plugin/multiplexing: Fix panic when id doesn't exist in connection map [[GH-16094](https://github.com/hashicorp/vault/pull/16094)] -* quotas/lease-count: Fix lease-count quotas on mounts not properly being enforced when the lease generating request is a read [[GH-15735](https://github.com/hashicorp/vault/pull/15735)] -* replication (enterprise): Fix data race in saveCheckpoint. -* secret/pki: Do not fail validation with a legacy key_bits default value and key_type=any when signing CSRs [[GH-16246](https://github.com/hashicorp/vault/pull/16246)] -* secrets/gcp: Fixes duplicate static account key creation from performance secondary clusters. [[GH-16534](https://github.com/hashicorp/vault/pull/16534)] -* secrets/kv: Fix `kv get` issue preventing the ability to read a secret when providing a leading slash [[GH-16443](https://github.com/hashicorp/vault/pull/16443)] -* storage/raft (enterprise): Fix some storage-modifying RPCs used by perf standbys that weren't returning the resulting WAL state. -* storage/raft (enterprise): Prevent unauthenticated voter status change with rejoin [[GH-16324](https://github.com/hashicorp/vault/pull/16324)] -* ui: Fix issue logging in with JWT auth method [[GH-16466](https://github.com/hashicorp/vault/pull/16466)] -* ui: Fixed bug where red spellcheck underline appears in sensitive/secret kv values when it should not appear [[GH-15681](https://github.com/hashicorp/vault/pull/15681)] -* ui: OIDC login type uses localStorage instead of sessionStorage [[GH-16170](https://github.com/hashicorp/vault/pull/16170)] -* vault: Fix a bug where duplicate policies could be added to an identity group. [[GH-15638](https://github.com/hashicorp/vault/pull/15638)] - -## 1.11.2 -### August 2, 2022 - -IMPROVEMENTS: - -* agent: Added `disable_keep_alives` configuration to disable keep alives in auto-auth, caching and templating. [[GH-16479](https://github.com/hashicorp/vault/pull/16479)] - -BUG FIXES: - -* core/auth: Return a 403 instead of a 500 for a malformed SSCT [[GH-16112](https://github.com/hashicorp/vault/pull/16112)] -* core: Increase the allowed concurrent gRPC streams over the cluster port. [[GH-16327](https://github.com/hashicorp/vault/pull/16327)] -* secrets/kv: Fix `kv get` issue preventing the ability to read a secret when providing a leading slash [[GH-16443](https://github.com/hashicorp/vault/pull/16443)] -* ui: Fix issue logging in with JWT auth method [[GH-16466](https://github.com/hashicorp/vault/pull/16466)] - -## 1.11.1 -### July 21, 2022 - -CHANGES: - -* core: Bump Go version to 1.17.12. - -IMPROVEMENTS: - -* agent: Added `disable_idle_connections` configuration to disable leaving idle connections open in auto-auth, caching and templating. [[GH-15986](https://github.com/hashicorp/vault/pull/15986)] -* core: Add `sys/loggers` and `sys/loggers/:name` endpoints to provide ability to modify logging verbosity [[GH-16111](https://github.com/hashicorp/vault/pull/16111)] -* secrets/ssh: Allow additional text along with a template definition in defaultExtension value fields. [[GH-16018](https://github.com/hashicorp/vault/pull/16018)] - -BUG FIXES: - -* agent/template: Fix parsing error for the exec stanza [[GH-16231](https://github.com/hashicorp/vault/pull/16231)] -* agent: Update consul-template for pkiCert bug fixes [[GH-16087](https://github.com/hashicorp/vault/pull/16087)] -* core/identity: Replicate member_entity_ids and policies in identity/group across nodes identically [[GH-16088](https://github.com/hashicorp/vault/pull/16088)] -* core/replication (enterprise): Don't flush merkle tree pages to disk after losing active duty -* core/seal: Fix possible keyring truncation when using the file backend. [[GH-15946](https://github.com/hashicorp/vault/pull/15946)] -* kmip (enterprise): Return SecretData as supported Object Type. -* plugin/multiplexing: Fix panic when id doesn't exist in connection map [[GH-16094](https://github.com/hashicorp/vault/pull/16094)] -* secret/pki: Do not fail validation with a legacy key_bits default value and key_type=any when signing CSRs [[GH-16246](https://github.com/hashicorp/vault/pull/16246)] -* storage/raft (enterprise): Prevent unauthenticated voter status change with rejoin [[GH-16324](https://github.com/hashicorp/vault/pull/16324)] -* transform (enterprise): Fix a bug in the handling of nested or unmatched capture groups in FPE transformations. -* ui: OIDC login type uses localStorage instead of sessionStorage [[GH-16170](https://github.com/hashicorp/vault/pull/16170)] - -SECURITY: -* storage/raft (enterprise): Vault Enterprise (“Vault”) clusters using Integrated Storage expose an unauthenticated API endpoint that could be abused to override the voter status of a node within a Vault HA cluster, introducing potential for future data loss or catastrophic failure. This vulnerability, CVE-2022-36129, was fixed in Vault 1.9.8, 1.10.5, and 1.11.1. [[HCSEC-2022-15](https://discuss.hashicorp.com/t/hcsec-2022-15-vault-enterprise-does-not-verify-existing-voter-status-when-joining-an-integrated-storage-ha-node/42420)] - ## 1.11.0 -### June 20, 2022 +### Unreleased CHANGES: * auth/aws: Add RoleSession to DisplayName when using assumeRole for authentication [[GH-14954](https://github.com/hashicorp/vault/pull/14954)] -* auth/kubernetes: If `kubernetes_ca_cert` is unset, and there is no pod-local CA available, an error will be surfaced when writing config instead of waiting for login. [[GH-15584](https://github.com/hashicorp/vault/pull/15584)] * auth: Remove support for legacy MFA (https://www.vaultproject.io/docs/v1.10.x/auth/mfa) [[GH-14869](https://github.com/hashicorp/vault/pull/14869)] -* core/fips: Disable and warn about entropy augmentation in FIPS 140-2 Inside mode [[GH-15858](https://github.com/hashicorp/vault/pull/15858)] * core: A request that fails path validation due to relative path check will now be responded to with a 400 rather than 500. [[GH-14328](https://github.com/hashicorp/vault/pull/14328)] -* core: Bump Go version to 1.17.11. [[GH-go-ver-1110](https://github.com/hashicorp/vault/pull/go-ver-1110)] -* database & storage: Change underlying driver library from [lib/pq](https://github.com/lib/pq) to [pgx](https://github.com/jackc/pgx). This change affects Redshift & Postgres database secrets engines, and CockroachDB & Postgres storage engines [[GH-15343](https://github.com/hashicorp/vault/pull/15343)] +* core: Bump Go version to 1.17.9. [[GH-go-ver-1110](https://github.com/hashicorp/vault/pull/go-ver-1110)] * licensing (enterprise): Remove support for stored licenses and associated `sys/license` and `sys/license/signed` endpoints in favor of [autoloaded licenses](https://www.vaultproject.io/docs/enterprise/license/autoloading). * replication (enterprise): The `/sys/replication/performance/primary/mount-filter` endpoint has been removed. Please use [Paths Filter](https://www.vaultproject.io/api-docs/system/replication/replication-performance#create-paths-filter) instead. -* secret/pki: Remove unused signature_bits parameter from intermediate CSR generation; this parameter doesn't control the final certificate's signature algorithm selection as that is up to the signing CA [[GH-15478](https://github.com/hashicorp/vault/pull/15478)] -* secrets/kubernetes: Split `additional_metadata` into `extra_annotations` and `extra_labels` parameters [[GH-15655](https://github.com/hashicorp/vault/pull/15655)] -* secrets/pki: A new aliased api path (/pki/issuer/:issuer_ref/sign-self-issued) -providing the same functionality as the existing API(/pki/root/sign-self-issued) -does not require sudo capabilities but the latter still requires it in an -effort to maintain backwards compatibility. [[GH-15211](https://github.com/hashicorp/vault/pull/15211)] -* secrets/pki: Err on unknown role during sign-verbatim. [[GH-15543](https://github.com/hashicorp/vault/pull/15543)] -* secrets/pki: Existing CRL API (/pki/crl) now returns an X.509 v2 CRL instead -of a v1 CRL. [[GH-15100](https://github.com/hashicorp/vault/pull/15100)] -* secrets/pki: The `ca_chain` response field within issuing (/pki/issue/:role) -and signing APIs will now include the root CA certificate if the mount is -aware of it. [[GH-15155](https://github.com/hashicorp/vault/pull/15155)] -* secrets/pki: existing Delete Root API (pki/root) will now delete all issuers -and keys within the mount path. [[GH-15004](https://github.com/hashicorp/vault/pull/15004)] -* secrets/pki: existing Generate Root (pki/root/generate/:type), -Set Signed Intermediate (/pki/intermediate/set-signed) APIs will -add new issuers/keys to a mount instead of warning that an existing CA exists [[GH-14975](https://github.com/hashicorp/vault/pull/14975)] -* secrets/pki: the signed CA certificate from the sign-intermediate api will now appear within the ca_chain -response field along with the issuer's ca chain. [[GH-15524](https://github.com/hashicorp/vault/pull/15524)] * ui: Upgrade Ember to version 3.28 [[GH-14763](https://github.com/hashicorp/vault/pull/14763)] FEATURES: -* **Autopilot Improvements (Enterprise)**: Autopilot on Vault Enterprise now supports automated upgrades and redundancy zones when using integrated storage. -* **KeyMgmt UI**: Add UI support for managing the Key Management Secrets Engine [[GH-15523](https://github.com/hashicorp/vault/pull/15523)] -* **Kubernetes Secrets Engine**: This new secrets engine generates Kubernetes service account tokens, service accounts, role bindings, and roles dynamically. [[GH-15551](https://github.com/hashicorp/vault/pull/15551)] * **Non-Disruptive Intermediate/Root Certificate Rotation**: This allows import, generation and configuration of any number of keys and/or issuers within a PKI mount, providing operators the ability to rotate certificates in place without affecting existing client configurations. [[GH-15277](https://github.com/hashicorp/vault/pull/15277)] -* **Print minimum required policy for any command**: The global CLI flag `-output-policy` can now be used with any command to print out the minimum required policy HCL for that operation, including whether the given path requires the "sudo" capability. [[GH-14899](https://github.com/hashicorp/vault/pull/14899)] -* **Snowflake Database Plugin**: Adds ability to manage RSA key pair credentials for dynamic and static Snowflake users. [[GH-15376](https://github.com/hashicorp/vault/pull/15376)] -* **Transit BYOK**: Allow import of externally-generated keys into the Transit secrets engine. [[GH-15414](https://github.com/hashicorp/vault/pull/15414)] +* api/command: Global -output-policy flag to determine minimum required policy HCL for a given operation [[GH-14899](https://github.com/hashicorp/vault/pull/14899)] * nomad: Bootstrap Nomad ACL system if no token is provided [[GH-12451](https://github.com/hashicorp/vault/pull/12451)] * storage/dynamodb: Added `AWS_DYNAMODB_REGION` environment variable. [[GH-15054](https://github.com/hashicorp/vault/pull/15054)] IMPROVEMENTS: -* activity: return nil response months in activity log API when no month data exists [[GH-15420](https://github.com/hashicorp/vault/pull/15420)] * agent/auto-auth: Add `min_backoff` to the method stanza for configuring initial backoff duration. [[GH-15204](https://github.com/hashicorp/vault/pull/15204)] -* agent: Update consul-template to v0.29.0 [[GH-15293](https://github.com/hashicorp/vault/pull/15293)] +* agent: Update consult-template to v0.29.0 [[GH-15293](https://github.com/hashicorp/vault/pull/15293)] * agent: Upgrade hashicorp/consul-template version for sprig template functions and improved writeTo function [[GH-15092](https://github.com/hashicorp/vault/pull/15092)] -* api/monitor: Add log_format option to allow for logs to be emitted in JSON format [[GH-15536](https://github.com/hashicorp/vault/pull/15536)] * api: Add ability to pass certificate as PEM bytes to api.Client. [[GH-14753](https://github.com/hashicorp/vault/pull/14753)] * api: Add context-aware functions to vault/api for each API wrapper function. [[GH-14388](https://github.com/hashicorp/vault/pull/14388)] * api: Added MFALogin() for handling MFA flow when using login helpers. [[GH-14900](https://github.com/hashicorp/vault/pull/14900)] @@ -197,110 +36,49 @@ IMPROVEMENTS: being what the endpoints were expecting, or if the parameters supplied get replaced by the values in the endpoint's path itself, warnings will be added to the non-empty responses listing all the ignored and replaced parameters. [[GH-14962](https://github.com/hashicorp/vault/pull/14962)] -* api: KV helper methods to simplify the common use case of reading and writing KV secrets [[GH-15305](https://github.com/hashicorp/vault/pull/15305)] * api: Provide a helper method WithNamespace to create a cloned client with a new NS [[GH-14963](https://github.com/hashicorp/vault/pull/14963)] -* api: Support VAULT_PROXY_ADDR environment variable to allow overriding the Vault client's HTTP proxy. [[GH-15377](https://github.com/hashicorp/vault/pull/15377)] * api: Use the context passed to the api/auth Login helpers. [[GH-14775](https://github.com/hashicorp/vault/pull/14775)] -* api: make ListPlugins parse only known plugin types [[GH-15434](https://github.com/hashicorp/vault/pull/15434)] -* audit: Add a policy_results block into the audit log that contains the set of -policies that granted this request access. [[GH-15457](https://github.com/hashicorp/vault/pull/15457)] -* audit: Include mount_accessor in audit request and response logs [[GH-15342](https://github.com/hashicorp/vault/pull/15342)] -* audit: added entity_created boolean to audit log, set when login operations create an entity [[GH-15487](https://github.com/hashicorp/vault/pull/15487)] -* auth/aws: Add rsa2048 signature type to API [[GH-15719](https://github.com/hashicorp/vault/pull/15719)] -* auth/gcp: Enable the Google service endpoints used by the underlying client to be customized [[GH-15592](https://github.com/hashicorp/vault/pull/15592)] -* auth/gcp: Vault CLI now infers the service account email when running on Google Cloud [[GH-15592](https://github.com/hashicorp/vault/pull/15592)] -* auth/jwt: Adds ability to use JSON pointer syntax for the `user_claim` value. [[GH-15593](https://github.com/hashicorp/vault/pull/15593)] * auth/okta: Add support for Google provider TOTP type in the Okta auth method [[GH-14985](https://github.com/hashicorp/vault/pull/14985)] -* auth/okta: Add support for performing [the number -challenge](https://help.okta.com/en-us/Content/Topics/Mobile/ov-admin-config.htm?cshid=csh-okta-verify-number-challenge-v1#enable-number-challenge) -during an Okta Verify push challenge [[GH-15361](https://github.com/hashicorp/vault/pull/15361)] -* auth: Globally scoped Login MFA method Get/List endpoints [[GH-15248](https://github.com/hashicorp/vault/pull/15248)] * auth: enforce a rate limit for TOTP passcode validation attempts [[GH-14864](https://github.com/hashicorp/vault/pull/14864)] -* auth: forward cached MFA auth response to the leader using RPC instead of forwarding all login requests [[GH-15469](https://github.com/hashicorp/vault/pull/15469)] * cli/debug: added support for retrieving metrics from DR clusters if `unauthenticated_metrics_access` is enabled [[GH-15316](https://github.com/hashicorp/vault/pull/15316)] * cli/vault: warn when policy name contains upper-case letter [[GH-14670](https://github.com/hashicorp/vault/pull/14670)] * cli: Alternative flag-based syntax for KV to mitigate confusion from automatically appended /data [[GH-14807](https://github.com/hashicorp/vault/pull/14807)] * cockroachdb: add high-availability support [[GH-12965](https://github.com/hashicorp/vault/pull/12965)] -* command/debug: Add log_format flag to allow for logs to be emitted in JSON format [[GH-15536](https://github.com/hashicorp/vault/pull/15536)] -* command: Support optional '-log-level' flag to be passed to 'operator migrate' command (defaults to info). Also support VAULT_LOG_LEVEL env var. [[GH-15405](https://github.com/hashicorp/vault/pull/15405)] -* command: Support the optional '-detailed' flag to be passed to 'vault list' command to show ListResponseWithInfo data. Also supports the VAULT_DETAILED env var. [[GH-15417](https://github.com/hashicorp/vault/pull/15417)] * core (enterprise): Include `termination_time` in `sys/license/status` response * core (enterprise): Include termination time in `license inspect` command output +* core : check uid and permissions of config dir, config file, plugin dir and plugin binaries [[GH-14817](https://github.com/hashicorp/vault/pull/14817)] * core,transit: Allow callers to choose random byte source including entropy augmentation sources for the sys/tools/random and transit/random endpoints. [[GH-15213](https://github.com/hashicorp/vault/pull/15213)] * core/activity: Order month data in ascending order of timestamps [[GH-15259](https://github.com/hashicorp/vault/pull/15259)] -* core/activity: allow client counts to be precomputed and queried on non-contiguous chunks of data [[GH-15352](https://github.com/hashicorp/vault/pull/15352)] -* core/managed-keys (enterprise): Allow configuring the number of parallel operations to PKCS#11 managed keys. -* core: Add an export API for historical activity log data [[GH-15586](https://github.com/hashicorp/vault/pull/15586)] * core: Add new DB methods that do not prepare statements. [[GH-15166](https://github.com/hashicorp/vault/pull/15166)] -* core: check uid and permissions of config dir, config file, plugin dir and plugin binaries [[GH-14817](https://github.com/hashicorp/vault/pull/14817)] * core: Fix some identity data races found by Go race detector (no known impact yet). [[GH-15123](https://github.com/hashicorp/vault/pull/15123)] * core: Include build date in `sys/seal-status` and `sys/version-history` endpoints. [[GH-14957](https://github.com/hashicorp/vault/pull/14957)] * core: Upgrade github.org/x/crypto/ssh [[GH-15125](https://github.com/hashicorp/vault/pull/15125)] -* kmip (enterprise): Implement operations Query, Import, Encrypt and Decrypt. Improve operations Locate, Add Attribute, Get Attributes and Get Attribute List to handle most supported attributes. -* mfa/okta: migrate to use official Okta SDK [[GH-15355](https://github.com/hashicorp/vault/pull/15355)] * sdk: Change OpenAPI code generator to extract request objects into /components/schemas and reference them by name. [[GH-14217](https://github.com/hashicorp/vault/pull/14217)] * secrets/consul: Add support for Consul node-identities and service-identities [[GH-15295](https://github.com/hashicorp/vault/pull/15295)] * secrets/consul: Vault is now able to automatically bootstrap the Consul ACL system. [[GH-10751](https://github.com/hashicorp/vault/pull/10751)] -* secrets/database/elasticsearch: Use the new /_security base API path instead of /_xpack/security when managing elasticsearch. [[GH-15614](https://github.com/hashicorp/vault/pull/15614)] -* secrets/pki: Add not_before_duration to root CA generation, intermediate CA signing paths. [[GH-14178](https://github.com/hashicorp/vault/pull/14178)] -* secrets/pki: Add support for CPS URLs and User Notice to Policy Information [[GH-15751](https://github.com/hashicorp/vault/pull/15751)] -* secrets/pki: Allow operators to control the issuing certificate behavior when -the requested TTL is beyond the NotAfter value of the signing certificate [[GH-15152](https://github.com/hashicorp/vault/pull/15152)] -* secrets/pki: Always return CRLs, URLs configurations, even if using the default value. [[GH-15470](https://github.com/hashicorp/vault/pull/15470)] -* secrets/pki: Enable Patch Functionality for Roles and Issuers (API only) [[GH-15510](https://github.com/hashicorp/vault/pull/15510)] -* secrets/pki: Have pki/sign-verbatim use the not_before_duration field defined in the role [[GH-15429](https://github.com/hashicorp/vault/pull/15429)] -* secrets/pki: Warn on empty Subject field during issuer generation (root/generate and root/sign-intermediate). [[GH-15494](https://github.com/hashicorp/vault/pull/15494)] -* secrets/pki: Warn on missing AIA access information when generating issuers (config/urls). [[GH-15509](https://github.com/hashicorp/vault/pull/15509)] * secrets/pki: Warn when `generate_lease` and `no_store` are both set to `true` on requests. [[GH-14292](https://github.com/hashicorp/vault/pull/14292)] -* secrets/ssh: Add connection timeout of 1 minute for outbound SSH connection in deprecated Dynamic SSH Keys mode. [[GH-15440](https://github.com/hashicorp/vault/pull/15440)] -* secrets/ssh: Support for `add_before_duration` in SSH [[GH-15250](https://github.com/hashicorp/vault/pull/15250)] * sentinel (enterprise): Upgrade sentinel to [v0.18.5](https://docs.hashicorp.com/sentinel/changelog#0-18-5-january-14-2022) to avoid potential naming collisions in the remote installer * storage/raft: Use larger timeouts at startup to reduce likelihood of inducing elections. [[GH-15042](https://github.com/hashicorp/vault/pull/15042)] -* ui: Allow namespace param to be parsed from state queryParam [[GH-15378](https://github.com/hashicorp/vault/pull/15378)] -* ui: Default auto-rotation period in transit is 30 days [[GH-15474](https://github.com/hashicorp/vault/pull/15474)] * ui: Parse schema refs from OpenAPI [[GH-14508](https://github.com/hashicorp/vault/pull/14508)] -* ui: Remove stored license references [[GH-15513](https://github.com/hashicorp/vault/pull/15513)] * ui: Remove storybook. [[GH-15074](https://github.com/hashicorp/vault/pull/15074)] * ui: Replaces the IvyCodemirror wrapper with a custom ember modifier. [[GH-14659](https://github.com/hashicorp/vault/pull/14659)] -* website/docs: Add usage documentation for Kubernetes Secrets Engine [[GH-15527](https://github.com/hashicorp/vault/pull/15527)] * website/docs: added a link to an Enigma secret plugin. [[GH-14389](https://github.com/hashicorp/vault/pull/14389)] -DEPRECATIONS: - -* docs: Document removal of X.509 certificates with signatures who use SHA-1 in Vault 1.12 [[GH-15581](https://github.com/hashicorp/vault/pull/15581)] -* secrets/consul: Deprecate old parameters "token_type" and "policy" [[GH-15550](https://github.com/hashicorp/vault/pull/15550)] -* secrets/consul: Deprecate parameter "policies" in favor of "consul_policies" for consistency [[GH-15400](https://github.com/hashicorp/vault/pull/15400)] - BUG FIXES: * Fixed panic when adding or modifying a Duo MFA Method in Enterprise * agent: Fix log level mismatch between ERR and ERROR [[GH-14424](https://github.com/hashicorp/vault/pull/14424)] -* agent: Redact auto auth token from renew endpoints [[GH-15380](https://github.com/hashicorp/vault/pull/15380)] * api/sys/raft: Update RaftSnapshotRestore to use net/http client allowing bodies larger than allocated memory to be streamed [[GH-14269](https://github.com/hashicorp/vault/pull/14269)] * api: Fixes bug where OutputCurlString field was unintentionally being copied over during client cloning [[GH-14968](https://github.com/hashicorp/vault/pull/14968)] * api: Respect increment value in grace period calculations in LifetimeWatcher [[GH-14836](https://github.com/hashicorp/vault/pull/14836)] * auth/approle: Add maximum length for input values that result in SHA56 HMAC calculation [[GH-14746](https://github.com/hashicorp/vault/pull/14746)] -* auth/kubernetes: Fix error code when using the wrong service account [[GH-15584](https://github.com/hashicorp/vault/pull/15584)] -* auth/ldap: The logic for setting the entity alias when `username_as_alias` is set -has been fixed. The previous behavior would make a request to the LDAP server to -get `user_attr` before discarding it and using the username instead. This would -make it impossible for a user to connect if this attribute was missing or had -multiple values, even though it would not be used anyway. This has been fixed -and the username is now used without making superfluous LDAP searches. [[GH-15525](https://github.com/hashicorp/vault/pull/15525)] -* auth: Fixed erroneous success message when using vault login in case of two-phase MFA [[GH-15428](https://github.com/hashicorp/vault/pull/15428)] -* auth: Fixed erroneous token information being displayed when using vault login in case of two-phase MFA [[GH-15428](https://github.com/hashicorp/vault/pull/15428)] -* auth: Fixed two-phase MFA information missing from table format when using vault login [[GH-15428](https://github.com/hashicorp/vault/pull/15428)] -* auth: Prevent deleting a valid MFA method ID using the endpoint for a different MFA method type [[GH-15482](https://github.com/hashicorp/vault/pull/15482)] * auth: forward requests subject to login MFA from perfStandby to Active node [[GH-15009](https://github.com/hashicorp/vault/pull/15009)] * auth: load login MFA configuration upon restart [[GH-15261](https://github.com/hashicorp/vault/pull/15261)] * cassandra: Update gocql Cassandra client to fix "no hosts available in the pool" error [[GH-14973](https://github.com/hashicorp/vault/pull/14973)] * cli: Fix panic caused by parsing key=value fields whose value is a single backslash [[GH-14523](https://github.com/hashicorp/vault/pull/14523)] * cli: kv get command now honors trailing spaces to retrieve secrets [[GH-15188](https://github.com/hashicorp/vault/pull/15188)] -* command: do not report listener and storage types as key not found warnings [[GH-15383](https://github.com/hashicorp/vault/pull/15383)] * core (enterprise): Allow local alias create RPCs to persist alias metadata -* core (enterprise): Fix overcounting of lease count quota usage at startup. * core (enterprise): Fix some races in merkle index flushing code found in testing -* core (enterprise): Handle additional edge cases reinitializing PKCS#11 libraries after login errors. * core/config: Only ask the system about network interfaces when address configs contain a template having the format: {{ ... }} [[GH-15224](https://github.com/hashicorp/vault/pull/15224)] * core/managed-keys (enterprise): Allow PKCS#11 managed keys to use 0 as a slot number * core/metrics: Fix incorrect table size metric for local mounts [[GH-14755](https://github.com/hashicorp/vault/pull/14755)] @@ -309,128 +87,33 @@ and the username is now used without making superfluous LDAP searches. [[GH-1552 * core: Fix panic caused by parsing JSON integers for fields defined as comma-delimited strings [[GH-14522](https://github.com/hashicorp/vault/pull/14522)] * core: Fix panic caused by parsing policies with empty slice values. [[GH-14501](https://github.com/hashicorp/vault/pull/14501)] * core: Fix panic for help request URL paths without /v1/ prefix [[GH-14704](https://github.com/hashicorp/vault/pull/14704)] -* core: Limit SSCT WAL checks on perf standbys to raft backends only [[GH-15879](https://github.com/hashicorp/vault/pull/15879)] -* core: Prevent changing file permissions of audit logs when mode 0000 is used. [[GH-15759](https://github.com/hashicorp/vault/pull/15759)] -* core: Prevent metrics generation from causing deadlocks. [[GH-15693](https://github.com/hashicorp/vault/pull/15693)] * core: fixed systemd reloading notification [[GH-15041](https://github.com/hashicorp/vault/pull/15041)] * core: fixing excessive unix file permissions [[GH-14791](https://github.com/hashicorp/vault/pull/14791)] * core: fixing excessive unix file permissions on dir, files and archive created by vault debug command [[GH-14846](https://github.com/hashicorp/vault/pull/14846)] * core: pre-calculate namespace specific paths when tainting a route during postUnseal [[GH-15067](https://github.com/hashicorp/vault/pull/15067)] -* core: renaming the environment variable VAULT_DISABLE_FILE_PERMISSIONS_CHECK to VAULT_ENABLE_FILE_PERMISSIONS_CHECK and adjusting the logic [[GH-15452](https://github.com/hashicorp/vault/pull/15452)] * core: report unused or redundant keys in server configuration [[GH-14752](https://github.com/hashicorp/vault/pull/14752)] * core: time.After() used in a select statement can lead to memory leak [[GH-14814](https://github.com/hashicorp/vault/pull/14814)] -* identity: deduplicate policies when creating/updating identity groups [[GH-15055](https://github.com/hashicorp/vault/pull/15055)] -* mfa/okta: disable client side rate limiting causing delays in push notifications [[GH-15369](https://github.com/hashicorp/vault/pull/15369)] -* plugin: Fix a bug where plugin reload would falsely report success in certain scenarios. [[GH-15579](https://github.com/hashicorp/vault/pull/15579)] -* raft: fix Raft TLS key rotation panic that occurs if active key is more than 24 hours old [[GH-15156](https://github.com/hashicorp/vault/pull/15156)] +* rafft: fix Raft TLS key rotation panic that occurs if active key is more than 24 hours old [[GH-15156](https://github.com/hashicorp/vault/pull/15156)] * raft: Ensure initialMmapSize is set to 0 on Windows [[GH-14977](https://github.com/hashicorp/vault/pull/14977)] * replication (enterprise): fix panic due to missing entity during invalidation of local aliases. [[GH-14622](https://github.com/hashicorp/vault/pull/14622)] * sdk/cidrutil: Only check if cidr contains remote address for IP addresses [[GH-14487](https://github.com/hashicorp/vault/pull/14487)] * sdk: Fix OpenApi spec generator to properly convert TypeInt64 to OAS supported int64 [[GH-15104](https://github.com/hashicorp/vault/pull/15104)] * sdk: Fix OpenApi spec generator to remove duplicate sha_256 parameter [[GH-15163](https://github.com/hashicorp/vault/pull/15163)] * secrets/database: Ensure that a `connection_url` password is redacted in all cases. [[GH-14744](https://github.com/hashicorp/vault/pull/14744)] -* secrets/kv: Fix issue preventing the ability to reset the `delete_version_after` key metadata field to 0s via HTTP `PATCH`. [[GH-15792](https://github.com/hashicorp/vault/pull/15792)] -* secrets/pki: CRLs on performance secondary clusters are now automatically -rebuilt upon changes to the list of issuers. [[GH-15179](https://github.com/hashicorp/vault/pull/15179)] * secrets/pki: Fix handling of "any" key type with default zero signature bits value. [[GH-14875](https://github.com/hashicorp/vault/pull/14875)] * secrets/pki: Fixed bug where larger SHA-2 hashes were truncated with shorter ECDSA CA certificates [[GH-14943](https://github.com/hashicorp/vault/pull/14943)] -* secrets/ssh: Convert role field not_before_duration to seconds before returning it [[GH-15559](https://github.com/hashicorp/vault/pull/15559)] -* storage/raft (enterprise): Auto-snapshot configuration now forbids slashes in file prefixes for all types, and "/" in path prefix for local storage type. Strip leading prefix in path prefix for AWS. Improve error handling/reporting. -* storage/raft: Forward autopilot state requests on perf standbys to active node. [[GH-15493](https://github.com/hashicorp/vault/pull/15493)] -* storage/raft: joining a node to a cluster now ignores any VAULT_NAMESPACE environment variable set on the server process [[GH-15519](https://github.com/hashicorp/vault/pull/15519)] * ui: Fix Generated Token's Policies helpText to clarify that comma separated values are not accepted in this field. [[GH-15046](https://github.com/hashicorp/vault/pull/15046)] * ui: Fix KV secret showing in the edit form after a user creates a new version but doesn't have read capabilities [[GH-14794](https://github.com/hashicorp/vault/pull/14794)] -* ui: Fix inconsistent behavior in client count calendar widget [[GH-15789](https://github.com/hashicorp/vault/pull/15789)] -* ui: Fix issue where metadata tab is hidden even though policy grants access [[GH-15824](https://github.com/hashicorp/vault/pull/15824)] * ui: Fix issue with KV not recomputing model when you changed versions. [[GH-14941](https://github.com/hashicorp/vault/pull/14941)] -* ui: Fixed client count timezone for start and end months [[GH-15167](https://github.com/hashicorp/vault/pull/15167)] -* ui: Fixed unsupported revocation statements field for DB roles [[GH-15573](https://github.com/hashicorp/vault/pull/15573)] * ui: Fixes edit auth method capabilities issue [[GH-14966](https://github.com/hashicorp/vault/pull/14966)] * ui: Fixes issue logging in with OIDC from a listed auth mounts tab [[GH-14916](https://github.com/hashicorp/vault/pull/14916)] -* ui: Revert using localStorage in favor of sessionStorage [[GH-15769](https://github.com/hashicorp/vault/pull/15769)] -* ui: Updated `leasId` to `leaseId` in the "Copy Credentials" section of "Generate AWS Credentials" [[GH-15685](https://github.com/hashicorp/vault/pull/15685)] * ui: fix firefox inability to recognize file format of client count csv export [[GH-15364](https://github.com/hashicorp/vault/pull/15364)] -* ui: fix form validations ignoring default values and disabling submit button [[GH-15560](https://github.com/hashicorp/vault/pull/15560)] * ui: fix search-select component showing blank selections when editing group member entity [[GH-15058](https://github.com/hashicorp/vault/pull/15058)] * ui: masked values no longer give away length or location of special characters [[GH-15025](https://github.com/hashicorp/vault/pull/15025)] -## 1.10.5 -### July 21, 2022 - -CHANGES: - -* core/fips: Disable and warn about entropy augmentation in FIPS 140-2 Inside mode [[GH-15858](https://github.com/hashicorp/vault/pull/15858)] -* core: Bump Go version to 1.17.12. - -IMPROVEMENTS: - -* core: Add `sys/loggers` and `sys/loggers/:name` endpoints to provide ability to modify logging verbosity [[GH-16111](https://github.com/hashicorp/vault/pull/16111)] -* secrets/ssh: Allow additional text along with a template definition in defaultExtension value fields. [[GH-16018](https://github.com/hashicorp/vault/pull/16018)] - -BUG FIXES: - -* agent/template: Fix parsing error for the exec stanza [[GH-16231](https://github.com/hashicorp/vault/pull/16231)] -* core/identity: Replicate member_entity_ids and policies in identity/group across nodes identically [[GH-16088](https://github.com/hashicorp/vault/pull/16088)] -* core/replication (enterprise): Don't flush merkle tree pages to disk after losing active duty -* core/seal: Fix possible keyring truncation when using the file backend. [[GH-15946](https://github.com/hashicorp/vault/pull/15946)] -* core: Limit SSCT WAL checks on perf standbys to raft backends only [[GH-15879](https://github.com/hashicorp/vault/pull/15879)] -* plugin/multiplexing: Fix panic when id doesn't exist in connection map [[GH-16094](https://github.com/hashicorp/vault/pull/16094)] -* secret/pki: Do not fail validation with a legacy key_bits default value and key_type=any when signing CSRs [[GH-16246](https://github.com/hashicorp/vault/pull/16246)] -* storage/raft (enterprise): Prevent unauthenticated voter status with rejoin [[GH-16324](https://github.com/hashicorp/vault/pull/16324)] -* transform (enterprise): Fix a bug in the handling of nested or unmatched capture groups in FPE transformations. -* ui: Fix issue where metadata tab is hidden even though policy grants access [[GH-15824](https://github.com/hashicorp/vault/pull/15824)] -* ui: Revert using localStorage in favor of sessionStorage [[GH-16169](https://github.com/hashicorp/vault/pull/16169)] -* ui: Updated `leasId` to `leaseId` in the "Copy Credentials" section of "Generate AWS Credentials" [[GH-15685](https://github.com/hashicorp/vault/pull/15685)] - -## 1.10.4 -### June 10, 2022 - -CHANGES: - -* core: Bump Go version to 1.17.11. [[GH-go-ver-1104](https://github.com/hashicorp/vault/pull/go-ver-1104)] - -IMPROVEMENTS: - -* api/monitor: Add log_format option to allow for logs to be emitted in JSON format [[GH-15536](https://github.com/hashicorp/vault/pull/15536)] -* auth: Globally scoped Login MFA method Get/List endpoints [[GH-15248](https://github.com/hashicorp/vault/pull/15248)] -* auth: forward cached MFA auth response to the leader using RPC instead of forwarding all login requests [[GH-15469](https://github.com/hashicorp/vault/pull/15469)] -* cli/debug: added support for retrieving metrics from DR clusters if `unauthenticated_metrics_access` is enabled [[GH-15316](https://github.com/hashicorp/vault/pull/15316)] -* command/debug: Add log_format flag to allow for logs to be emitted in JSON format [[GH-15536](https://github.com/hashicorp/vault/pull/15536)] -* core: Fix some identity data races found by Go race detector (no known impact yet). [[GH-15123](https://github.com/hashicorp/vault/pull/15123)] -* storage/raft: Use larger timeouts at startup to reduce likelihood of inducing elections. [[GH-15042](https://github.com/hashicorp/vault/pull/15042)] -* ui: Allow namespace param to be parsed from state queryParam [[GH-15378](https://github.com/hashicorp/vault/pull/15378)] - -BUG FIXES: - -* agent: Redact auto auth token from renew endpoints [[GH-15380](https://github.com/hashicorp/vault/pull/15380)] -* auth/kubernetes: Fix error code when using the wrong service account [[GH-15585](https://github.com/hashicorp/vault/pull/15585)] -* auth/ldap: The logic for setting the entity alias when `username_as_alias` is set -has been fixed. The previous behavior would make a request to the LDAP server to -get `user_attr` before discarding it and using the username instead. This would -make it impossible for a user to connect if this attribute was missing or had -multiple values, even though it would not be used anyway. This has been fixed -and the username is now used without making superfluous LDAP searches. [[GH-15525](https://github.com/hashicorp/vault/pull/15525)] -* auth: Fixed erroneous success message when using vault login in case of two-phase MFA [[GH-15428](https://github.com/hashicorp/vault/pull/15428)] -* auth: Fixed erroneous token information being displayed when using vault login in case of two-phase MFA [[GH-15428](https://github.com/hashicorp/vault/pull/15428)] -* auth: Fixed two-phase MFA information missing from table format when using vault login [[GH-15428](https://github.com/hashicorp/vault/pull/15428)] -* auth: Prevent deleting a valid MFA method ID using the endpoint for a different MFA method type [[GH-15482](https://github.com/hashicorp/vault/pull/15482)] -* core (enterprise): Fix overcounting of lease count quota usage at startup. -* core: Prevent changing file permissions of audit logs when mode 0000 is used. [[GH-15759](https://github.com/hashicorp/vault/pull/15759)] -* core: Prevent metrics generation from causing deadlocks. [[GH-15693](https://github.com/hashicorp/vault/pull/15693)] -* core: fixed systemd reloading notification [[GH-15041](https://github.com/hashicorp/vault/pull/15041)] -* mfa/okta: disable client side rate limiting causing delays in push notifications [[GH-15369](https://github.com/hashicorp/vault/pull/15369)] -* storage/raft (enterprise): Auto-snapshot configuration now forbids slashes in file prefixes for all types, and "/" in path prefix for local storage type. Strip leading prefix in path prefix for AWS. Improve error handling/reporting. -* transform (enterprise): Fix non-overridable column default value causing tokenization tokens to expire prematurely when using the MySQL storage backend. -* ui: Fix inconsistent behavior in client count calendar widget [[GH-15789](https://github.com/hashicorp/vault/pull/15789)] -* ui: Fixed client count timezone for start and end months [[GH-15167](https://github.com/hashicorp/vault/pull/15167)] -* ui: fix firefox inability to recognize file format of client count csv export [[GH-15364](https://github.com/hashicorp/vault/pull/15364)] - ## 1.10.3 ### May 11, 2022 -SECURITY: -* auth: A vulnerability was identified in Vault and Vault Enterprise (“Vault”) from 1.10.0 to 1.10.2 where MFA may not be enforced on user logins after a server restart. This vulnerability, CVE-2022-30689, was fixed in Vault 1.10.3. - BUG FIXES: * auth: load login MFA configuration upon restart [[GH-15261](https://github.com/hashicorp/vault/pull/15261)] @@ -711,58 +394,6 @@ operation for upgraded configurations with a `root_password_ttl` of zero. [[GH-1 * ui: Removes ability to tune token_type for token auth methods [[GH-12904](https://github.com/hashicorp/vault/pull/12904)] * ui: trigger token renewal if inactive and half of TTL has passed [[GH-13950](https://github.com/hashicorp/vault/pull/13950)] -## 1.9.8 -### July 21, 2022 - -CHANGES: - -* core: Bump Go version to 1.17.12. - -IMPROVEMENTS: - -* secrets/ssh: Allow additional text along with a template definition in defaultExtension value fields. [[GH-16018](https://github.com/hashicorp/vault/pull/16018)] - -BUG FIXES: - -* core/identity: Replicate member_entity_ids and policies in identity/group across nodes identically [[GH-16088](https://github.com/hashicorp/vault/pull/16088)] -* core/replication (enterprise): Don't flush merkle tree pages to disk after losing active duty -* core/seal: Fix possible keyring truncation when using the file backend. [[GH-15946](https://github.com/hashicorp/vault/pull/15946)] -* storage/raft (enterprise): Prevent unauthenticated voter status change with rejoin [[GH-16324](https://github.com/hashicorp/vault/pull/16324)] -* transform (enterprise): Fix a bug in the handling of nested or unmatched capture groups in FPE transformations. -* ui: Fix issue where metadata tab is hidden even though policy grants access [[GH-15824](https://github.com/hashicorp/vault/pull/15824)] -* ui: Updated `leasId` to `leaseId` in the "Copy Credentials" section of "Generate AWS Credentials" [[GH-15685](https://github.com/hashicorp/vault/pull/15685)] - -## 1.9.7 -### June 10, 2022 - -CHANGES: - -* core: Bump Go version to 1.17.11. [[GH-go-ver-197](https://github.com/hashicorp/vault/pull/go-ver-197)] - -IMPROVEMENTS: - -* ui: Allow namespace param to be parsed from state queryParam [[GH-15378](https://github.com/hashicorp/vault/pull/15378)] - -BUG FIXES: - -* agent: Redact auto auth token from renew endpoints [[GH-15380](https://github.com/hashicorp/vault/pull/15380)] -* auth/ldap: The logic for setting the entity alias when `username_as_alias` is set -has been fixed. The previous behavior would make a request to the LDAP server to -get `user_attr` before discarding it and using the username instead. This would -make it impossible for a user to connect if this attribute was missing or had -multiple values, even though it would not be used anyway. This has been fixed -and the username is now used without making superfluous LDAP searches. [[GH-15525](https://github.com/hashicorp/vault/pull/15525)] -* core (enterprise): Fix overcounting of lease count quota usage at startup. -* core/config: Only ask the system about network interfaces when address configs contain a template having the format: {{ ... }} [[GH-15224](https://github.com/hashicorp/vault/pull/15224)] -* core: Prevent changing file permissions of audit logs when mode 0000 is used. [[GH-15759](https://github.com/hashicorp/vault/pull/15759)] -* core: Prevent metrics generation from causing deadlocks. [[GH-15693](https://github.com/hashicorp/vault/pull/15693)] -* core: fixed systemd reloading notification [[GH-15041](https://github.com/hashicorp/vault/pull/15041)] -* core: pre-calculate namespace specific paths when tainting a route during postUnseal [[GH-15067](https://github.com/hashicorp/vault/pull/15067)] -* storage/raft (enterprise): Auto-snapshot configuration now forbids slashes in file prefixes for all types, and "/" in path prefix for local storage type. Strip leading prefix in path prefix for AWS. Improve error handling/reporting. -* transform (enterprise): Fix non-overridable column default value causing tokenization tokens to expire prematurely when using the MySQL storage backend. -* ui: Fixes client count timezone bug [[GH-15743](https://github.com/hashicorp/vault/pull/15743)] -* ui: Fixes issue logging in with OIDC from a listed auth mounts tab [[GH-15666](https://github.com/hashicorp/vault/pull/15666)] - ## 1.9.6 ### April 29, 2022 @@ -823,10 +454,6 @@ autosnapshot save error. ## 1.9.4 ### March 3, 2022 -SECURITY: -* secrets/pki: Vault and Vault Enterprise (“Vault”) allowed the PKI secrets engine under certain configurations to issue wildcard certificates to authorized users for a specified domain, even if the PKI role policy attribute allow_subdomains is set to false. This vulnerability, CVE-2022-25243, was fixed in Vault 1.8.9 and 1.9.4. -* transform (enterprise): Vault Enterprise (“Vault”) clusters using the tokenization transform feature can expose the tokenization key through the tokenization key configuration endpoint to authorized operators with read permissions on this endpoint. This vulnerability, CVE-2022-25244, was fixed in Vault Enterprise 1.7.10, 1.8.9, and 1.9.4. - CHANGES: * secrets/azure: Changes the configuration parameter `use_microsoft_graph_api` to use the Microsoft @@ -1135,18 +762,6 @@ of dirty pages in the merkle tree at time of checkpoint creation. [[GH-2093](htt * ui: update bar chart when model changes [[GH-12622](https://github.com/hashicorp/vault/pull/12622)] * ui: updating database TTL picker help text. [[GH-12212](https://github.com/hashicorp/vault/pull/12212)] -## 1.8.12 -### June 10, 2022 - -BUG FIXES: - -* agent: Redact auto auth token from renew endpoints [[GH-15380](https://github.com/hashicorp/vault/pull/15380)] -* core: Prevent changing file permissions of audit logs when mode 0000 is used. [[GH-15759](https://github.com/hashicorp/vault/pull/15759)] -* core: fixed systemd reloading notification [[GH-15041](https://github.com/hashicorp/vault/pull/15041)] -* core: pre-calculate namespace specific paths when tainting a route during postUnseal [[GH-15067](https://github.com/hashicorp/vault/pull/15067)] -* storage/raft (enterprise): Auto-snapshot configuration now forbids slashes in file prefixes for all types, and "/" in path prefix for local storage type. Strip leading prefix in path prefix for AWS. Improve error handling/reporting. -* transform (enterprise): Fix non-overridable column default value causing tokenization tokens to expire prematurely when using the MySQL storage backend. - ## 1.8.11 ### April 29, 2022 @@ -1197,9 +812,6 @@ autosnapshot save error. ## 1.8.9 ### March 3, 2022 -* secrets/pki: Vault and Vault Enterprise (“Vault”) allowed the PKI secrets engine under certain configurations to issue wildcard certificates to authorized users for a specified domain, even if the PKI role policy attribute allow_subdomains is set to false. This vulnerability, CVE-2022-25243, was fixed in Vault 1.8.9 and 1.9.4. -* transform (enterprise): Vault Enterprise (“Vault”) clusters using the tokenization transform feature can expose the tokenization key through the tokenization key configuration endpoint to authorized operators with read permissions on this endpoint. This vulnerability, CVE-2022-25244, was fixed in Vault Enterprise 1.7.10, 1.8.9, and 1.9.4. - IMPROVEMENTS: * secrets/pki: Restrict issuance of wildcard certificates via role parameter (`allow_wildcard_certificates`) [[GH-14238](https://github.com/hashicorp/vault/pull/14238)] @@ -1535,10 +1147,6 @@ BUG FIXES: ## 1.7.10 ### March 3, 2022 -SECURITY: - -* transform (enterprise): Vault Enterprise (“Vault”) clusters using the tokenization transform feature can expose the tokenization key through the tokenization key configuration endpoint to authorized operators with read permissions on this endpoint. This vulnerability, CVE-2022-25244, was fixed in Vault Enterprise 1.7.10, 1.8.9, and 1.9.4. - BUG FIXES: * database/mssql: Removed string interpolation on internal queries and replaced them with inline queries using named parameters. [[GH-13799](https://github.com/hashicorp/vault/pull/13799)] diff --git a/CODEOWNERS b/CODEOWNERS index 4c3ddce3735bd..0f0191af3715a 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -38,7 +38,3 @@ # so stewards of the backend code are added below for notification. /ui/app/components/auth-jwt.js @austingebauer /ui/app/routes/vault/cluster/oidc-*.js @austingebauer - -# Release config; service account is required for automation tooling. -/.release/ @hashicorp/release-engineering @hashicorp/github-secure-vault-core -/.github/workflows/build.yml @hashicorp/release-engineering @hashicorp/github-secure-vault-core diff --git a/Makefile b/Makefile index bccecfe6ff8bf..8e1d067d8fea2 100644 --- a/Makefile +++ b/Makefile @@ -8,13 +8,14 @@ EXTENDED_TEST_TIMEOUT=60m INTEG_TEST_TIMEOUT=120m VETARGS?=-asmdecl -atomic -bool -buildtags -copylocks -methods -nilfunc -printf -rangeloops -shift -structtags -unsafeptr EXTERNAL_TOOLS_CI=\ + github.com/mitchellh/gox \ golang.org/x/tools/cmd/goimports EXTERNAL_TOOLS=\ github.com/client9/misspell/cmd/misspell GOFMT_FILES?=$$(find . -name '*.go' | grep -v pb.go | grep -v vendor) -GO_VERSION_MIN=1.18.4 +GO_VERSION_MIN=1.17.12 GO_CMD?=go CGO_ENABLED?=0 ifneq ($(FDB_ENABLED), ) @@ -150,11 +151,23 @@ test-ember-enos: install-ui-dependencies @echo "--> Running ember tests with a real backend" @cd ui && yarn run test:enos +ember-ci-test: # Deprecated, to be removed soon. + @echo "ember-ci-test is deprecated in favour of test-ui-browserstack" + @exit 1 + check-vault-in-path: @VAULT_BIN=$$(command -v vault) || { echo "vault command not found"; exit 1; }; \ [ -x "$$VAULT_BIN" ] || { echo "$$VAULT_BIN not executable"; exit 1; }; \ printf "Using Vault at %s:\n\$$ vault version\n%s\n" "$$VAULT_BIN" "$$(vault version)" +check-browserstack-creds: + @[ -n "$$BROWSERSTACK_ACCESS_KEY" ] || { echo "BROWSERSTACK_ACCESS_KEY not set"; exit 1; } + @[ -n "$$BROWSERSTACK_USERNAME" ] || { echo "BROWSERSTACK_USERNAME not set"; exit 1; } + +test-ui-browserstack: check-vault-in-path check-browserstack-creds install-ui-dependencies + @echo "--> Running ember tests in Browserstack" + @cd ui && yarn run test:browserstack + ember-dist: install-ui-dependencies @cd ui && npm rebuild node-sass @echo "--> Building Ember application" @@ -201,10 +214,10 @@ fmtcheck: fmt: find . -name '*.go' | grep -v pb.go | grep -v vendor | xargs gofumpt -w -semgrep: +semgrep: semgrep --include '*.go' --exclude 'vendor' -a -f tools/semgrep . -semgrep-ci: +semgrep-ci: semgrep --error --include '*.go' --exclude 'vendor' -f tools/semgrep/ci . assetcheck: @@ -246,7 +259,7 @@ ci-config: ci-verify: @$(MAKE) -C .circleci ci-verify -.PHONY: bin default prep test vet bootstrap ci-bootstrap fmt fmtcheck mysql-database-plugin mysql-legacy-database-plugin cassandra-database-plugin influxdb-database-plugin postgresql-database-plugin mssql-database-plugin hana-database-plugin mongodb-database-plugin ember-dist ember-dist-dev static-dist static-dist-dev assetcheck check-vault-in-path packages build build-ci semgrep semgrep-ci +.PHONY: bin default prep test vet bootstrap ci-bootstrap fmt fmtcheck mysql-database-plugin mysql-legacy-database-plugin cassandra-database-plugin influxdb-database-plugin postgresql-database-plugin mssql-database-plugin hana-database-plugin mongodb-database-plugin ember-dist ember-dist-dev static-dist static-dist-dev assetcheck check-vault-in-path check-browserstack-creds test-ui-browserstack packages build build-ci semgrep semgrep-ci .NOTPARALLEL: ember-dist ember-dist-dev diff --git a/README.md b/README.md index 6293a3633d441..2e7ff382acb35 100644 --- a/README.md +++ b/README.md @@ -40,11 +40,11 @@ The key features of Vault are: having to design their own encryption methods. * **Leasing and Renewal**: All secrets in Vault have a _lease_ associated - with them. At the end of the lease, Vault will automatically revoke that + with it. At the end of the lease, Vault will automatically revoke that secret. Clients are able to renew leases via built-in renew APIs. * **Revocation**: Vault has built-in support for secret revocation. Vault - can revoke not only single secrets, but a tree of secrets, for example, + can revoke not only single secrets, but a tree of secrets, for example all secrets read by a specific user, or all secrets of a particular type. Revocation assists in key rolling as well as locking down systems in the case of an intrusion. @@ -71,11 +71,11 @@ Developing Vault If you wish to work on Vault itself or any of its built-in systems, you'll first need [Go](https://www.golang.org) installed on your machine. Go version -1.18.4+ is *required*. +1.17.12+ is *required*. For local dev first make sure Go is properly installed, including setting up a [GOPATH](https://golang.org/doc/code.html#GOPATH). Ensure that `$GOPATH/bin` is in -your path as some distributions bundle the old version of build tools. Next, clone this +your path as some distributions bundle old version of build tools. Next, clone this repository. Vault uses [Go Modules](https://github.com/golang/go/wiki/Modules), so it is recommended that you clone the repository ***outside*** of the GOPATH. You can then download any required build tools by bootstrapping your environment: diff --git a/api/auth/approle/go.mod b/api/auth/approle/go.mod index 383e99b0affc9..4313984b23069 100644 --- a/api/auth/approle/go.mod +++ b/api/auth/approle/go.mod @@ -2,4 +2,4 @@ module github.com/hashicorp/vault/api/auth/approle go 1.16 -require github.com/hashicorp/vault/api v1.7.2 +require github.com/hashicorp/vault/api v1.5.0 diff --git a/api/auth/approle/go.sum b/api/auth/approle/go.sum index f8674acac3da5..89bdb5ce7a2af 100644 --- a/api/auth/approle/go.sum +++ b/api/auth/approle/go.sum @@ -113,13 +113,11 @@ github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR3 github.com/hashicorp/go-secure-stdlib/base62 v0.1.1/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw= github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 h1:cCRo8gK7oq6A2L6LICkUZ+/a5rLiRXFMf1Qd4xSwxTc= github.com/hashicorp/go-secure-stdlib/mlock v0.1.1/go.mod h1:zq93CJChV6L9QTfGKtfBxKqD7BqqXx5O04A/ns2p5+I= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1 h1:78ki3QBevHwYrVxnyVeaEz+7WtifHhauYF23es/0KlI= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= github.com/hashicorp/go-secure-stdlib/password v0.1.1/go.mod h1:9hH302QllNwu1o2TGYtSk8I8kTAN0ca1EHpwhm5Mmzo= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.1 h1:nd0HIW15E6FG1MsnArYaHfuw9C2zgzM8LxkG5Ty/788= github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1/go.mod h1:l8slYwnJA26yBz+ErHpp2IRCLr0vuOMGBORIz4rRiAs= github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= @@ -133,10 +131,10 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/vault/api v1.7.2 h1:kawHE7s/4xwrdKbkmwQi0wYaIeUhk5ueek7ljuezCVQ= -github.com/hashicorp/vault/api v1.7.2/go.mod h1:xbfA+1AvxFseDzxxdWaL0uO99n1+tndus4GCrtouy0M= -github.com/hashicorp/vault/sdk v0.5.1 h1:zly/TmNgOXCGgWIRA8GojyXzG817POtVh3uzIwzZx+8= -github.com/hashicorp/vault/sdk v0.5.1/go.mod h1:DoGraE9kKGNcVgPmTuX357Fm6WAx1Okvde8Vp3dPDoU= +github.com/hashicorp/vault/api v1.5.0 h1:Bp6yc2bn7CWkOrVIzFT/Qurzx528bdavF3nz590eu28= +github.com/hashicorp/vault/api v1.5.0/go.mod h1:LkMdrZnWNrFaQyYYazWVn7KshilfDidgVBq6YiTq/bM= +github.com/hashicorp/vault/sdk v0.4.1 h1:3SaHOJY687jY1fnB61PtL0cOkKItphrbLmux7T92HBo= +github.com/hashicorp/vault/sdk v0.4.1/go.mod h1:aZ3fNuL5VNydQk8GcLJ2TV8YCRVvyaakYkhZRoVuhj0= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -175,8 +173,8 @@ github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdI github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo= +github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= diff --git a/api/auth/aws/go.mod b/api/auth/aws/go.mod index 9db45480986cf..75e5343a3ba31 100644 --- a/api/auth/aws/go.mod +++ b/api/auth/aws/go.mod @@ -7,5 +7,5 @@ require ( github.com/hashicorp/go-hclog v0.16.2 github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 github.com/hashicorp/go-uuid v1.0.2 - github.com/hashicorp/vault/api v1.7.2 + github.com/hashicorp/vault/api v1.5.0 ) diff --git a/api/auth/aws/go.sum b/api/auth/aws/go.sum index cd99bab3400bd..0c57287ff115d 100644 --- a/api/auth/aws/go.sum +++ b/api/auth/aws/go.sum @@ -118,13 +118,11 @@ github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6/go.mod h1:MpCPSPGLDILGb4JMm github.com/hashicorp/go-secure-stdlib/base62 v0.1.1/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw= github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 h1:cCRo8gK7oq6A2L6LICkUZ+/a5rLiRXFMf1Qd4xSwxTc= github.com/hashicorp/go-secure-stdlib/mlock v0.1.1/go.mod h1:zq93CJChV6L9QTfGKtfBxKqD7BqqXx5O04A/ns2p5+I= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1 h1:78ki3QBevHwYrVxnyVeaEz+7WtifHhauYF23es/0KlI= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= github.com/hashicorp/go-secure-stdlib/password v0.1.1/go.mod h1:9hH302QllNwu1o2TGYtSk8I8kTAN0ca1EHpwhm5Mmzo= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.1 h1:nd0HIW15E6FG1MsnArYaHfuw9C2zgzM8LxkG5Ty/788= github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1/go.mod h1:l8slYwnJA26yBz+ErHpp2IRCLr0vuOMGBORIz4rRiAs= github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= @@ -138,10 +136,10 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/vault/api v1.7.2 h1:kawHE7s/4xwrdKbkmwQi0wYaIeUhk5ueek7ljuezCVQ= -github.com/hashicorp/vault/api v1.7.2/go.mod h1:xbfA+1AvxFseDzxxdWaL0uO99n1+tndus4GCrtouy0M= -github.com/hashicorp/vault/sdk v0.5.1 h1:zly/TmNgOXCGgWIRA8GojyXzG817POtVh3uzIwzZx+8= -github.com/hashicorp/vault/sdk v0.5.1/go.mod h1:DoGraE9kKGNcVgPmTuX357Fm6WAx1Okvde8Vp3dPDoU= +github.com/hashicorp/vault/api v1.5.0 h1:Bp6yc2bn7CWkOrVIzFT/Qurzx528bdavF3nz590eu28= +github.com/hashicorp/vault/api v1.5.0/go.mod h1:LkMdrZnWNrFaQyYYazWVn7KshilfDidgVBq6YiTq/bM= +github.com/hashicorp/vault/sdk v0.4.1 h1:3SaHOJY687jY1fnB61PtL0cOkKItphrbLmux7T92HBo= +github.com/hashicorp/vault/sdk v0.4.1/go.mod h1:aZ3fNuL5VNydQk8GcLJ2TV8YCRVvyaakYkhZRoVuhj0= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -183,8 +181,8 @@ github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdI github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo= +github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= diff --git a/api/auth/azure/go.mod b/api/auth/azure/go.mod index ac5a97d51b7cb..89283886b2b83 100644 --- a/api/auth/azure/go.mod +++ b/api/auth/azure/go.mod @@ -2,4 +2,4 @@ module github.com/hashicorp/vault/api/auth/azure go 1.16 -require github.com/hashicorp/vault/api v1.7.2 +require github.com/hashicorp/vault/api v1.5.0 diff --git a/api/auth/azure/go.sum b/api/auth/azure/go.sum index f8674acac3da5..89bdb5ce7a2af 100644 --- a/api/auth/azure/go.sum +++ b/api/auth/azure/go.sum @@ -113,13 +113,11 @@ github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR3 github.com/hashicorp/go-secure-stdlib/base62 v0.1.1/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw= github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 h1:cCRo8gK7oq6A2L6LICkUZ+/a5rLiRXFMf1Qd4xSwxTc= github.com/hashicorp/go-secure-stdlib/mlock v0.1.1/go.mod h1:zq93CJChV6L9QTfGKtfBxKqD7BqqXx5O04A/ns2p5+I= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1 h1:78ki3QBevHwYrVxnyVeaEz+7WtifHhauYF23es/0KlI= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= github.com/hashicorp/go-secure-stdlib/password v0.1.1/go.mod h1:9hH302QllNwu1o2TGYtSk8I8kTAN0ca1EHpwhm5Mmzo= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.1 h1:nd0HIW15E6FG1MsnArYaHfuw9C2zgzM8LxkG5Ty/788= github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1/go.mod h1:l8slYwnJA26yBz+ErHpp2IRCLr0vuOMGBORIz4rRiAs= github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= @@ -133,10 +131,10 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/vault/api v1.7.2 h1:kawHE7s/4xwrdKbkmwQi0wYaIeUhk5ueek7ljuezCVQ= -github.com/hashicorp/vault/api v1.7.2/go.mod h1:xbfA+1AvxFseDzxxdWaL0uO99n1+tndus4GCrtouy0M= -github.com/hashicorp/vault/sdk v0.5.1 h1:zly/TmNgOXCGgWIRA8GojyXzG817POtVh3uzIwzZx+8= -github.com/hashicorp/vault/sdk v0.5.1/go.mod h1:DoGraE9kKGNcVgPmTuX357Fm6WAx1Okvde8Vp3dPDoU= +github.com/hashicorp/vault/api v1.5.0 h1:Bp6yc2bn7CWkOrVIzFT/Qurzx528bdavF3nz590eu28= +github.com/hashicorp/vault/api v1.5.0/go.mod h1:LkMdrZnWNrFaQyYYazWVn7KshilfDidgVBq6YiTq/bM= +github.com/hashicorp/vault/sdk v0.4.1 h1:3SaHOJY687jY1fnB61PtL0cOkKItphrbLmux7T92HBo= +github.com/hashicorp/vault/sdk v0.4.1/go.mod h1:aZ3fNuL5VNydQk8GcLJ2TV8YCRVvyaakYkhZRoVuhj0= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -175,8 +173,8 @@ github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdI github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo= +github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= diff --git a/api/auth/gcp/go.mod b/api/auth/gcp/go.mod index 6620c128e0c75..a7d8637ff0180 100644 --- a/api/auth/gcp/go.mod +++ b/api/auth/gcp/go.mod @@ -4,6 +4,6 @@ go 1.16 require ( cloud.google.com/go v0.97.0 - github.com/hashicorp/vault/api v1.7.2 + github.com/hashicorp/vault/api v1.5.0 google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0 ) diff --git a/api/auth/gcp/go.sum b/api/auth/gcp/go.sum index 0d38b37674fe0..60c2540e96636 100644 --- a/api/auth/gcp/go.sum +++ b/api/auth/gcp/go.sum @@ -217,13 +217,11 @@ github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR3 github.com/hashicorp/go-secure-stdlib/base62 v0.1.1/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw= github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 h1:cCRo8gK7oq6A2L6LICkUZ+/a5rLiRXFMf1Qd4xSwxTc= github.com/hashicorp/go-secure-stdlib/mlock v0.1.1/go.mod h1:zq93CJChV6L9QTfGKtfBxKqD7BqqXx5O04A/ns2p5+I= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1 h1:78ki3QBevHwYrVxnyVeaEz+7WtifHhauYF23es/0KlI= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= github.com/hashicorp/go-secure-stdlib/password v0.1.1/go.mod h1:9hH302QllNwu1o2TGYtSk8I8kTAN0ca1EHpwhm5Mmzo= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.1 h1:nd0HIW15E6FG1MsnArYaHfuw9C2zgzM8LxkG5Ty/788= github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1/go.mod h1:l8slYwnJA26yBz+ErHpp2IRCLr0vuOMGBORIz4rRiAs= github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= @@ -238,10 +236,10 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/vault/api v1.7.2 h1:kawHE7s/4xwrdKbkmwQi0wYaIeUhk5ueek7ljuezCVQ= -github.com/hashicorp/vault/api v1.7.2/go.mod h1:xbfA+1AvxFseDzxxdWaL0uO99n1+tndus4GCrtouy0M= -github.com/hashicorp/vault/sdk v0.5.1 h1:zly/TmNgOXCGgWIRA8GojyXzG817POtVh3uzIwzZx+8= -github.com/hashicorp/vault/sdk v0.5.1/go.mod h1:DoGraE9kKGNcVgPmTuX357Fm6WAx1Okvde8Vp3dPDoU= +github.com/hashicorp/vault/api v1.5.0 h1:Bp6yc2bn7CWkOrVIzFT/Qurzx528bdavF3nz590eu28= +github.com/hashicorp/vault/api v1.5.0/go.mod h1:LkMdrZnWNrFaQyYYazWVn7KshilfDidgVBq6YiTq/bM= +github.com/hashicorp/vault/sdk v0.4.1 h1:3SaHOJY687jY1fnB61PtL0cOkKItphrbLmux7T92HBo= +github.com/hashicorp/vault/sdk v0.4.1/go.mod h1:aZ3fNuL5VNydQk8GcLJ2TV8YCRVvyaakYkhZRoVuhj0= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -285,8 +283,8 @@ github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdI github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo= +github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= diff --git a/api/auth/kubernetes/go.mod b/api/auth/kubernetes/go.mod index 2329c301bbd4f..e529831e6fba1 100644 --- a/api/auth/kubernetes/go.mod +++ b/api/auth/kubernetes/go.mod @@ -2,4 +2,4 @@ module github.com/hashicorp/vault/api/auth/kubernetes go 1.16 -require github.com/hashicorp/vault/api v1.7.2 +require github.com/hashicorp/vault/api v1.5.0 diff --git a/api/auth/kubernetes/go.sum b/api/auth/kubernetes/go.sum index f8674acac3da5..89bdb5ce7a2af 100644 --- a/api/auth/kubernetes/go.sum +++ b/api/auth/kubernetes/go.sum @@ -113,13 +113,11 @@ github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR3 github.com/hashicorp/go-secure-stdlib/base62 v0.1.1/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw= github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 h1:cCRo8gK7oq6A2L6LICkUZ+/a5rLiRXFMf1Qd4xSwxTc= github.com/hashicorp/go-secure-stdlib/mlock v0.1.1/go.mod h1:zq93CJChV6L9QTfGKtfBxKqD7BqqXx5O04A/ns2p5+I= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1 h1:78ki3QBevHwYrVxnyVeaEz+7WtifHhauYF23es/0KlI= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= github.com/hashicorp/go-secure-stdlib/password v0.1.1/go.mod h1:9hH302QllNwu1o2TGYtSk8I8kTAN0ca1EHpwhm5Mmzo= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.1 h1:nd0HIW15E6FG1MsnArYaHfuw9C2zgzM8LxkG5Ty/788= github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1/go.mod h1:l8slYwnJA26yBz+ErHpp2IRCLr0vuOMGBORIz4rRiAs= github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= @@ -133,10 +131,10 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/vault/api v1.7.2 h1:kawHE7s/4xwrdKbkmwQi0wYaIeUhk5ueek7ljuezCVQ= -github.com/hashicorp/vault/api v1.7.2/go.mod h1:xbfA+1AvxFseDzxxdWaL0uO99n1+tndus4GCrtouy0M= -github.com/hashicorp/vault/sdk v0.5.1 h1:zly/TmNgOXCGgWIRA8GojyXzG817POtVh3uzIwzZx+8= -github.com/hashicorp/vault/sdk v0.5.1/go.mod h1:DoGraE9kKGNcVgPmTuX357Fm6WAx1Okvde8Vp3dPDoU= +github.com/hashicorp/vault/api v1.5.0 h1:Bp6yc2bn7CWkOrVIzFT/Qurzx528bdavF3nz590eu28= +github.com/hashicorp/vault/api v1.5.0/go.mod h1:LkMdrZnWNrFaQyYYazWVn7KshilfDidgVBq6YiTq/bM= +github.com/hashicorp/vault/sdk v0.4.1 h1:3SaHOJY687jY1fnB61PtL0cOkKItphrbLmux7T92HBo= +github.com/hashicorp/vault/sdk v0.4.1/go.mod h1:aZ3fNuL5VNydQk8GcLJ2TV8YCRVvyaakYkhZRoVuhj0= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -175,8 +173,8 @@ github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdI github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo= +github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= diff --git a/api/auth/ldap/go.mod b/api/auth/ldap/go.mod index f316a64216705..3b04391541d7b 100644 --- a/api/auth/ldap/go.mod +++ b/api/auth/ldap/go.mod @@ -2,4 +2,4 @@ module github.com/hashicorp/vault/api/auth/ldap go 1.16 -require github.com/hashicorp/vault/api v1.7.2 +require github.com/hashicorp/vault/api v1.5.0 diff --git a/api/auth/ldap/go.sum b/api/auth/ldap/go.sum index f8674acac3da5..89bdb5ce7a2af 100644 --- a/api/auth/ldap/go.sum +++ b/api/auth/ldap/go.sum @@ -113,13 +113,11 @@ github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR3 github.com/hashicorp/go-secure-stdlib/base62 v0.1.1/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw= github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 h1:cCRo8gK7oq6A2L6LICkUZ+/a5rLiRXFMf1Qd4xSwxTc= github.com/hashicorp/go-secure-stdlib/mlock v0.1.1/go.mod h1:zq93CJChV6L9QTfGKtfBxKqD7BqqXx5O04A/ns2p5+I= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1 h1:78ki3QBevHwYrVxnyVeaEz+7WtifHhauYF23es/0KlI= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= github.com/hashicorp/go-secure-stdlib/password v0.1.1/go.mod h1:9hH302QllNwu1o2TGYtSk8I8kTAN0ca1EHpwhm5Mmzo= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.1 h1:nd0HIW15E6FG1MsnArYaHfuw9C2zgzM8LxkG5Ty/788= github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1/go.mod h1:l8slYwnJA26yBz+ErHpp2IRCLr0vuOMGBORIz4rRiAs= github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= @@ -133,10 +131,10 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/vault/api v1.7.2 h1:kawHE7s/4xwrdKbkmwQi0wYaIeUhk5ueek7ljuezCVQ= -github.com/hashicorp/vault/api v1.7.2/go.mod h1:xbfA+1AvxFseDzxxdWaL0uO99n1+tndus4GCrtouy0M= -github.com/hashicorp/vault/sdk v0.5.1 h1:zly/TmNgOXCGgWIRA8GojyXzG817POtVh3uzIwzZx+8= -github.com/hashicorp/vault/sdk v0.5.1/go.mod h1:DoGraE9kKGNcVgPmTuX357Fm6WAx1Okvde8Vp3dPDoU= +github.com/hashicorp/vault/api v1.5.0 h1:Bp6yc2bn7CWkOrVIzFT/Qurzx528bdavF3nz590eu28= +github.com/hashicorp/vault/api v1.5.0/go.mod h1:LkMdrZnWNrFaQyYYazWVn7KshilfDidgVBq6YiTq/bM= +github.com/hashicorp/vault/sdk v0.4.1 h1:3SaHOJY687jY1fnB61PtL0cOkKItphrbLmux7T92HBo= +github.com/hashicorp/vault/sdk v0.4.1/go.mod h1:aZ3fNuL5VNydQk8GcLJ2TV8YCRVvyaakYkhZRoVuhj0= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -175,8 +173,8 @@ github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdI github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo= +github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= diff --git a/api/auth/userpass/go.mod b/api/auth/userpass/go.mod index 4d3cac68e1d78..dcbbdffa58149 100644 --- a/api/auth/userpass/go.mod +++ b/api/auth/userpass/go.mod @@ -2,4 +2,4 @@ module github.com/hashicorp/vault/api/auth/userpass go 1.16 -require github.com/hashicorp/vault/api v1.7.2 +require github.com/hashicorp/vault/api v1.5.0 diff --git a/api/auth/userpass/go.sum b/api/auth/userpass/go.sum index f8674acac3da5..89bdb5ce7a2af 100644 --- a/api/auth/userpass/go.sum +++ b/api/auth/userpass/go.sum @@ -113,13 +113,11 @@ github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR3 github.com/hashicorp/go-secure-stdlib/base62 v0.1.1/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw= github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 h1:cCRo8gK7oq6A2L6LICkUZ+/a5rLiRXFMf1Qd4xSwxTc= github.com/hashicorp/go-secure-stdlib/mlock v0.1.1/go.mod h1:zq93CJChV6L9QTfGKtfBxKqD7BqqXx5O04A/ns2p5+I= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1 h1:78ki3QBevHwYrVxnyVeaEz+7WtifHhauYF23es/0KlI= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= github.com/hashicorp/go-secure-stdlib/password v0.1.1/go.mod h1:9hH302QllNwu1o2TGYtSk8I8kTAN0ca1EHpwhm5Mmzo= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.1 h1:nd0HIW15E6FG1MsnArYaHfuw9C2zgzM8LxkG5Ty/788= github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= -github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1/go.mod h1:l8slYwnJA26yBz+ErHpp2IRCLr0vuOMGBORIz4rRiAs= github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= @@ -133,10 +131,10 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/vault/api v1.7.2 h1:kawHE7s/4xwrdKbkmwQi0wYaIeUhk5ueek7ljuezCVQ= -github.com/hashicorp/vault/api v1.7.2/go.mod h1:xbfA+1AvxFseDzxxdWaL0uO99n1+tndus4GCrtouy0M= -github.com/hashicorp/vault/sdk v0.5.1 h1:zly/TmNgOXCGgWIRA8GojyXzG817POtVh3uzIwzZx+8= -github.com/hashicorp/vault/sdk v0.5.1/go.mod h1:DoGraE9kKGNcVgPmTuX357Fm6WAx1Okvde8Vp3dPDoU= +github.com/hashicorp/vault/api v1.5.0 h1:Bp6yc2bn7CWkOrVIzFT/Qurzx528bdavF3nz590eu28= +github.com/hashicorp/vault/api v1.5.0/go.mod h1:LkMdrZnWNrFaQyYYazWVn7KshilfDidgVBq6YiTq/bM= +github.com/hashicorp/vault/sdk v0.4.1 h1:3SaHOJY687jY1fnB61PtL0cOkKItphrbLmux7T92HBo= +github.com/hashicorp/vault/sdk v0.4.1/go.mod h1:aZ3fNuL5VNydQk8GcLJ2TV8YCRVvyaakYkhZRoVuhj0= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -175,8 +173,8 @@ github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdI github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= -github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo= +github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= diff --git a/api/client.go b/api/client.go index 7c17981059fb7..c07f3b124a3c7 100644 --- a/api/client.go +++ b/api/client.go @@ -347,6 +347,8 @@ func (c *Config) ReadEnvironment() error { } if v := os.Getenv(EnvVaultAgentAddr); v != "" { envAgentAddress = v + } else if v := os.Getenv(EnvVaultAgentAddress); v != "" { + envAgentAddress = v } if v := os.Getenv(EnvVaultMaxRetries); v != "" { maxRetries, err := strconv.ParseUint(v, 10, 32) @@ -390,6 +392,12 @@ func (c *Config) ReadEnvironment() error { if err != nil { return fmt.Errorf("could not parse VAULT_SKIP_VERIFY") } + } else if v := os.Getenv(EnvVaultInsecure); v != "" { + var err error + envInsecure, err = strconv.ParseBool(v) + if err != nil { + return fmt.Errorf("could not parse VAULT_INSECURE") + } } if v := os.Getenv(EnvVaultSRVLookup); v != "" { var err error @@ -462,51 +470,6 @@ func (c *Config) ReadEnvironment() error { return nil } -// ParseAddress transforms the provided address into a url.URL and handles -// the case of Unix domain sockets by setting the DialContext in the -// configuration's HttpClient.Transport. This function must be called with -// c.modifyLock held for write access. -func (c *Config) ParseAddress(address string) (*url.URL, error) { - u, err := url.Parse(address) - if err != nil { - return nil, err - } - - c.Address = address - - if strings.HasPrefix(address, "unix://") { - // When the address begins with unix://, always change the transport's - // DialContext (to match previous behaviour) - socket := strings.TrimPrefix(address, "unix://") - - if transport, ok := c.HttpClient.Transport.(*http.Transport); ok { - transport.DialContext = func(context.Context, string, string) (net.Conn, error) { - return net.Dial("unix", socket) - } - - // Since the address points to a unix domain socket, the scheme in the - // *URL would be set to `unix`. The *URL in the client is expected to - // be pointing to the protocol used in the application layer and not to - // the transport layer. Hence, setting the fields accordingly. - u.Scheme = "http" - u.Host = socket - u.Path = "" - } else { - return nil, fmt.Errorf("attempting to specify unix:// address with non-transport transport") - } - } else if strings.HasPrefix(c.Address, "unix://") { - // When the address being set does not begin with unix:// but the previous - // address in the Config did, change the transport's DialContext back to - // use the default configuration that cleanhttp uses. - - if transport, ok := c.HttpClient.Transport.(*http.Transport); ok { - transport.DialContext = cleanhttp.DefaultPooledTransport().DialContext - } - } - - return u, nil -} - func parseRateLimit(val string) (rate float64, burst int, err error) { _, err = fmt.Sscanf(val, "%f:%d", &rate, &burst) if err != nil { @@ -579,11 +542,27 @@ func NewClient(c *Config) (*Client, error) { address = c.AgentAddress } - u, err := c.ParseAddress(address) + u, err := url.Parse(address) if err != nil { return nil, err } + if strings.HasPrefix(address, "unix://") { + socket := strings.TrimPrefix(address, "unix://") + transport := c.HttpClient.Transport.(*http.Transport) + transport.DialContext = func(context.Context, string, string) (net.Conn, error) { + return net.Dial("unix", socket) + } + + // Since the address points to a unix domain socket, the scheme in the + // *URL would be set to `unix`. The *URL in the client is expected to + // be pointing to the protocol used in the application layer and not to + // the transport layer. Hence, setting the fields accordingly. + u.Scheme = "http" + u.Host = socket + u.Path = "" + } + client := &Client{ addr: u, config: c, @@ -642,11 +621,14 @@ func (c *Client) SetAddress(addr string) error { c.modifyLock.Lock() defer c.modifyLock.Unlock() - parsedAddr, err := c.config.ParseAddress(addr) + parsedAddr, err := url.Parse(addr) if err != nil { return errwrap.Wrapf("failed to set address: {{err}}", err) } + c.config.modifyLock.Lock() + c.config.Address = addr + c.config.modifyLock.Unlock() c.addr = parsedAddr return nil } diff --git a/api/client_test.go b/api/client_test.go index 2305d42fe7870..74f1b9354e361 100644 --- a/api/client_test.go +++ b/api/client_test.go @@ -69,63 +69,17 @@ func TestClientNilConfig(t *testing.T) { } } -func TestClientDefaultHttpClient_unixSocket(t *testing.T) { - os.Setenv("VAULT_AGENT_ADDR", "unix:///var/run/vault.sock") - defer os.Setenv("VAULT_AGENT_ADDR", "") - - client, err := NewClient(nil) - if err != nil { - t.Fatal(err) - } - if client == nil { - t.Fatal("expected a non-nil client") - } - if client.addr.Scheme != "http" { - t.Fatalf("bad: %s", client.addr.Scheme) - } - if client.addr.Host != "/var/run/vault.sock" { - t.Fatalf("bad: %s", client.addr.Host) - } -} - func TestClientSetAddress(t *testing.T) { client, err := NewClient(nil) if err != nil { t.Fatal(err) } - // Start with TCP address using HTTP - if err := client.SetAddress("http://172.168.2.1:8300"); err != nil { - t.Fatal(err) - } - if client.addr.Host != "172.168.2.1:8300" { - t.Fatalf("bad: expected: '172.168.2.1:8300' actual: %q", client.addr.Host) - } - // Test switching to Unix Socket address from TCP address - if err := client.SetAddress("unix:///var/run/vault.sock"); err != nil { - t.Fatal(err) - } - if client.addr.Scheme != "http" { - t.Fatalf("bad: expected: 'http' actual: %q", client.addr.Scheme) - } - if client.addr.Host != "/var/run/vault.sock" { - t.Fatalf("bad: expected: '/var/run/vault.sock' actual: %q", client.addr.Host) - } - if client.addr.Path != "" { - t.Fatalf("bad: expected '' actual: %q", client.addr.Path) - } - if client.config.HttpClient.Transport.(*http.Transport).DialContext == nil { - t.Fatal("bad: expected DialContext to not be nil") - } - // Test switching to TCP address from Unix Socket address if err := client.SetAddress("http://172.168.2.1:8300"); err != nil { t.Fatal(err) } if client.addr.Host != "172.168.2.1:8300" { t.Fatalf("bad: expected: '172.168.2.1:8300' actual: %q", client.addr.Host) } - if client.addr.Scheme != "http" { - t.Fatalf("bad: expected: 'http' actual: %q", client.addr.Scheme) - } } func TestClientToken(t *testing.T) { @@ -299,7 +253,7 @@ func TestDefaulRetryPolicy(t *testing.T) { t.Fatalf("expected to retry request: '%t', but actual result was: '%t'", test.expect, retry) } if err != test.expectErr { - t.Fatalf("expected error from retry policy: %q, but actual result was: %q", err, test.expectErr) + t.Fatalf("expected error from retry policy: '%s', but actual result was: '%s'", err, test.expectErr) } }) } @@ -472,20 +426,6 @@ func TestClientNonTransportRoundTripper(t *testing.T) { } } -func TestClientNonTransportRoundTripperUnixAddress(t *testing.T) { - client := &http.Client{ - Transport: roundTripperFunc(http.DefaultTransport.RoundTrip), - } - - _, err := NewClient(&Config{ - HttpClient: client, - Address: "unix:///var/run/vault.sock", - }) - if err == nil { - t.Fatal("bad: expected error got nil") - } -} - func TestClone(t *testing.T) { type fields struct{} tests := []struct { @@ -1219,7 +1159,7 @@ func TestClientWithNamespace(t *testing.T) { t.Fatalf("err: %s", err) } if ns != ogNS { - t.Fatalf("Expected namespace: %q, got %q", ogNS, ns) + t.Fatalf("Expected namespace: \"%s\", got \"%s\"", ogNS, ns) } // make a call with a temporary namespace @@ -1231,7 +1171,7 @@ func TestClientWithNamespace(t *testing.T) { t.Fatalf("err: %s", err) } if ns != newNS { - t.Fatalf("Expected new namespace: %q, got %q", newNS, ns) + t.Fatalf("Expected new namespace: \"%s\", got \"%s\"", newNS, ns) } // ensure client has not been modified _, err = client.rawRequestWithContext( @@ -1241,7 +1181,7 @@ func TestClientWithNamespace(t *testing.T) { t.Fatalf("err: %s", err) } if ns != ogNS { - t.Fatalf("Expected original namespace: %q, got %q", ogNS, ns) + t.Fatalf("Expected original namespace: \"%s\", got \"%s\"", ogNS, ns) } // make call with empty ns @@ -1252,12 +1192,12 @@ func TestClientWithNamespace(t *testing.T) { t.Fatalf("err: %s", err) } if ns != "" { - t.Fatalf("Expected no namespace, got %q", ns) + t.Fatalf("Expected no namespace, got \"%s\"", ns) } // ensure client has not been modified if client.Namespace() != ogNS { - t.Fatalf("Expected original namespace: %q, got %q", ogNS, client.Namespace()) + t.Fatalf("Expected original namespace: \"%s\", got \"%s\"", ogNS, client.Namespace()) } } @@ -1344,25 +1284,3 @@ func TestVaultProxy(t *testing.T) { }) } } - -func TestParseAddressWithUnixSocket(t *testing.T) { - address := "unix:///var/run/vault.sock" - config := DefaultConfig() - - u, err := config.ParseAddress(address) - if err != nil { - t.Fatal("Error not expected") - } - if u.Scheme != "http" { - t.Fatal("Scheme not changed to http") - } - if u.Host != "/var/run/vault.sock" { - t.Fatal("Host not changed to socket name") - } - if u.Path != "" { - t.Fatal("Path expected to be blank") - } - if config.HttpClient.Transport.(*http.Transport).DialContext == nil { - t.Fatal("DialContext function not set in config.HttpClient.Transport") - } -} diff --git a/api/kv.go b/api/kv.go index 16437582e703c..a334c8e218e57 100644 --- a/api/kv.go +++ b/api/kv.go @@ -30,8 +30,8 @@ type KVSecret struct { // // Learn more about the KV secrets engine here: // https://www.vaultproject.io/docs/secrets/kv -func (c *Client) KVv1(mountPath string) *KVv1 { - return &KVv1{c: c, mountPath: mountPath} +func (c *Client) KVv1(mountPath string) *kvv1 { + return &kvv1{c: c, mountPath: mountPath} } // KVv2 is used to return a client for reads and writes against @@ -45,6 +45,6 @@ func (c *Client) KVv1(mountPath string) *KVv1 { // // Learn more about the KV secrets engine here: // https://www.vaultproject.io/docs/secrets/kv -func (c *Client) KVv2(mountPath string) *KVv2 { - return &KVv2{c: c, mountPath: mountPath} +func (c *Client) KVv2(mountPath string) *kvv2 { + return &kvv2{c: c, mountPath: mountPath} } diff --git a/api/kv_v1.go b/api/kv_v1.go index d269070bc38b0..1b0428dee977c 100644 --- a/api/kv_v1.go +++ b/api/kv_v1.go @@ -5,13 +5,13 @@ import ( "fmt" ) -type KVv1 struct { +type kvv1 struct { c *Client mountPath string } // Get returns a secret from the KV v1 secrets engine. -func (kv *KVv1) Get(ctx context.Context, secretPath string) (*KVSecret, error) { +func (kv *kvv1) Get(ctx context.Context, secretPath string) (*KVSecret, error) { pathToRead := fmt.Sprintf("%s/%s", kv.mountPath, secretPath) secret, err := kv.c.Logical().ReadWithContext(ctx, pathToRead) @@ -33,7 +33,7 @@ func (kv *KVv1) Get(ctx context.Context, secretPath string) (*KVSecret, error) { // KV v1 secrets engine. // // If the secret already exists, it will be overwritten. -func (kv *KVv1) Put(ctx context.Context, secretPath string, data map[string]interface{}) error { +func (kv *kvv1) Put(ctx context.Context, secretPath string, data map[string]interface{}) error { pathToWriteTo := fmt.Sprintf("%s/%s", kv.mountPath, secretPath) _, err := kv.c.Logical().WriteWithContext(ctx, pathToWriteTo, data) @@ -45,7 +45,7 @@ func (kv *KVv1) Put(ctx context.Context, secretPath string, data map[string]inte } // Delete deletes a secret from the KV v1 secrets engine. -func (kv *KVv1) Delete(ctx context.Context, secretPath string) error { +func (kv *kvv1) Delete(ctx context.Context, secretPath string) error { pathToDelete := fmt.Sprintf("%s/%s", kv.mountPath, secretPath) _, err := kv.c.Logical().DeleteWithContext(ctx, pathToDelete) diff --git a/api/kv_v2.go b/api/kv_v2.go index f0f59abfe57ac..2b6149b16a45c 100644 --- a/api/kv_v2.go +++ b/api/kv_v2.go @@ -10,7 +10,7 @@ import ( "github.com/mitchellh/mapstructure" ) -type KVv2 struct { +type kvv2 struct { c *Client mountPath string } @@ -30,35 +30,6 @@ type KVMetadata struct { Raw *Secret } -// KVMetadataPutInput is the subset of metadata that can be replaced for a -// KV v2 secret using the PutMetadata method. -// -// All fields should be explicitly provided, as any fields left unset in the -// struct will be reset to their zero value. -type KVMetadataPutInput struct { - CASRequired bool - CustomMetadata map[string]interface{} - DeleteVersionAfter time.Duration - MaxVersions int -} - -// KVMetadataPatchInput is the subset of metadata that can be manually modified for -// a KV v2 secret using the PatchMetadata method. -// -// The struct's fields are all pointers. A pointer to a field's zero -// value (e.g. false for *bool) implies that field should be reset to its -// zero value after update, whereas a field left as a nil pointer -// (e.g. nil for *bool) implies the field should remain unchanged. -// -// Since maps are already pointers, use an empty map to remove all -// custom metadata. -type KVMetadataPatchInput struct { - CASRequired *bool - CustomMetadata map[string]interface{} - DeleteVersionAfter *time.Duration - MaxVersions *int -} - // KVVersionMetadata is a subset of metadata for a given version of a KV v2 secret. type KVVersionMetadata struct { Version int `mapstructure:"version"` @@ -67,39 +38,18 @@ type KVVersionMetadata struct { Destroyed bool `mapstructure:"destroyed"` } -// Currently supported options: WithOption, WithCheckAndSet, WithMethod +// Currently supported options: WithCheckAndSet type KVOption func() (key string, value interface{}) -const ( - KVOptionCheckAndSet = "cas" - KVOptionMethod = "method" - KVMergeMethodPatch = "patch" - KVMergeMethodReadWrite = "rw" -) - -// WithOption can optionally be passed to provide generic options for a -// KV request. Valid keys and values depend on the type of request. -func WithOption(key string, value interface{}) KVOption { - return func() (string, interface{}) { - return key, value - } -} - // WithCheckAndSet can optionally be passed to perform a check-and-set -// operation on a KV request. If not set, the write will be allowed. -// If cas is set to 0, a write will only be allowed if the key doesn't exist. -// If set to non-zero, the write will only be allowed if the key’s current -// version matches the version specified in the cas parameter. +// operation. If not set, the write will be allowed. If cas is set to 0, a +// write will only be allowed if the key doesn't exist. If set to non-zero, +// the write will only be allowed if the key’s current version matches the +// version specified in the cas parameter. func WithCheckAndSet(cas int) KVOption { - return WithOption(KVOptionCheckAndSet, cas) -} - -// WithMergeMethod can optionally be passed to dictate which type of -// patch to perform in a Patch request. If set to "patch", then an HTTP PATCH -// request will be issued. If set to "rw", then a read will be performed, -// then a local update, followed by a remote update. Defaults to "patch". -func WithMergeMethod(method string) KVOption { - return WithOption(KVOptionMethod, method) + return func() (string, interface{}) { + return "cas", cas + } } // Get returns the latest version of a secret from the KV v2 secrets engine. @@ -107,7 +57,7 @@ func WithMergeMethod(method string) KVOption { // If the latest version has been deleted, an error will not be thrown, but // the Data field on the returned secret will be nil, and the Metadata field // will contain the deletion time. -func (kv *KVv2) Get(ctx context.Context, secretPath string) (*KVSecret, error) { +func (kv *kvv2) Get(ctx context.Context, secretPath string) (*KVSecret, error) { pathToRead := fmt.Sprintf("%s/data/%s", kv.mountPath, secretPath) secret, err := kv.c.Logical().ReadWithContext(ctx, pathToRead) @@ -140,7 +90,7 @@ func (kv *KVv2) Get(ctx context.Context, secretPath string) (*KVSecret, error) { // // GetVersionsAsList can provide a list of available versions sorted by // version number, while the response from GetMetadata contains them as a map. -func (kv *KVv2) GetVersion(ctx context.Context, secretPath string, version int) (*KVSecret, error) { +func (kv *kvv2) GetVersion(ctx context.Context, secretPath string, version int) (*KVSecret, error) { pathToRead := fmt.Sprintf("%s/data/%s", kv.mountPath, secretPath) queryParams := map[string][]string{"version": {strconv.Itoa(version)}} @@ -167,7 +117,7 @@ func (kv *KVv2) GetVersion(ctx context.Context, secretPath string, version int) } // GetVersionsAsList returns a subset of the metadata for each version of the secret, sorted by version number. -func (kv *KVv2) GetVersionsAsList(ctx context.Context, secretPath string) ([]KVVersionMetadata, error) { +func (kv *kvv2) GetVersionsAsList(ctx context.Context, secretPath string) ([]KVVersionMetadata, error) { pathToRead := fmt.Sprintf("%s/metadata/%s", kv.mountPath, secretPath) secret, err := kv.c.Logical().ReadWithContext(ctx, pathToRead) @@ -194,7 +144,7 @@ func (kv *KVv2) GetVersionsAsList(ctx context.Context, secretPath string) ([]KVV // GetMetadata returns the full metadata for a given secret, including a map of // its existing versions and their respective creation/deletion times, etc. -func (kv *KVv2) GetMetadata(ctx context.Context, secretPath string) (*KVMetadata, error) { +func (kv *kvv2) GetMetadata(ctx context.Context, secretPath string) (*KVMetadata, error) { pathToRead := fmt.Sprintf("%s/metadata/%s", kv.mountPath, secretPath) secret, err := kv.c.Logical().ReadWithContext(ctx, pathToRead) @@ -219,7 +169,7 @@ func (kv *KVv2) GetMetadata(ctx context.Context, secretPath string) (*KVMetadata // If the secret already exists, a new version will be created // and the previous version can be accessed with the GetVersion method. // GetMetadata can provide a list of available versions. -func (kv *KVv2) Put(ctx context.Context, secretPath string, data map[string]interface{}, opts ...KVOption) (*KVSecret, error) { +func (kv *kvv2) Put(ctx context.Context, secretPath string, data map[string]interface{}, opts ...KVOption) (*KVSecret, error) { pathToWriteTo := fmt.Sprintf("%s/data/%s", kv.mountPath, secretPath) wrappedData := map[string]interface{}{ @@ -267,107 +217,9 @@ func (kv *KVv2) Put(ctx context.Context, secretPath string, data map[string]inte return kvSecret, nil } -// PutMetadata can be used to fully replace a subset of metadata fields for a -// given KV v2 secret. All fields will replace the corresponding values on the Vault server. -// Any fields left as nil will reset the field on the Vault server back to its zero value. -// -// To only partially replace the values of these metadata fields, use PatchMetadata. -// -// This method can also be used to create a new secret with just metadata and no secret data yet. -func (kv *KVv2) PutMetadata(ctx context.Context, secretPath string, metadata KVMetadataPutInput) error { - pathToWriteTo := fmt.Sprintf("%s/metadata/%s", kv.mountPath, secretPath) - - const ( - casRequiredKey = "cas_required" - deleteVersionAfterKey = "delete_version_after" - maxVersionsKey = "max_versions" - customMetadataKey = "custom_metadata" - ) - - // convert values to a map we can pass to Logical - metadataMap := make(map[string]interface{}) - metadataMap[maxVersionsKey] = metadata.MaxVersions - metadataMap[deleteVersionAfterKey] = metadata.DeleteVersionAfter.String() - metadataMap[casRequiredKey] = metadata.CASRequired - metadataMap[customMetadataKey] = metadata.CustomMetadata - - _, err := kv.c.Logical().WriteWithContext(ctx, pathToWriteTo, metadataMap) - if err != nil { - return fmt.Errorf("error writing secret metadata to %s: %w", pathToWriteTo, err) - } - - return nil -} - -// Patch additively updates the most recent version of a key-value secret, -// differentiating it from Put which will fully overwrite the previous data. -// Only the key-value pairs that are new or changing need to be provided. -// -// The WithMethod KVOption function can optionally be passed to dictate which -// kind of patch to perform, as older Vault server versions (pre-1.9.0) may -// only be able to use the old "rw" (read-then-write) style of partial update, -// whereas newer Vault servers can use the default value of "patch" if the -// client token's policy has the "patch" capability. -func (kv *KVv2) Patch(ctx context.Context, secretPath string, newData map[string]interface{}, opts ...KVOption) (*KVSecret, error) { - // determine patch method - var patchMethod string - var ok bool - for _, opt := range opts { - k, v := opt() - if k == "method" { - patchMethod, ok = v.(string) - if !ok { - return nil, fmt.Errorf("unsupported type provided for option value; value for patch method should be string \"rw\" or \"patch\"") - } - } - } - - // Determine which kind of patch to use, - // the newer HTTP Patch style or the older read-then-write style - var kvs *KVSecret - var perr error - switch patchMethod { - case "rw": - kvs, perr = readThenWrite(ctx, kv.c, kv.mountPath, secretPath, newData) - case "patch": - kvs, perr = mergePatch(ctx, kv.c, kv.mountPath, secretPath, newData, opts...) - case "": - kvs, perr = mergePatch(ctx, kv.c, kv.mountPath, secretPath, newData, opts...) - default: - return nil, fmt.Errorf("unsupported patch method provided; value for patch method should be string \"rw\" or \"patch\"") - } - if perr != nil { - return nil, fmt.Errorf("unable to perform patch: %w", perr) - } - if kvs == nil { - return nil, fmt.Errorf("no secret was written to %s", secretPath) - } - - return kvs, nil -} - -// PatchMetadata can be used to replace just a subset of a secret's -// metadata fields at a time, as opposed to PutMetadata which is used to -// completely replace all fields on the previous metadata. -func (kv *KVv2) PatchMetadata(ctx context.Context, secretPath string, metadata KVMetadataPatchInput) error { - pathToWriteTo := fmt.Sprintf("%s/metadata/%s", kv.mountPath, secretPath) - - md, err := toMetadataMap(metadata) - if err != nil { - return fmt.Errorf("unable to create map for JSON merge patch request: %w", err) - } - - _, err = kv.c.Logical().JSONMergePatch(ctx, pathToWriteTo, md) - if err != nil { - return fmt.Errorf("error patching metadata at %s: %w", pathToWriteTo, err) - } - - return nil -} - // Delete deletes the most recent version of a secret from the KV v2 // secrets engine. To delete an older version, use DeleteVersions. -func (kv *KVv2) Delete(ctx context.Context, secretPath string) error { +func (kv *kvv2) Delete(ctx context.Context, secretPath string) error { pathToDelete := fmt.Sprintf("%s/data/%s", kv.mountPath, secretPath) _, err := kv.c.Logical().DeleteWithContext(ctx, pathToDelete) @@ -380,7 +232,7 @@ func (kv *KVv2) Delete(ctx context.Context, secretPath string) error { // DeleteVersions deletes the specified versions of a secret from the KV v2 // secrets engine. To delete the latest version of a secret, just use Delete. -func (kv *KVv2) DeleteVersions(ctx context.Context, secretPath string, versions []int) error { +func (kv *kvv2) DeleteVersions(ctx context.Context, secretPath string, versions []int) error { // verb and path are different when trying to delete past versions pathToDelete := fmt.Sprintf("%s/delete/%s", kv.mountPath, secretPath) @@ -403,119 +255,27 @@ func (kv *KVv2) DeleteVersions(ctx context.Context, secretPath string, versions return nil } -// DeleteMetadata deletes all versions and metadata of the secret at the -// given path. -func (kv *KVv2) DeleteMetadata(ctx context.Context, secretPath string) error { - pathToDelete := fmt.Sprintf("%s/metadata/%s", kv.mountPath, secretPath) - - _, err := kv.c.Logical().DeleteWithContext(ctx, pathToDelete) - if err != nil { - return fmt.Errorf("error deleting secret metadata at %s: %w", pathToDelete, err) - } - - return nil -} - -// Undelete undeletes the given versions of a secret, restoring the data -// so that it can be fetched again with Get requests. -// -// A list of existing versions can be retrieved using the GetVersionsAsList method. -func (kv *KVv2) Undelete(ctx context.Context, secretPath string, versions []int) error { - pathToUndelete := fmt.Sprintf("%s/undelete/%s", kv.mountPath, secretPath) - - data := map[string]interface{}{ - "versions": versions, - } - - _, err := kv.c.Logical().WriteWithContext(ctx, pathToUndelete, data) - if err != nil { - return fmt.Errorf("error undeleting secret metadata at %s: %w", pathToUndelete, err) - } - - return nil -} - -// Destroy permanently removes the specified secret versions' data -// from the Vault server. If no secret exists at the given path, no -// action will be taken. -// -// A list of existing versions can be retrieved using the GetVersionsAsList method. -func (kv *KVv2) Destroy(ctx context.Context, secretPath string, versions []int) error { - pathToDestroy := fmt.Sprintf("%s/destroy/%s", kv.mountPath, secretPath) - - data := map[string]interface{}{ - "versions": versions, - } - - _, err := kv.c.Logical().WriteWithContext(ctx, pathToDestroy, data) - if err != nil { - return fmt.Errorf("error destroying secret metadata at %s: %w", pathToDestroy, err) - } - - return nil -} - -// Rollback can be used to roll a secret back to a previous -// non-deleted/non-destroyed version. That previous version becomes the -// next/newest version for the path. -func (kv *KVv2) Rollback(ctx context.Context, secretPath string, toVersion int) (*KVSecret, error) { - // First, do a read to get the current version for check-and-set - latest, err := kv.Get(ctx, secretPath) - if err != nil { - return nil, fmt.Errorf("unable to get latest version of secret: %w", err) - } - - // Make sure a value already exists - if latest == nil { - return nil, fmt.Errorf("no secret was found: %w", err) - } - - // Verify metadata found - if latest.VersionMetadata == nil { - return nil, fmt.Errorf("no metadata found; rollback can only be used on existing data") - } - - // Now run it again and read the version we want to roll back to - rollbackVersion, err := kv.GetVersion(ctx, secretPath, toVersion) - if err != nil { - return nil, fmt.Errorf("unable to get previous version %d of secret: %s", toVersion, err) - } - - err = validateRollbackVersion(rollbackVersion) - if err != nil { - return nil, fmt.Errorf("invalid rollback version %d: %w", toVersion, err) - } - - casVersion := latest.VersionMetadata.Version - kvs, err := kv.Put(ctx, secretPath, rollbackVersion.Data, WithCheckAndSet(casVersion)) - if err != nil { - return nil, fmt.Errorf("unable to roll back to previous secret version: %w", err) - } - - return kvs, nil -} - func extractCustomMetadata(secret *Secret) (map[string]interface{}, error) { // Logical Writes return the metadata directly, Reads return it nested inside the "metadata" key - customMetadataInterface, ok := secret.Data["custom_metadata"] + cmI, ok := secret.Data["custom_metadata"] if !ok { - metadataInterface, ok := secret.Data["metadata"] + mI, ok := secret.Data["metadata"] if !ok { // if that's not found, bail since it should have had one or the other return nil, fmt.Errorf("secret is missing expected fields") } - metadataMap, ok := metadataInterface.(map[string]interface{}) + mM, ok := mI.(map[string]interface{}) if !ok { - return nil, fmt.Errorf("unexpected type for 'metadata' element: %T (%#v)", metadataInterface, metadataInterface) + return nil, fmt.Errorf("unexpected type for 'metadata' element: %T (%#v)", mI, mI) } - customMetadataInterface, ok = metadataMap["custom_metadata"] + cmI, ok = mM["custom_metadata"] if !ok { - return nil, fmt.Errorf("metadata missing expected field \"custom_metadata\": %v", metadataMap) + return nil, fmt.Errorf("metadata missing expected field \"custom_metadata\":%v", mM) } } - cm, ok := customMetadataInterface.(map[string]interface{}) - if !ok && customMetadataInterface != nil { - return nil, fmt.Errorf("unexpected type for 'metadata' element: %T (%#v)", customMetadataInterface, customMetadataInterface) + cm, ok := cmI.(map[string]interface{}) + if !ok && cmI != nil { + return nil, fmt.Errorf("unexpected type for 'metadata' element: %T (%#v)", cmI, cmI) } return cm, nil @@ -639,150 +399,3 @@ func extractFullMetadata(secret *Secret) (*KVMetadata, error) { return metadata, nil } - -func validateRollbackVersion(rollbackVersion *KVSecret) error { - // Make sure a value already exists - if rollbackVersion == nil || rollbackVersion.Data == nil { - return fmt.Errorf("no secret found") - } - - // Verify metadata found - if rollbackVersion.VersionMetadata == nil { - return fmt.Errorf("no version metadata found; rollback only works on existing data") - } - - // Verify it hasn't been deleted - if !rollbackVersion.VersionMetadata.DeletionTime.IsZero() { - return fmt.Errorf("cannot roll back to a version that has been deleted") - } - - if rollbackVersion.VersionMetadata.Destroyed { - return fmt.Errorf("cannot roll back to a version that has been destroyed") - } - - // Verify old data found - if rollbackVersion.Data == nil { - return fmt.Errorf("no data found; rollback only works on existing data") - } - - return nil -} - -func mergePatch(ctx context.Context, client *Client, mountPath string, secretPath string, newData map[string]interface{}, opts ...KVOption) (*KVSecret, error) { - pathToMergePatch := fmt.Sprintf("%s/data/%s", mountPath, secretPath) - - // take any other additional options provided - // and pass them along to the patch request - wrappedData := map[string]interface{}{ - "data": newData, - } - options := make(map[string]interface{}) - for _, opt := range opts { - k, v := opt() - options[k] = v - } - if len(opts) > 0 { - wrappedData["options"] = options - } - - secret, err := client.Logical().JSONMergePatch(ctx, pathToMergePatch, wrappedData) - if err != nil { - // If it's a 405, that probably means the server is running a pre-1.9 - // Vault version that doesn't support the HTTP PATCH method. - // Fall back to the old way of doing it. - if re, ok := err.(*ResponseError); ok && re.StatusCode == 405 { - return readThenWrite(ctx, client, mountPath, secretPath, newData) - } - - if re, ok := err.(*ResponseError); ok && re.StatusCode == 403 { - return nil, fmt.Errorf("received 403 from Vault server; please ensure that token's policy has \"patch\" capability: %w", err) - } - - return nil, fmt.Errorf("error performing merge patch to %s: %s", pathToMergePatch, err) - } - - metadata, err := extractVersionMetadata(secret) - if err != nil { - return nil, fmt.Errorf("secret was written successfully, but unable to view version metadata from response: %w", err) - } - - kvSecret := &KVSecret{ - Data: nil, // secret.Data in this case is the metadata - VersionMetadata: metadata, - Raw: secret, - } - - cm, err := extractCustomMetadata(secret) - if err != nil { - return nil, fmt.Errorf("error reading custom metadata for secret %s: %w", secretPath, err) - } - kvSecret.CustomMetadata = cm - - return kvSecret, nil -} - -func readThenWrite(ctx context.Context, client *Client, mountPath string, secretPath string, newData map[string]interface{}) (*KVSecret, error) { - // First, read the secret. - existingVersion, err := client.KVv2(mountPath).Get(ctx, secretPath) - if err != nil { - return nil, fmt.Errorf("error reading secret as part of read-then-write patch operation: %w", err) - } - - // Make sure the secret already exists - if existingVersion == nil || existingVersion.Data == nil { - return nil, fmt.Errorf("no existing secret was found at %s when doing read-then-write patch operation: %w", secretPath, err) - } - - // Verify existing secret has metadata - if existingVersion.VersionMetadata == nil { - return nil, fmt.Errorf("no metadata found at %s; patch can only be used on existing data", secretPath) - } - - // Copy new data over with existing data - combinedData := existingVersion.Data - for k, v := range newData { - combinedData[k] = v - } - - updatedSecret, err := client.KVv2(mountPath).Put(ctx, secretPath, combinedData, WithCheckAndSet(existingVersion.VersionMetadata.Version)) - if err != nil { - return nil, fmt.Errorf("error writing secret to %s: %w", secretPath, err) - } - - return updatedSecret, nil -} - -func toMetadataMap(patchInput KVMetadataPatchInput) (map[string]interface{}, error) { - metadataMap := make(map[string]interface{}) - - const ( - casRequiredKey = "cas_required" - deleteVersionAfterKey = "delete_version_after" - maxVersionsKey = "max_versions" - customMetadataKey = "custom_metadata" - ) - - // The KVMetadataPatchInput struct is designed to have pointer fields so that - // the user can easily express the difference between explicitly setting a - // field back to its zero value (e.g. false), as opposed to just having - // the field remain unchanged (e.g. nil). This way, they only need to pass - // the fields they want to change. - if patchInput.MaxVersions != nil { - metadataMap[maxVersionsKey] = *(patchInput.MaxVersions) - } - if patchInput.CASRequired != nil { - metadataMap[casRequiredKey] = *(patchInput.CASRequired) - } - if patchInput.CustomMetadata != nil { - if len(patchInput.CustomMetadata) == 0 { // empty non-nil map means delete all the keys - metadataMap[customMetadataKey] = nil - } else { - metadataMap[customMetadataKey] = patchInput.CustomMetadata - } - } - if patchInput.DeleteVersionAfter != nil { - metadataMap[deleteVersionAfterKey] = patchInput.DeleteVersionAfter.String() - } - - return metadataMap, nil -} diff --git a/api/output_string.go b/api/output_string.go index 80c591f20b5c7..b8c396ebc05db 100644 --- a/api/output_string.go +++ b/api/output_string.go @@ -60,19 +60,19 @@ func (d *OutputStringError) buildCurlString() (string, error) { finalCurlString = fmt.Sprintf("%s-X %s ", finalCurlString, d.Request.Method) } if d.ClientCACert != "" { - clientCACert := strings.ReplaceAll(d.ClientCACert, "'", "'\"'\"'") + clientCACert := strings.Replace(d.ClientCACert, "'", "'\"'\"'", -1) finalCurlString = fmt.Sprintf("%s--cacert '%s' ", finalCurlString, clientCACert) } if d.ClientCAPath != "" { - clientCAPath := strings.ReplaceAll(d.ClientCAPath, "'", "'\"'\"'") + clientCAPath := strings.Replace(d.ClientCAPath, "'", "'\"'\"'", -1) finalCurlString = fmt.Sprintf("%s--capath '%s' ", finalCurlString, clientCAPath) } if d.ClientCert != "" { - clientCert := strings.ReplaceAll(d.ClientCert, "'", "'\"'\"'") + clientCert := strings.Replace(d.ClientCert, "'", "'\"'\"'", -1) finalCurlString = fmt.Sprintf("%s--cert '%s' ", finalCurlString, clientCert) } if d.ClientKey != "" { - clientKey := strings.ReplaceAll(d.ClientKey, "'", "'\"'\"'") + clientKey := strings.Replace(d.ClientKey, "'", "'\"'\"'", -1) finalCurlString = fmt.Sprintf("%s--key '%s' ", finalCurlString, clientKey) } for k, v := range d.Request.Header { @@ -87,7 +87,7 @@ func (d *OutputStringError) buildCurlString() (string, error) { if len(body) > 0 { // We need to escape single quotes since that's what we're using to // quote the body - escapedBody := strings.ReplaceAll(string(body), "'", "'\"'\"'") + escapedBody := strings.Replace(string(body), "'", "'\"'\"'", -1) finalCurlString = fmt.Sprintf("%s-d '%s' ", finalCurlString, escapedBody) } diff --git a/audit/format_json_test.go b/audit/format_json_test.go index e4a703d12ad42..e2d8b3b086870 100644 --- a/audit/format_json_test.go +++ b/audit/format_json_test.go @@ -144,7 +144,7 @@ func TestFormatJSON_formatRequest(t *testing.T) { if !strings.HasSuffix(strings.TrimSpace(buf.String()), string(expectedBytes)) { t.Fatalf( - "bad: %s\nResult:\n\n%q\n\nExpected:\n\n%q", + "bad: %s\nResult:\n\n'%s'\n\nExpected:\n\n'%s'", name, buf.String(), string(expectedBytes)) } } diff --git a/audit/format_jsonx_test.go b/audit/format_jsonx_test.go index 00921c0c71a95..6774f01fb6bd7 100644 --- a/audit/format_jsonx_test.go +++ b/audit/format_jsonx_test.go @@ -137,7 +137,7 @@ func TestFormatJSONx_formatRequest(t *testing.T) { if !strings.HasSuffix(strings.TrimSpace(buf.String()), string(tc.ExpectedStr)) { t.Fatalf( - "bad: %s\nResult:\n\n%q\n\nExpected:\n\n%q", + "bad: %s\nResult:\n\n'%s'\n\nExpected:\n\n'%s'", name, strings.TrimSpace(buf.String()), string(tc.ExpectedStr)) } } diff --git a/builtin/credential/approle/path_login.go b/builtin/credential/approle/path_login.go index 5822519b1c79f..ba478c4ffd50e 100644 --- a/builtin/credential/approle/path_login.go +++ b/builtin/credential/approle/path_login.go @@ -33,9 +33,6 @@ func pathLogin(b *backend) *framework.Path { logical.AliasLookaheadOperation: &framework.PathOperation{ Callback: b.pathLoginUpdateAliasLookahead, }, - logical.ResolveRoleOperation: &framework.PathOperation{ - Callback: b.pathLoginResolveRole, - }, }, HelpSynopsis: pathLoginHelpSys, HelpDescription: pathLoginHelpDesc, @@ -57,39 +54,6 @@ func (b *backend) pathLoginUpdateAliasLookahead(ctx context.Context, req *logica }, nil } -func (b *backend) pathLoginResolveRole(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { - // RoleID must be supplied during every login - roleID := strings.TrimSpace(data.Get("role_id").(string)) - if roleID == "" { - return logical.ErrorResponse("missing role_id"), nil - } - - // Look for the storage entry that maps the roleID to role - roleIDIndex, err := b.roleIDEntry(ctx, req.Storage, roleID) - if err != nil { - return nil, err - } - if roleIDIndex == nil { - return logical.ErrorResponse("invalid role ID"), nil - } - - roleName := roleIDIndex.Name - - roleLock := b.roleLock(roleName) - roleLock.RLock() - - role, err := b.roleEntry(ctx, req.Storage, roleName) - roleLock.RUnlock() - if err != nil { - return nil, err - } - if role == nil { - return logical.ErrorResponse("invalid role ID"), nil - } - - return logical.ResolveRoleResponse(roleName) -} - // Returns the Auth object indicating the authentication and authorization information // if the credentials provided are validated by the backend. func (b *backend) pathLoginUpdate(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { diff --git a/builtin/credential/approle/path_login_test.go b/builtin/credential/approle/path_login_test.go index 542bf665b6e9a..9d1facf52cf96 100644 --- a/builtin/credential/approle/path_login_test.go +++ b/builtin/credential/approle/path_login_test.go @@ -301,92 +301,3 @@ func generateRenewRequest(s logical.Storage, auth *logical.Auth) *logical.Reques return renewReq } - -func TestAppRole_RoleResolve(t *testing.T) { - var resp *logical.Response - var err error - b, storage := createBackendWithStorage(t) - - role := "role1" - createRole(t, b, storage, role, "a,b,c") - roleRoleIDReq := &logical.Request{ - Operation: logical.ReadOperation, - Path: "role/role1/role-id", - Storage: storage, - } - resp, err = b.HandleRequest(context.Background(), roleRoleIDReq) - if err != nil || (resp != nil && resp.IsError()) { - t.Fatalf("err:%v resp:%#v", err, resp) - } - roleID := resp.Data["role_id"] - - roleSecretIDReq := &logical.Request{ - Operation: logical.UpdateOperation, - Path: "role/role1/secret-id", - Storage: storage, - } - resp, err = b.HandleRequest(context.Background(), roleSecretIDReq) - if err != nil || (resp != nil && resp.IsError()) { - t.Fatalf("err:%v resp:%#v", err, resp) - } - secretID := resp.Data["secret_id"] - - loginData := map[string]interface{}{ - "role_id": roleID, - "secret_id": secretID, - } - loginReq := &logical.Request{ - Operation: logical.ResolveRoleOperation, - Path: "login", - Storage: storage, - Data: loginData, - Connection: &logical.Connection{ - RemoteAddr: "127.0.0.1", - }, - } - - resp, err = b.HandleRequest(context.Background(), loginReq) - if err != nil || (resp != nil && resp.IsError()) { - t.Fatalf("err:%v resp:%#v", err, resp) - } - - if resp.Data["role"] != role { - t.Fatalf("Role was not as expected. Expected %s, received %s", role, resp.Data["role"]) - } -} - -func TestAppRole_RoleDoesNotExist(t *testing.T) { - var resp *logical.Response - var err error - b, storage := createBackendWithStorage(t) - - roleID := "roleDoesNotExist" - - loginData := map[string]interface{}{ - "role_id": roleID, - "secret_id": "secret", - } - loginReq := &logical.Request{ - Operation: logical.ResolveRoleOperation, - Path: "login", - Storage: storage, - Data: loginData, - Connection: &logical.Connection{ - RemoteAddr: "127.0.0.1", - }, - } - - resp, err = b.HandleRequest(context.Background(), loginReq) - if resp == nil && !resp.IsError() { - t.Fatalf("Response was not an error: err:%v resp:%#v", err, resp) - } - - errString, ok := resp.Data["error"].(string) - if !ok { - t.Fatal("Error not part of response.") - } - - if !strings.Contains(errString, "invalid role ID") { - t.Fatalf("Error was not due to invalid role ID. Error: %s", errString) - } -} diff --git a/builtin/credential/aws/backend_test.go b/builtin/credential/aws/backend_test.go index 209317ed21178..14b79735c1b4d 100644 --- a/builtin/credential/aws/backend_test.go +++ b/builtin/credential/aws/backend_test.go @@ -1052,7 +1052,7 @@ func TestBackendAcc_LoginWithInstanceIdentityDocAndAccessListIdentity(t *testing // This test case should be run only when certain env vars are set and // executed as an acceptance test. if os.Getenv(logicaltest.TestEnvVar) == "" { - t.Skip(fmt.Sprintf("Acceptance tests skipped unless env %q set", logicaltest.TestEnvVar)) + t.Skip(fmt.Sprintf("Acceptance tests skipped unless env '%s' set", logicaltest.TestEnvVar)) return } @@ -1515,7 +1515,7 @@ func TestBackendAcc_LoginWithCallerIdentity(t *testing.T) { // This test case should be run only when certain env vars are set and // executed as an acceptance test. if os.Getenv(logicaltest.TestEnvVar) == "" { - t.Skip(fmt.Sprintf("Acceptance tests skipped unless env %q set", logicaltest.TestEnvVar)) + t.Skip(fmt.Sprintf("Acceptance tests skipped unless env '%s' set", logicaltest.TestEnvVar)) return } diff --git a/builtin/credential/aws/path_login.go b/builtin/credential/aws/path_login.go index fb8ab4f47492f..fe70de0d06e87 100644 --- a/builtin/credential/aws/path_login.go +++ b/builtin/credential/aws/path_login.go @@ -128,9 +128,6 @@ needs to be supplied along with 'identity' parameter.`, logical.AliasLookaheadOperation: &framework.PathOperation{ Callback: b.pathLoginUpdate, }, - logical.ResolveRoleOperation: &framework.PathOperation{ - Callback: b.pathLoginResolveRole, - }, }, HelpSynopsis: pathLoginSyn, @@ -138,203 +135,6 @@ needs to be supplied along with 'identity' parameter.`, } } -func (b *backend) pathLoginResolveRole(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { - anyEc2, allEc2 := hasValuesForEc2Auth(data) - anyIam, allIam := hasValuesForIamAuth(data) - switch { - case anyEc2 && anyIam: - return logical.ErrorResponse("supplied auth values for both ec2 and iam auth types"), nil - case anyEc2 && !allEc2: - return logical.ErrorResponse("supplied some of the auth values for the ec2 auth type but not all"), nil - case anyEc2: - return b.pathLoginResolveRoleEc2(ctx, req, data) - case anyIam && !allIam: - return logical.ErrorResponse("supplied some of the auth values for the iam auth type but not all"), nil - case anyIam: - return b.pathLoginResolveRoleIam(ctx, req, data) - default: - return logical.ErrorResponse("didn't supply required authentication values"), nil - } -} - -func (b *backend) pathLoginEc2GetRoleNameAndIdentityDoc(ctx context.Context, req *logical.Request, data *framework.FieldData) (string, *identityDocument, *logical.Response, error) { - identityDocB64 := data.Get("identity").(string) - var identityDocBytes []byte - var err error - if identityDocB64 != "" { - identityDocBytes, err = base64.StdEncoding.DecodeString(identityDocB64) - if err != nil || len(identityDocBytes) == 0 { - return "", nil, logical.ErrorResponse("failed to base64 decode the instance identity document"), nil - } - } - - signatureB64 := data.Get("signature").(string) - var signatureBytes []byte - if signatureB64 != "" { - signatureBytes, err = base64.StdEncoding.DecodeString(signatureB64) - if err != nil { - return "", nil, logical.ErrorResponse("failed to base64 decode the SHA256 RSA signature of the instance identity document"), nil - } - } - - pkcs7B64 := data.Get("pkcs7").(string) - - // Either the pkcs7 signature of the instance identity document, or - // the identity document itself along with its SHA256 RSA signature - // needs to be provided. - if pkcs7B64 == "" && (len(identityDocBytes) == 0 && len(signatureBytes) == 0) { - return "", nil, logical.ErrorResponse("either pkcs7 or a tuple containing the instance identity document and its SHA256 RSA signature needs to be provided"), nil - } else if pkcs7B64 != "" && (len(identityDocBytes) != 0 && len(signatureBytes) != 0) { - return "", nil, logical.ErrorResponse("both pkcs7 and a tuple containing the instance identity document and its SHA256 RSA signature is supplied; provide only one"), nil - } - - // Verify the signature of the identity document and unmarshal it - var identityDocParsed *identityDocument - if pkcs7B64 != "" { - identityDocParsed, err = b.parseIdentityDocument(ctx, req.Storage, pkcs7B64) - if err != nil { - return "", nil, nil, err - } - if identityDocParsed == nil { - return "", nil, logical.ErrorResponse("failed to verify the instance identity document using pkcs7"), nil - } - } else { - identityDocParsed, err = b.verifyInstanceIdentitySignature(ctx, req.Storage, identityDocBytes, signatureBytes) - if err != nil { - return "", nil, nil, err - } - if identityDocParsed == nil { - return "", nil, logical.ErrorResponse("failed to verify the instance identity document using the SHA256 RSA digest"), nil - } - } - - roleName := data.Get("role").(string) - - // If roleName is not supplied, a role in the name of the instance's AMI ID will be looked for - if roleName == "" { - roleName = identityDocParsed.AmiID - } - - // Get the entry for the role used by the instance - // Note that we don't return the roleEntry, but use it to determine if the role exists - // roleEntry does not contain the role name, so it is not appropriate to return - roleEntry, err := b.role(ctx, req.Storage, roleName) - if err != nil { - return "", nil, nil, err - } - if roleEntry == nil { - return "", nil, logical.ErrorResponse(fmt.Sprintf("entry for role %q not found", roleName)), nil - } - return roleName, identityDocParsed, nil, nil -} - -func (b *backend) pathLoginResolveRoleEc2(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { - role, _, resp, err := b.pathLoginEc2GetRoleNameAndIdentityDoc(ctx, req, data) - if resp != nil || err != nil { - return resp, err - } - return logical.ResolveRoleResponse(role) -} - -func (b *backend) pathLoginIamGetRoleNameCallerIdAndEntity(ctx context.Context, req *logical.Request, data *framework.FieldData) (string, *GetCallerIdentityResult, *iamEntity, *logical.Response, error) { - method := data.Get("iam_http_request_method").(string) - if method == "" { - return "", nil, nil, logical.ErrorResponse("missing iam_http_request_method"), nil - } - - // In the future, might consider supporting GET - if method != "POST" { - return "", nil, nil, logical.ErrorResponse("invalid iam_http_request_method; currently only 'POST' is supported"), nil - } - - rawUrlB64 := data.Get("iam_request_url").(string) - if rawUrlB64 == "" { - return "", nil, nil, logical.ErrorResponse("missing iam_request_url"), nil - } - rawUrl, err := base64.StdEncoding.DecodeString(rawUrlB64) - if err != nil { - return "", nil, nil, logical.ErrorResponse("failed to base64 decode iam_request_url"), nil - } - parsedUrl, err := url.Parse(string(rawUrl)) - if err != nil { - return "", nil, nil, logical.ErrorResponse("error parsing iam_request_url"), nil - } - if parsedUrl.RawQuery != "" { - // Should be no query parameters - return "", nil, nil, logical.ErrorResponse(logical.ErrInvalidRequest.Error()), nil - } - // TODO: There are two potentially valid cases we're not yet supporting that would - // necessitate this check being changed. First, if we support GET requests. - // Second if we support presigned POST requests - bodyB64 := data.Get("iam_request_body").(string) - if bodyB64 == "" { - return "", nil, nil, logical.ErrorResponse("missing iam_request_body"), nil - } - bodyRaw, err := base64.StdEncoding.DecodeString(bodyB64) - if err != nil { - return "", nil, nil, logical.ErrorResponse("failed to base64 decode iam_request_body"), nil - } - body := string(bodyRaw) - if err = validateLoginIamRequestBody(body); err != nil { - return "", nil, nil, logical.ErrorResponse(err.Error()), nil - } - - headers := data.Get("iam_request_headers").(http.Header) - if len(headers) == 0 { - return "", nil, nil, logical.ErrorResponse("missing iam_request_headers"), nil - } - - config, err := b.lockedClientConfigEntry(ctx, req.Storage) - if err != nil { - return "", nil, nil, logical.ErrorResponse("error getting configuration"), nil - } - - endpoint := "https://sts.amazonaws.com" - - maxRetries := awsClient.DefaultRetryerMaxNumRetries - if config != nil { - if config.IAMServerIdHeaderValue != "" { - err = validateVaultHeaderValue(headers, parsedUrl, config.IAMServerIdHeaderValue) - if err != nil { - return "", nil, nil, logical.ErrorResponse(fmt.Sprintf("error validating %s header: %v", iamServerIdHeader, err)), nil - } - } - if err = config.validateAllowedSTSHeaderValues(headers); err != nil { - return "", nil, nil, logical.ErrorResponse(err.Error()), nil - } - if config.STSEndpoint != "" { - endpoint = config.STSEndpoint - } - if config.MaxRetries >= 0 { - maxRetries = config.MaxRetries - } - } - - callerID, err := submitCallerIdentityRequest(ctx, maxRetries, method, endpoint, parsedUrl, body, headers) - if err != nil { - return "", nil, nil, logical.ErrorResponse(fmt.Sprintf("error making upstream request: %v", err)), nil - } - - entity, err := parseIamArn(callerID.Arn) - if err != nil { - return "", nil, nil, logical.ErrorResponse(fmt.Sprintf("error parsing arn %q: %v", callerID.Arn, err)), nil - } - - roleName := data.Get("role").(string) - if roleName == "" { - roleName = entity.FriendlyName - } - return roleName, callerID, entity, nil, nil -} - -func (b *backend) pathLoginResolveRoleIam(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { - role, _, _, resp, err := b.pathLoginIamGetRoleNameCallerIdAndEntity(ctx, req, data) - if resp != nil || err != nil { - return resp, err - } - return logical.ResolveRoleResponse(role) -} - // instanceIamRoleARN fetches the IAM role ARN associated with the given // instance profile name func (b *backend) instanceIamRoleARN(iamClient *iam.IAM, instanceProfileName string) (string, error) { @@ -754,9 +554,61 @@ func (b *backend) verifyInstanceMeetsRoleRequirements(ctx context.Context, // and a client created nonce. Client nonce is optional if 'disallow_reauthentication' // option is enabled on the registered role. func (b *backend) pathLoginUpdateEc2(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { - roleName, identityDocParsed, errResp, err := b.pathLoginEc2GetRoleNameAndIdentityDoc(ctx, req, data) - if errResp != nil || err != nil { - return errResp, err + identityDocB64 := data.Get("identity").(string) + var identityDocBytes []byte + var err error + if identityDocB64 != "" { + identityDocBytes, err = base64.StdEncoding.DecodeString(identityDocB64) + if err != nil || len(identityDocBytes) == 0 { + return logical.ErrorResponse("failed to base64 decode the instance identity document"), nil + } + } + + signatureB64 := data.Get("signature").(string) + var signatureBytes []byte + if signatureB64 != "" { + signatureBytes, err = base64.StdEncoding.DecodeString(signatureB64) + if err != nil { + return logical.ErrorResponse("failed to base64 decode the SHA256 RSA signature of the instance identity document"), nil + } + } + + pkcs7B64 := data.Get("pkcs7").(string) + + // Either the pkcs7 signature of the instance identity document, or + // the identity document itself along with its SHA256 RSA signature + // needs to be provided. + if pkcs7B64 == "" && (len(identityDocBytes) == 0 && len(signatureBytes) == 0) { + return logical.ErrorResponse("either pkcs7 or a tuple containing the instance identity document and its SHA256 RSA signature needs to be provided"), nil + } else if pkcs7B64 != "" && (len(identityDocBytes) != 0 && len(signatureBytes) != 0) { + return logical.ErrorResponse("both pkcs7 and a tuple containing the instance identity document and its SHA256 RSA signature is supplied; provide only one"), nil + } + + // Verify the signature of the identity document and unmarshal it + var identityDocParsed *identityDocument + if pkcs7B64 != "" { + identityDocParsed, err = b.parseIdentityDocument(ctx, req.Storage, pkcs7B64) + if err != nil { + return nil, err + } + if identityDocParsed == nil { + return logical.ErrorResponse("failed to verify the instance identity document using pkcs7"), nil + } + } else { + identityDocParsed, err = b.verifyInstanceIdentitySignature(ctx, req.Storage, identityDocBytes, signatureBytes) + if err != nil { + return nil, err + } + if identityDocParsed == nil { + return logical.ErrorResponse("failed to verify the instance identity document using the SHA256 RSA digest"), nil + } + } + + roleName := data.Get("role").(string) + + // If roleName is not supplied, a role in the name of the instance's AMI ID will be looked for + if roleName == "" { + roleName = identityDocParsed.AmiID } // Get the entry for the role used by the instance @@ -1324,9 +1176,92 @@ func (b *backend) pathLoginRenewEc2(ctx context.Context, req *logical.Request, _ } func (b *backend) pathLoginUpdateIam(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { - roleName, callerID, entity, errResp, err := b.pathLoginIamGetRoleNameCallerIdAndEntity(ctx, req, data) - if errResp != nil || err != nil { - return errResp, err + method := data.Get("iam_http_request_method").(string) + if method == "" { + return logical.ErrorResponse("missing iam_http_request_method"), nil + } + + // In the future, might consider supporting GET + if method != "POST" { + return logical.ErrorResponse("invalid iam_http_request_method; currently only 'POST' is supported"), nil + } + + rawUrlB64 := data.Get("iam_request_url").(string) + if rawUrlB64 == "" { + return logical.ErrorResponse("missing iam_request_url"), nil + } + rawUrl, err := base64.StdEncoding.DecodeString(rawUrlB64) + if err != nil { + return logical.ErrorResponse("failed to base64 decode iam_request_url"), nil + } + parsedUrl, err := url.Parse(string(rawUrl)) + if err != nil { + return logical.ErrorResponse("error parsing iam_request_url"), nil + } + if parsedUrl.RawQuery != "" { + // Should be no query parameters + return logical.ErrorResponse(logical.ErrInvalidRequest.Error()), nil + } + // TODO: There are two potentially valid cases we're not yet supporting that would + // necessitate this check being changed. First, if we support GET requests. + // Second if we support presigned POST requests + bodyB64 := data.Get("iam_request_body").(string) + if bodyB64 == "" { + return logical.ErrorResponse("missing iam_request_body"), nil + } + bodyRaw, err := base64.StdEncoding.DecodeString(bodyB64) + if err != nil { + return logical.ErrorResponse("failed to base64 decode iam_request_body"), nil + } + body := string(bodyRaw) + if err = validateLoginIamRequestBody(body); err != nil { + return logical.ErrorResponse(err.Error()), nil + } + + headers := data.Get("iam_request_headers").(http.Header) + if len(headers) == 0 { + return logical.ErrorResponse("missing iam_request_headers"), nil + } + + config, err := b.lockedClientConfigEntry(ctx, req.Storage) + if err != nil { + return logical.ErrorResponse("error getting configuration"), nil + } + + endpoint := "https://sts.amazonaws.com" + + maxRetries := awsClient.DefaultRetryerMaxNumRetries + if config != nil { + if config.IAMServerIdHeaderValue != "" { + err = validateVaultHeaderValue(headers, parsedUrl, config.IAMServerIdHeaderValue) + if err != nil { + return logical.ErrorResponse(fmt.Sprintf("error validating %s header: %v", iamServerIdHeader, err)), nil + } + } + if err = config.validateAllowedSTSHeaderValues(headers); err != nil { + return logical.ErrorResponse(err.Error()), nil + } + if config.STSEndpoint != "" { + endpoint = config.STSEndpoint + } + if config.MaxRetries >= 0 { + maxRetries = config.MaxRetries + } + } + + callerID, err := submitCallerIdentityRequest(ctx, maxRetries, method, endpoint, parsedUrl, body, headers) + if err != nil { + return logical.ErrorResponse(fmt.Sprintf("error making upstream request: %v", err)), nil + } + + entity, err := parseIamArn(callerID.Arn) + if err != nil { + return logical.ErrorResponse(fmt.Sprintf("error parsing arn %q: %v", callerID.Arn, err)), nil + } + + roleName := data.Get("role").(string) + if roleName == "" { + roleName = entity.FriendlyName } roleEntry, err := b.role(ctx, req.Storage, roleName) diff --git a/builtin/credential/aws/path_login_test.go b/builtin/credential/aws/path_login_test.go index 6ffd60ed14943..82a2d9152e806 100644 --- a/builtin/credential/aws/path_login_test.go +++ b/builtin/credential/aws/path_login_test.go @@ -386,106 +386,6 @@ func TestBackend_pathLogin_IAMHeaders(t *testing.T) { } } -// TestBackend_pathLogin_IAMRoleResolution tests role resolution for an Iam login -func TestBackend_pathLogin_IAMRoleResolution(t *testing.T) { - storage := &logical.InmemStorage{} - config := logical.TestBackendConfig() - config.StorageView = storage - b, err := Backend(config) - if err != nil { - t.Fatal(err) - } - - err = b.Setup(context.Background(), config) - if err != nil { - t.Fatal(err) - } - - // sets up a test server to stand in for STS service - ts := setupIAMTestServer() - defer ts.Close() - - clientConfigData := map[string]interface{}{ - "iam_server_id_header_value": testVaultHeaderValue, - "sts_endpoint": ts.URL, - } - clientRequest := &logical.Request{ - Operation: logical.UpdateOperation, - Path: "config/client", - Storage: storage, - Data: clientConfigData, - } - _, err = b.HandleRequest(context.Background(), clientRequest) - if err != nil { - t.Fatal(err) - } - - // Configure identity. - _, err = b.HandleRequest(context.Background(), &logical.Request{ - Operation: logical.UpdateOperation, - Path: "config/identity", - Storage: storage, - Data: map[string]interface{}{ - "iam_alias": "role_id", - "iam_metadata": []string{ - "account_id", - "auth_type", - "canonical_arn", - "client_arn", - "client_user_id", - "inferred_aws_region", - "inferred_entity_id", - "inferred_entity_type", - }, - "ec2_alias": "role_id", - "ec2_metadata": []string{ - "account_id", - "ami_id", - "instance_id", - "region", - }, - }, - }) - if err != nil { - t.Fatal(err) - } - - // create a role entry - roleEntry := &awsRoleEntry{ - RoleID: "foo", - Version: currentRoleStorageVersion, - AuthType: iamAuthType, - } - - if err := b.setRole(context.Background(), storage, testValidRoleName, roleEntry); err != nil { - t.Fatalf("failed to set entry: %s", err) - } - - // create a baseline loginData map structure, including iam_request_headers - // already base64encoded. This is the "Default" loginData used for all tests. - // Each sub test can override the map's iam_request_headers entry - loginData, err := defaultLoginData() - if err != nil { - t.Fatal(err) - } - - loginRequest := &logical.Request{ - Operation: logical.ResolveRoleOperation, - Path: "login", - Storage: storage, - Data: loginData, - Connection: &logical.Connection{}, - } - - resp, err := b.HandleRequest(context.Background(), loginRequest) - if err != nil || resp == nil || resp.IsError() { - t.Errorf("unexpected failed role resolution:\nresp: %#v\n\nerr: %v", resp, err) - } - if resp.Data["role"] != testValidRoleName { - t.Fatalf("Role was not as expected. Expected %s, received %s", testValidRoleName, resp.Data["role"]) - } -} - func TestBackend_defaultAliasMetadata(t *testing.T) { storage := &logical.InmemStorage{} config := logical.TestBackendConfig() diff --git a/builtin/credential/aws/path_role.go b/builtin/credential/aws/path_role.go index 2e7f89fd68365..8cca61b3de9e2 100644 --- a/builtin/credential/aws/path_role.go +++ b/builtin/credential/aws/path_role.go @@ -259,7 +259,7 @@ func (b *backend) role(ctx context.Context, s logical.Storage, roleName string) return b.roleInternal(ctx, s, roleName) } -// roleInternal does not perform locking, and rechecks the cache, going to disk if necessary +// roleInternal does not perform locking, and rechecks the cache, going to disk if necessar func (b *backend) roleInternal(ctx context.Context, s logical.Storage, roleName string) (*awsRoleEntry, error) { // Check cache again now that we have the lock roleEntryRaw, found := b.roleCache.Get(roleName) @@ -897,7 +897,7 @@ func (b *backend) pathRoleCreateUpdate(ctx context.Context, req *logical.Request return logical.ErrorResponse("ttl should be shorter than max ttl"), nil } if roleEntry.TokenPeriod > b.System().MaxLeaseTTL() { - return logical.ErrorResponse(fmt.Sprintf("period of %q is greater than the backend's maximum lease TTL of %q", roleEntry.TokenPeriod.String(), b.System().MaxLeaseTTL().String())), nil + return logical.ErrorResponse(fmt.Sprintf("period of '%s' is greater than the backend's maximum lease TTL of '%s'", roleEntry.TokenPeriod.String(), b.System().MaxLeaseTTL().String())), nil } roleTagStr, ok := data.GetOk("role_tag") diff --git a/builtin/credential/aws/pkcs7/encrypt_test.go b/builtin/credential/aws/pkcs7/encrypt_test.go index 7f1bead232b9d..c64381e215517 100644 --- a/builtin/credential/aws/pkcs7/encrypt_test.go +++ b/builtin/credential/aws/pkcs7/encrypt_test.go @@ -15,6 +15,7 @@ func TestEncrypt(t *testing.T) { EncryptionAlgorithmAES256GCM, } sigalgs := []x509.SignatureAlgorithm{ + x509.SHA1WithRSA, x509.SHA256WithRSA, x509.SHA512WithRSA, } diff --git a/builtin/credential/aws/pkcs7/pkcs7_test.go b/builtin/credential/aws/pkcs7/pkcs7_test.go index 7753c174b2006..1eabc9bd4eda8 100644 --- a/builtin/credential/aws/pkcs7/pkcs7_test.go +++ b/builtin/credential/aws/pkcs7/pkcs7_test.go @@ -125,6 +125,16 @@ func createTestCertificateByIssuer(name string, issuer *certKeyPair, sigAlg x509 issuerKey = *issuer.PrivateKey } switch sigAlg { + case x509.SHA1WithRSA: + priv = test1024Key + switch issuerKey.(type) { + case *rsa.PrivateKey: + template.SignatureAlgorithm = x509.SHA1WithRSA + case *ecdsa.PrivateKey: + template.SignatureAlgorithm = x509.ECDSAWithSHA1 + case *dsa.PrivateKey: + template.SignatureAlgorithm = x509.DSAWithSHA1 + } case x509.SHA256WithRSA: priv = test2048Key switch issuerKey.(type) { @@ -155,6 +165,19 @@ func createTestCertificateByIssuer(name string, issuer *certKeyPair, sigAlg x509 case *dsa.PrivateKey: template.SignatureAlgorithm = x509.DSAWithSHA256 } + case x509.ECDSAWithSHA1: + priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) + if err != nil { + return nil, err + } + switch issuerKey.(type) { + case *rsa.PrivateKey: + template.SignatureAlgorithm = x509.SHA1WithRSA + case *ecdsa.PrivateKey: + template.SignatureAlgorithm = x509.ECDSAWithSHA1 + case *dsa.PrivateKey: + template.SignatureAlgorithm = x509.DSAWithSHA1 + } case x509.ECDSAWithSHA256: priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { @@ -194,6 +217,26 @@ func createTestCertificateByIssuer(name string, issuer *certKeyPair, sigAlg x509 case *dsa.PrivateKey: template.SignatureAlgorithm = x509.DSAWithSHA256 } + case x509.DSAWithSHA1: + var dsaPriv dsa.PrivateKey + params := &dsaPriv.Parameters + err = dsa.GenerateParameters(params, rand.Reader, dsa.L1024N160) + if err != nil { + return nil, err + } + err = dsa.GenerateKey(&dsaPriv, rand.Reader) + if err != nil { + return nil, err + } + switch issuerKey.(type) { + case *rsa.PrivateKey: + template.SignatureAlgorithm = x509.SHA1WithRSA + case *ecdsa.PrivateKey: + template.SignatureAlgorithm = x509.ECDSAWithSHA1 + case *dsa.PrivateKey: + template.SignatureAlgorithm = x509.DSAWithSHA1 + } + priv = &dsaPriv } if isCA { template.IsCA = true diff --git a/builtin/credential/aws/pkcs7/sign.go b/builtin/credential/aws/pkcs7/sign.go index b64fcb11da47b..0db0052616c88 100644 --- a/builtin/credential/aws/pkcs7/sign.go +++ b/builtin/credential/aws/pkcs7/sign.go @@ -24,7 +24,7 @@ type SignedData struct { } // NewSignedData takes data and initializes a PKCS7 SignedData struct that is -// ready to be signed via AddSigner. The digest algorithm is set to SHA-256 by default +// ready to be signed via AddSigner. The digest algorithm is set to SHA1 by default // and can be changed by calling SetDigestAlgorithm. func NewSignedData(data []byte) (*SignedData, error) { content, err := asn1.Marshal(data) @@ -39,7 +39,7 @@ func NewSignedData(data []byte) (*SignedData, error) { ContentInfo: ci, Version: 1, } - return &SignedData{sd: sd, data: data, digestOid: OIDDigestAlgorithmSHA256}, nil + return &SignedData{sd: sd, data: data, digestOid: OIDDigestAlgorithmSHA1}, nil } // SignerInfoConfig are optional values to include when adding a signer diff --git a/builtin/credential/aws/pkcs7/sign_test.go b/builtin/credential/aws/pkcs7/sign_test.go index 641cb0465fd05..0e513be3d7ae4 100644 --- a/builtin/credential/aws/pkcs7/sign_test.go +++ b/builtin/credential/aws/pkcs7/sign_test.go @@ -18,8 +18,10 @@ import ( func TestSign(t *testing.T) { content := []byte("Hello World") sigalgs := []x509.SignatureAlgorithm{ + x509.SHA1WithRSA, x509.SHA256WithRSA, x509.SHA512WithRSA, + x509.ECDSAWithSHA1, x509.ECDSAWithSHA256, x509.ECDSAWithSHA384, x509.ECDSAWithSHA512, @@ -97,7 +99,7 @@ func TestDSASignAndVerifyWithOpenSSL(t *testing.T) { } ioutil.WriteFile(tmpContentFile.Name(), content, 0o755) - block, _ := pem.Decode(dsaPublicCert) + block, _ := pem.Decode([]byte(dsaPublicCert)) if block == nil { t.Fatal("failed to parse certificate PEM") } @@ -127,8 +129,6 @@ func TestDSASignAndVerifyWithOpenSSL(t *testing.T) { if err != nil { t.Fatalf("test case: cannot initialize signed data: %s", err) } - // openssl DSA only supports SHA1 for our 1024-bit DSA key, since that is all the standard officially supports - toBeSigned.digestOid = OIDDigestAlgorithmSHA1 if err := toBeSigned.SignWithoutAttr(signerCert, &priv, SignerInfoConfig{}); err != nil { t.Fatalf("Cannot add signer: %s", err) } @@ -151,7 +151,6 @@ func TestDSASignAndVerifyWithOpenSSL(t *testing.T) { "-content", tmpContentFile.Name()) out, err := opensslCMD.CombinedOutput() if err != nil { - t.Errorf("Command: %s", opensslCMD.Args) t.Fatalf("test case: openssl command failed with %s: %s", err, out) } os.Remove(tmpSignatureFile.Name()) // clean up @@ -225,7 +224,7 @@ func TestUnmarshalSignedAttribute(t *testing.T) { } func TestDegenerateCertificate(t *testing.T) { - cert, err := createTestCertificate(x509.SHA256WithRSA) + cert, err := createTestCertificate(x509.SHA1WithRSA) if err != nil { t.Fatal(err) } diff --git a/builtin/credential/aws/pkcs7/verify_dsa_test.go b/builtin/credential/aws/pkcs7/verify_test_dsa.go similarity index 100% rename from builtin/credential/aws/pkcs7/verify_dsa_test.go rename to builtin/credential/aws/pkcs7/verify_test_dsa.go diff --git a/builtin/credential/cert/path_login.go b/builtin/credential/cert/path_login.go index f45e39f2e0692..e458b3fda9b7c 100644 --- a/builtin/credential/cert/path_login.go +++ b/builtin/credential/cert/path_login.go @@ -39,28 +39,10 @@ func pathLogin(b *backend) *framework.Path { Callbacks: map[logical.Operation]framework.OperationFunc{ logical.UpdateOperation: b.pathLogin, logical.AliasLookaheadOperation: b.pathLoginAliasLookahead, - logical.ResolveRoleOperation: b.pathLoginResolveRole, }, } } -func (b *backend) pathLoginResolveRole(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { - var matched *ParsedCert - if verifyResp, resp, err := b.verifyCredentials(ctx, req, data); err != nil { - return nil, err - } else if resp != nil { - return resp, nil - } else { - matched = verifyResp - } - - if matched == nil { - return logical.ErrorResponse("no certificate was matched by this request"), nil - } - - return logical.ResolveRoleResponse(matched.Entry.Name) -} - func (b *backend) pathLoginAliasLookahead(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) { clientCerts := req.Connection.ConnState.PeerCertificates if len(clientCerts) == 0 { diff --git a/builtin/credential/cert/path_login_test.go b/builtin/credential/cert/path_login_test.go deleted file mode 100644 index a01ec981663f3..0000000000000 --- a/builtin/credential/cert/path_login_test.go +++ /dev/null @@ -1,199 +0,0 @@ -package cert - -import ( - "crypto/tls" - "crypto/x509" - "crypto/x509/pkix" - "io/ioutil" - "math/big" - mathrand "math/rand" - "net" - "os" - "path/filepath" - "strings" - "testing" - "time" - - logicaltest "github.com/hashicorp/vault/helper/testhelpers/logical" - - "github.com/hashicorp/vault/sdk/logical" -) - -func TestCert_RoleResolve(t *testing.T) { - certTemplate := &x509.Certificate{ - Subject: pkix.Name{ - CommonName: "example.com", - }, - DNSNames: []string{"example.com"}, - IPAddresses: []net.IP{net.ParseIP("127.0.0.1")}, - ExtKeyUsage: []x509.ExtKeyUsage{ - x509.ExtKeyUsageServerAuth, - x509.ExtKeyUsageClientAuth, - }, - KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment | x509.KeyUsageKeyAgreement, - SerialNumber: big.NewInt(mathrand.Int63()), - NotBefore: time.Now().Add(-30 * time.Second), - NotAfter: time.Now().Add(262980 * time.Hour), - } - - tempDir, connState, err := generateTestCertAndConnState(t, certTemplate) - if tempDir != "" { - defer os.RemoveAll(tempDir) - } - if err != nil { - t.Fatalf("error testing connection state: %v", err) - } - ca, err := ioutil.ReadFile(filepath.Join(tempDir, "ca_cert.pem")) - if err != nil { - t.Fatalf("err: %v", err) - } - - logicaltest.Test(t, logicaltest.TestCase{ - CredentialBackend: testFactory(t), - Steps: []logicaltest.TestStep{ - testAccStepCert(t, "web", ca, "foo", allowed{dns: "example.com"}, false), - testAccStepLoginWithName(t, connState, "web"), - testAccStepResolveRoleWithName(t, connState, "web"), - }, - }) -} - -func testAccStepResolveRoleWithName(t *testing.T, connState tls.ConnectionState, certName string) logicaltest.TestStep { - return logicaltest.TestStep{ - Operation: logical.ResolveRoleOperation, - Path: "login", - Unauthenticated: true, - ConnState: &connState, - Check: func(resp *logical.Response) error { - if resp.Data["role"] != certName { - t.Fatalf("Role was not as expected. Expected %s, received %s", certName, resp.Data["role"]) - } - return nil - }, - Data: map[string]interface{}{ - "name": certName, - }, - } -} - -func TestCert_RoleResolveWithoutProvidingCertName(t *testing.T) { - certTemplate := &x509.Certificate{ - Subject: pkix.Name{ - CommonName: "example.com", - }, - DNSNames: []string{"example.com"}, - IPAddresses: []net.IP{net.ParseIP("127.0.0.1")}, - ExtKeyUsage: []x509.ExtKeyUsage{ - x509.ExtKeyUsageServerAuth, - x509.ExtKeyUsageClientAuth, - }, - KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment | x509.KeyUsageKeyAgreement, - SerialNumber: big.NewInt(mathrand.Int63()), - NotBefore: time.Now().Add(-30 * time.Second), - NotAfter: time.Now().Add(262980 * time.Hour), - } - - tempDir, connState, err := generateTestCertAndConnState(t, certTemplate) - if tempDir != "" { - defer os.RemoveAll(tempDir) - } - if err != nil { - t.Fatalf("error testing connection state: %v", err) - } - ca, err := ioutil.ReadFile(filepath.Join(tempDir, "ca_cert.pem")) - if err != nil { - t.Fatalf("err: %v", err) - } - - logicaltest.Test(t, logicaltest.TestCase{ - CredentialBackend: testFactory(t), - Steps: []logicaltest.TestStep{ - testAccStepCert(t, "web", ca, "foo", allowed{dns: "example.com"}, false), - testAccStepLoginWithName(t, connState, "web"), - testAccStepResolveRoleWithEmptyDataMap(t, connState, "web"), - }, - }) -} - -func testAccStepResolveRoleWithEmptyDataMap(t *testing.T, connState tls.ConnectionState, certName string) logicaltest.TestStep { - return logicaltest.TestStep{ - Operation: logical.ResolveRoleOperation, - Path: "login", - Unauthenticated: true, - ConnState: &connState, - Check: func(resp *logical.Response) error { - if resp.Data["role"] != certName { - t.Fatalf("Role was not as expected. Expected %s, received %s", certName, resp.Data["role"]) - } - return nil - }, - Data: map[string]interface{}{}, - } -} - -func testAccStepResolveRoleExpectRoleResolutionToFail(t *testing.T, connState tls.ConnectionState, certName string) logicaltest.TestStep { - return logicaltest.TestStep{ - Operation: logical.ResolveRoleOperation, - Path: "login", - Unauthenticated: true, - ConnState: &connState, - ErrorOk: true, - Check: func(resp *logical.Response) error { - if resp == nil && !resp.IsError() { - t.Fatalf("Response was not an error: resp:%#v", resp) - } - - errString, ok := resp.Data["error"].(string) - if !ok { - t.Fatal("Error not part of response.") - } - - if !strings.Contains(errString, "invalid certificate") { - t.Fatalf("Error was not due to invalid role name. Error: %s", errString) - } - return nil - }, - Data: map[string]interface{}{ - "name": certName, - }, - } -} - -func TestCert_RoleResolve_RoleDoesNotExist(t *testing.T) { - certTemplate := &x509.Certificate{ - Subject: pkix.Name{ - CommonName: "example.com", - }, - DNSNames: []string{"example.com"}, - IPAddresses: []net.IP{net.ParseIP("127.0.0.1")}, - ExtKeyUsage: []x509.ExtKeyUsage{ - x509.ExtKeyUsageServerAuth, - x509.ExtKeyUsageClientAuth, - }, - KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment | x509.KeyUsageKeyAgreement, - SerialNumber: big.NewInt(mathrand.Int63()), - NotBefore: time.Now().Add(-30 * time.Second), - NotAfter: time.Now().Add(262980 * time.Hour), - } - - tempDir, connState, err := generateTestCertAndConnState(t, certTemplate) - if tempDir != "" { - defer os.RemoveAll(tempDir) - } - if err != nil { - t.Fatalf("error testing connection state: %v", err) - } - ca, err := ioutil.ReadFile(filepath.Join(tempDir, "ca_cert.pem")) - if err != nil { - t.Fatalf("err: %v", err) - } - - logicaltest.Test(t, logicaltest.TestCase{ - CredentialBackend: testFactory(t), - Steps: []logicaltest.TestStep{ - testAccStepCert(t, "web", ca, "foo", allowed{dns: "example.com"}, false), - testAccStepLoginWithName(t, connState, "web"), - testAccStepResolveRoleExpectRoleResolutionToFail(t, connState, "notweb"), - }, - }) -} diff --git a/builtin/credential/ldap/backend.go b/builtin/credential/ldap/backend.go index d318fe4b4c6bb..bbd9f1bfc157d 100644 --- a/builtin/credential/ldap/backend.go +++ b/builtin/credential/ldap/backend.go @@ -150,7 +150,7 @@ func (b *backend) Login(ctx context.Context, req *logical.Request, username stri } if len(ldapGroups) == 0 { errString := fmt.Sprintf( - "no LDAP groups found in groupDN %q; only policies from locally-defined groups available", + "no LDAP groups found in groupDN '%s'; only policies from locally-defined groups available", cfg.GroupDN) ldapResponse.AddWarning(errString) } diff --git a/builtin/credential/ldap/backend_test.go b/builtin/credential/ldap/backend_test.go index d9d6482df0713..7a9f0f0eed5e3 100644 --- a/builtin/credential/ldap/backend_test.go +++ b/builtin/credential/ldap/backend_test.go @@ -783,27 +783,27 @@ func TestBackend_configDefaultsAfterUpdate(t *testing.T) { cfg := resp.Data defaultGroupFilter := "(|(memberUid={{.Username}})(member={{.UserDN}})(uniqueMember={{.UserDN}}))" if cfg["groupfilter"] != defaultGroupFilter { - t.Errorf("Default mismatch: groupfilter. Expected: %q, received :%q", defaultGroupFilter, cfg["groupfilter"]) + t.Errorf("Default mismatch: groupfilter. Expected: '%s', received :'%s'", defaultGroupFilter, cfg["groupfilter"]) } defaultGroupAttr := "cn" if cfg["groupattr"] != defaultGroupAttr { - t.Errorf("Default mismatch: groupattr. Expected: %q, received :%q", defaultGroupAttr, cfg["groupattr"]) + t.Errorf("Default mismatch: groupattr. Expected: '%s', received :'%s'", defaultGroupAttr, cfg["groupattr"]) } defaultUserAttr := "cn" if cfg["userattr"] != defaultUserAttr { - t.Errorf("Default mismatch: userattr. Expected: %q, received :%q", defaultUserAttr, cfg["userattr"]) + t.Errorf("Default mismatch: userattr. Expected: '%s', received :'%s'", defaultUserAttr, cfg["userattr"]) } defaultUserFilter := "({{.UserAttr}}={{.Username}})" if cfg["userfilter"] != defaultUserFilter { - t.Errorf("Default mismatch: userfilter. Expected: %q, received :%q", defaultUserFilter, cfg["userfilter"]) + t.Errorf("Default mismatch: userfilter. Expected: '%s', received :'%s'", defaultUserFilter, cfg["userfilter"]) } defaultDenyNullBind := true if cfg["deny_null_bind"] != defaultDenyNullBind { - t.Errorf("Default mismatch: deny_null_bind. Expected: '%t', received :%q", defaultDenyNullBind, cfg["deny_null_bind"]) + t.Errorf("Default mismatch: deny_null_bind. Expected: '%t', received :'%s'", defaultDenyNullBind, cfg["deny_null_bind"]) } return nil diff --git a/builtin/logical/aws/path_roles.go b/builtin/logical/aws/path_roles.go index a7c3dd84a8967..ca241b5472b68 100644 --- a/builtin/logical/aws/path_roles.go +++ b/builtin/logical/aws/path_roles.go @@ -562,7 +562,7 @@ func (r *awsRoleEntry) validate() error { errors = multierror.Append(errors, fmt.Errorf("user_path parameter only valid for %s credential type", iamUserCred)) } if !userPathRegex.MatchString(r.UserPath) { - errors = multierror.Append(errors, fmt.Errorf("The specified value for user_path is invalid. It must match %q regexp", userPathRegex.String())) + errors = multierror.Append(errors, fmt.Errorf("The specified value for user_path is invalid. It must match '%s' regexp", userPathRegex.String())) } } diff --git a/builtin/logical/aws/path_user.go b/builtin/logical/aws/path_user.go index 035350cdbfb1f..94e4eac286dff 100644 --- a/builtin/logical/aws/path_user.go +++ b/builtin/logical/aws/path_user.go @@ -58,7 +58,7 @@ func (b *backend) pathCredsRead(ctx context.Context, req *logical.Request, d *fr } if role == nil { return logical.ErrorResponse(fmt.Sprintf( - "Role %q not found", roleName)), nil + "Role '%s' not found", roleName)), nil } var ttl int64 diff --git a/builtin/logical/cassandra/path_creds_create.go b/builtin/logical/cassandra/path_creds_create.go index ec100b961317b..a66c4e574e382 100644 --- a/builtin/logical/cassandra/path_creds_create.go +++ b/builtin/logical/cassandra/path_creds_create.go @@ -50,7 +50,7 @@ func (b *backend) pathCredsCreateRead(ctx context.Context, req *logical.Request, return nil, err } username := fmt.Sprintf("vault_%s_%s_%s_%d", name, displayName, userUUID, time.Now().Unix()) - username = strings.ReplaceAll(username, "-", "_") + username = strings.Replace(username, "-", "_", -1) password, err := uuid.GenerateUUID() if err != nil { return nil, err diff --git a/builtin/logical/cassandra/util.go b/builtin/logical/cassandra/util.go index 8257aafd787fb..c0347bc49f5d8 100644 --- a/builtin/logical/cassandra/util.go +++ b/builtin/logical/cassandra/util.go @@ -15,7 +15,7 @@ import ( // Query templates a query for us. func substQuery(tpl string, data map[string]string) string { for k, v := range data { - tpl = strings.ReplaceAll(tpl, fmt.Sprintf("{{%s}}", k), v) + tpl = strings.Replace(tpl, fmt.Sprintf("{{%s}}", k), v, -1) } return tpl diff --git a/builtin/logical/consul/backend_test.go b/builtin/logical/consul/backend_test.go index fa7cf647135a2..531da0f06b8e7 100644 --- a/builtin/logical/consul/backend_test.go +++ b/builtin/logical/consul/backend_test.go @@ -7,7 +7,6 @@ import ( "log" "os" "reflect" - "strings" "testing" "time" @@ -40,7 +39,7 @@ func TestBackend_Config_Access(t *testing.T) { }) } -func testBackendConfigAccess(t *testing.T, version string, autoBootstrap bool) { +func testBackendConfigAccess(t *testing.T, version string, bootstrap bool) { config := logical.TestBackendConfig() config.StorageView = &logical.InmemStorage{} b, err := Factory(context.Background(), config) @@ -48,14 +47,12 @@ func testBackendConfigAccess(t *testing.T, version string, autoBootstrap bool) { t.Fatal(err) } - cleanup, consulConfig := consul.PrepareTestContainer(t, version, false, autoBootstrap) + cleanup, consulConfig := consul.PrepareTestContainer(t, version, false, bootstrap) defer cleanup() connData := map[string]interface{}{ "address": consulConfig.Address(), - } - if autoBootstrap || strings.HasPrefix(version, "1.3") { - connData["token"] = consulConfig.Token + "token": consulConfig.Token, } confReq := &logical.Request{ diff --git a/builtin/logical/database/backend.go b/builtin/logical/database/backend.go index b79093fe3f7f3..cd24943c2db8e 100644 --- a/builtin/logical/database/backend.go +++ b/builtin/logical/database/backend.go @@ -8,12 +8,9 @@ import ( "sync" "time" - "github.com/armon/go-metrics" log "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-secure-stdlib/strutil" "github.com/hashicorp/go-uuid" - "github.com/hashicorp/vault/helper/metricsutil" - "github.com/hashicorp/vault/internalshared/configutil" v4 "github.com/hashicorp/vault/sdk/database/dbplugin" v5 "github.com/hashicorp/vault/sdk/database/dbplugin/v5" "github.com/hashicorp/vault/sdk/database/helper/dbutil" @@ -58,23 +55,13 @@ func Factory(ctx context.Context, conf *logical.BackendConfig) (logical.Backend, } b.credRotationQueue = queue.New() + // Create a context with a cancel method for processing any WAL entries and + // populating the queue + initCtx := context.Background() + ictx, cancel := context.WithCancel(initCtx) + b.cancelQueue = cancel // Load queue and kickoff new periodic ticker - go b.initQueue(b.queueCtx, conf, conf.System.ReplicationState()) - - // collect metrics on number of plugin instances - var err error - b.gaugeCollectionProcess, err = metricsutil.NewGaugeCollectionProcess( - []string{"secrets", "database", "backend", "pluginInstances", "count"}, - []metricsutil.Label{}, - b.collectPluginInstanceGaugeValues, - metrics.Default(), - configutil.UsageGaugeDefaultPeriod, // TODO: add config settings for these, or add plumbing to the main config settings - configutil.MaximumGaugeCardinalityDefault, - b.logger) - if err != nil { - return nil, err - } - go b.gaugeCollectionProcess.Run() + go b.initQueue(ictx, conf, conf.System.ReplicationState()) return b, nil } @@ -116,110 +103,33 @@ func Backend(conf *logical.BackendConfig) *databaseBackend { b.logger = conf.Logger b.connections = make(map[string]*dbPluginInstance) - b.queueCtx, b.cancelQueueCtx = context.WithCancel(context.Background()) + b.roleLocks = locksutil.CreateLocks() - return &b -} -func (b *databaseBackend) collectPluginInstanceGaugeValues(context.Context) ([]metricsutil.GaugeLabelValues, error) { - // copy the map so we can release the lock - connMapCopy := func() map[string]*dbPluginInstance { - b.connLock.RLock() - defer b.connLock.RUnlock() - mapCopy := map[string]*dbPluginInstance{} - for k, v := range b.connections { - mapCopy[k] = v - } - return mapCopy - }() - counts := map[string]int{} - for _, v := range connMapCopy { - dbType, err := v.database.Type() - if err != nil { - // there's a chance this will already be closed since we don't hold the lock - continue - } - if _, ok := counts[dbType]; !ok { - counts[dbType] = 0 - } - counts[dbType] += 1 - } - var gauges []metricsutil.GaugeLabelValues - for k, v := range counts { - gauges = append(gauges, metricsutil.GaugeLabelValues{Labels: []metricsutil.Label{{Name: "dbType", Value: k}}, Value: float32(v)}) - } - return gauges, nil + return &b } type databaseBackend struct { - // connLock is used to synchronize access to the connections map - connLock sync.RWMutex // connections holds configured database connections by config name connections map[string]*dbPluginInstance logger log.Logger *framework.Backend - // credRotationQueue is an in-memory priority queue used to track Static Roles + sync.RWMutex + // CredRotationQueue is an in-memory priority queue used to track Static Roles // that require periodic rotation. Backends will have a PriorityQueue // initialized on setup, but only backends that are mounted by a primary // server or mounted as a local mount will perform the rotations. + // + // cancelQueue is used to remove the priority queue and terminate the + // background ticker. credRotationQueue *queue.PriorityQueue - // queueCtx is the context for the priority queue - queueCtx context.Context - // cancelQueueCtx is used to terminate the background ticker - cancelQueueCtx context.CancelFunc + cancelQueue context.CancelFunc // roleLocks is used to lock modifications to roles in the queue, to ensure // concurrent requests are not modifying the same role and possibly causing // issues with the priority queue. roleLocks []*locksutil.LockEntry - - // the running gauge collection process - gaugeCollectionProcess *metricsutil.GaugeCollectionProcess - gaugeCollectionProcessStop sync.Once -} - -func (b *databaseBackend) connGet(name string) *dbPluginInstance { - b.connLock.RLock() - defer b.connLock.RUnlock() - return b.connections[name] -} - -func (b *databaseBackend) connPop(name string) *dbPluginInstance { - b.connLock.Lock() - defer b.connLock.Unlock() - dbi, ok := b.connections[name] - if ok { - delete(b.connections, name) - } - return dbi -} - -func (b *databaseBackend) connPopIfEqual(name, id string) *dbPluginInstance { - b.connLock.Lock() - defer b.connLock.Unlock() - dbi, ok := b.connections[name] - if ok && dbi.id == id { - delete(b.connections, name) - return dbi - } - return nil -} - -func (b *databaseBackend) connPut(name string, newDbi *dbPluginInstance) *dbPluginInstance { - b.connLock.Lock() - defer b.connLock.Unlock() - dbi := b.connections[name] - b.connections[name] = newDbi - return dbi -} - -func (b *databaseBackend) connClear() map[string]*dbPluginInstance { - b.connLock.Lock() - defer b.connLock.Unlock() - old := b.connections - b.connections = make(map[string]*dbPluginInstance) - return old } func (b *databaseBackend) DatabaseConfig(ctx context.Context, s logical.Storage, name string) (*DatabaseConfig, error) { @@ -326,8 +236,22 @@ func (b *databaseBackend) GetConnection(ctx context.Context, s logical.Storage, } func (b *databaseBackend) GetConnectionWithConfig(ctx context.Context, name string, config *DatabaseConfig) (*dbPluginInstance, error) { - dbi := b.connGet(name) - if dbi != nil { + b.RLock() + unlockFunc := b.RUnlock + defer func() { unlockFunc() }() + + dbi, ok := b.connections[name] + if ok { + return dbi, nil + } + + // Upgrade lock + b.RUnlock() + b.Lock() + unlockFunc = b.Unlock + + dbi, ok = b.connections[name] + if ok { return dbi, nil } @@ -356,34 +280,38 @@ func (b *databaseBackend) GetConnectionWithConfig(ctx context.Context, name stri id: id, name: name, } - oldConn := b.connPut(name, dbi) - if oldConn != nil { - err := oldConn.Close() - if err != nil { - b.Logger().Warn("Error closing database connection", "error", err) - } - } + b.connections[name] = dbi return dbi, nil } +// invalidateQueue cancels any background queue loading and destroys the queue. +func (b *databaseBackend) invalidateQueue() { + // cancel context before grabbing lock to start closing any open connections + // this is safe to do without the lock since it is only written to once in initialization + // and can be canceled multiple times safely + if b.cancelQueue != nil { + b.cancelQueue() + } + b.Lock() + defer b.Unlock() + + b.credRotationQueue = nil +} + // ClearConnection closes the database connection and // removes it from the b.connections map. func (b *databaseBackend) ClearConnection(name string) error { - db := b.connPop(name) - if db != nil { - // Ignore error here since the database client is always killed - db.Close() - } - return nil + b.Lock() + defer b.Unlock() + return b.clearConnection(name) } -// ClearConnectionId closes the database connection with a specific id and -// removes it from the b.connections map. -func (b *databaseBackend) ClearConnectionId(name, id string) error { - db := b.connPopIfEqual(name, id) - if db != nil { +func (b *databaseBackend) clearConnection(name string) error { + db, ok := b.connections[name] + if ok { // Ignore error here since the database client is always killed db.Close() + delete(b.connections, name) } return nil } @@ -396,32 +324,33 @@ func (b *databaseBackend) CloseIfShutdown(db *dbPluginInstance, err error) { // and simply defer the unlock. Since we are attaching the instance and matching // the id in the connection map, we can safely do this. go func() { + b.Lock() + defer b.Unlock() db.Close() - // Delete the connection if it is still active. - b.connPopIfEqual(db.name, db.id) + // Ensure we are deleting the correct connection + mapDB, ok := b.connections[db.name] + if ok && db.id == mapDB.id { + delete(b.connections, db.name) + } }() } } // clean closes all connections from all database types // and cancels any rotation queue loading operation. -func (b *databaseBackend) clean(_ context.Context) { - // kill the queue and terminate the background ticker - if b.cancelQueueCtx != nil { - b.cancelQueueCtx() - } +func (b *databaseBackend) clean(ctx context.Context) { + // invalidateQueue acquires it's own lock on the backend, removes queue, and + // terminates the background ticker + b.invalidateQueue() + + b.Lock() + defer b.Unlock() - connections := b.connClear() - for _, db := range connections { - go db.Close() + for _, db := range b.connections { + db.Close() } - b.gaugeCollectionProcessStop.Do(func() { - if b.gaugeCollectionProcess != nil { - b.gaugeCollectionProcess.Stop() - } - b.gaugeCollectionProcess = nil - }) + b.connections = make(map[string]*dbPluginInstance) } const backendHelp = ` diff --git a/builtin/logical/database/backend_test.go b/builtin/logical/database/backend_test.go index cb56209ccf1c7..cf700c6d71fb0 100644 --- a/builtin/logical/database/backend_test.go +++ b/builtin/logical/database/backend_test.go @@ -711,7 +711,7 @@ func TestBackend_connectionCrud(t *testing.T) { // Replace connection url with templated version req.Operation = logical.UpdateOperation - connURL = strings.ReplaceAll(connURL, "postgres:secret", "{{username}}:{{password}}") + connURL = strings.Replace(connURL, "postgres:secret", "{{username}}:{{password}}", -1) data["connection_url"] = connURL resp, err = b.HandleRequest(namespace.RootContext(nil), req) if err != nil || (resp != nil && resp.IsError()) { @@ -1267,7 +1267,7 @@ func TestBackend_RotateRootCredentials(t *testing.T) { cleanup, connURL := postgreshelper.PrepareTestContainer(t, "13.4-buster") defer cleanup() - connURL = strings.ReplaceAll(connURL, "postgres:secret", "{{username}}:{{password}}") + connURL = strings.Replace(connURL, "postgres:secret", "{{username}}:{{password}}", -1) // Configure a connection data := map[string]interface{}{ @@ -1461,91 +1461,6 @@ func TestBackend_ConnectionURL_redacted(t *testing.T) { } } -type hangingPlugin struct{} - -func (h hangingPlugin) Initialize(_ context.Context, req v5.InitializeRequest) (v5.InitializeResponse, error) { - return v5.InitializeResponse{ - Config: req.Config, - }, nil -} - -func (h hangingPlugin) NewUser(_ context.Context, _ v5.NewUserRequest) (v5.NewUserResponse, error) { - return v5.NewUserResponse{}, nil -} - -func (h hangingPlugin) UpdateUser(_ context.Context, _ v5.UpdateUserRequest) (v5.UpdateUserResponse, error) { - return v5.UpdateUserResponse{}, nil -} - -func (h hangingPlugin) DeleteUser(_ context.Context, _ v5.DeleteUserRequest) (v5.DeleteUserResponse, error) { - return v5.DeleteUserResponse{}, nil -} - -func (h hangingPlugin) Type() (string, error) { - return "hanging", nil -} - -func (h hangingPlugin) Close() error { - time.Sleep(1000 * time.Second) - return nil -} - -var _ v5.Database = (*hangingPlugin)(nil) - -func TestBackend_PluginMain_Hanging(t *testing.T) { - if os.Getenv(pluginutil.PluginVaultVersionEnv) == "" { - return - } - v5.Serve(&hangingPlugin{}) -} - -func TestBackend_AsyncClose(t *testing.T) { - // Test that having a plugin that takes a LONG time to close will not cause the cleanup function to take - // longer than 750ms. - cluster, sys := getCluster(t) - vault.TestAddTestPlugin(t, cluster.Cores[0].Core, "hanging-plugin", consts.PluginTypeDatabase, "TestBackend_PluginMain_Hanging", []string{}, "") - t.Cleanup(cluster.Cleanup) - - config := logical.TestBackendConfig() - config.StorageView = &logical.InmemStorage{} - config.System = sys - - b, err := Factory(context.Background(), config) - if err != nil { - t.Fatal(err) - } - - // Configure a connection - data := map[string]interface{}{ - "connection_url": "doesn't matter", - "plugin_name": "hanging-plugin", - "allowed_roles": []string{"plugin-role-test"}, - } - req := &logical.Request{ - Operation: logical.UpdateOperation, - Path: "config/hang", - Storage: config.StorageView, - Data: data, - } - _, err = b.HandleRequest(namespace.RootContext(nil), req) - if err != nil { - t.Fatalf("err: %v", err) - } - timeout := time.NewTimer(750 * time.Millisecond) - done := make(chan bool) - go func() { - b.Cleanup(context.Background()) - // check that clean can be called twice safely - b.Cleanup(context.Background()) - done <- true - }() - select { - case <-timeout.C: - t.Error("Hanging plugin caused Close() to take longer than 750ms") - case <-done: - } -} - func testCredsExist(t *testing.T, resp *logical.Response, connURL string) bool { t.Helper() var d struct { diff --git a/builtin/logical/database/path_config_connection.go b/builtin/logical/database/path_config_connection.go index cfc61a98b8228..ac5a623d73635 100644 --- a/builtin/logical/database/path_config_connection.go +++ b/builtin/logical/database/path_config_connection.go @@ -344,14 +344,16 @@ func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc { b.Logger().Debug("created database object", "name", name, "plugin_name", config.PluginName) + b.Lock() + defer b.Unlock() + // Close and remove the old connection - oldConn := b.connPut(name, &dbPluginInstance{ + b.clearConnection(name) + + b.connections[name] = &dbPluginInstance{ database: dbw, name: name, id: id, - }) - if oldConn != nil { - oldConn.Close() } err = storeConfig(ctx, req.Storage, name, config) diff --git a/builtin/logical/database/path_rotate_credentials.go b/builtin/logical/database/path_rotate_credentials.go index 4d05393b86acc..2b197d59e780f 100644 --- a/builtin/logical/database/path_rotate_credentials.go +++ b/builtin/logical/database/path_rotate_credentials.go @@ -78,19 +78,22 @@ func (b *databaseBackend) pathRotateRootCredentialsUpdate() framework.OperationF return nil, err } + // Take out the backend lock since we are swapping out the connection + b.Lock() + defer b.Unlock() + // Take the write lock on the instance dbi.Lock() - defer func() { - dbi.Unlock() - // Even on error, still remove the connection - b.ClearConnectionId(name, dbi.id) - }() + defer dbi.Unlock() + defer func() { // Close the plugin dbi.closed = true if err := dbi.database.Close(); err != nil { b.Logger().Error("error closing the database plugin connection", "err", err) } + // Even on error, still remove the connection + delete(b.connections, name) }() generator, err := newPasswordGenerator(nil) diff --git a/builtin/logical/database/rollback_test.go b/builtin/logical/database/rollback_test.go index 7e3fd458b75c5..48e3744cc88cc 100644 --- a/builtin/logical/database/rollback_test.go +++ b/builtin/logical/database/rollback_test.go @@ -44,7 +44,7 @@ func TestBackend_RotateRootCredentials_WAL_rollback(t *testing.T) { cleanup, connURL := postgreshelper.PrepareTestContainer(t, "") defer cleanup() - connURL = strings.ReplaceAll(connURL, "postgres:secret", "{{username}}:{{password}}") + connURL = strings.Replace(connURL, "postgres:secret", "{{username}}:{{password}}", -1) // Configure a connection to the database data := map[string]interface{}{ @@ -183,7 +183,7 @@ func TestBackend_RotateRootCredentials_WAL_no_rollback_1(t *testing.T) { cleanup, connURL := postgreshelper.PrepareTestContainer(t, "") defer cleanup() - connURL = strings.ReplaceAll(connURL, "postgres:secret", "{{username}}:{{password}}") + connURL = strings.Replace(connURL, "postgres:secret", "{{username}}:{{password}}", -1) // Configure a connection to the database data := map[string]interface{}{ @@ -291,7 +291,7 @@ func TestBackend_RotateRootCredentials_WAL_no_rollback_2(t *testing.T) { cleanup, connURL := postgreshelper.PrepareTestContainer(t, "") defer cleanup() - connURL = strings.ReplaceAll(connURL, "postgres:secret", "{{username}}:{{password}}") + connURL = strings.Replace(connURL, "postgres:secret", "{{username}}:{{password}}", -1) // Configure a connection to the database data := map[string]interface{}{ diff --git a/builtin/logical/database/rotation.go b/builtin/logical/database/rotation.go index 0aee4756b178b..53464b361394e 100644 --- a/builtin/logical/database/rotation.go +++ b/builtin/logical/database/rotation.go @@ -642,11 +642,14 @@ func (b *databaseBackend) loadStaticWALs(ctx context.Context, s logical.Storage) // actually available. This is needed because both runTicker and initQueue // operate in go-routines, and could be accessing the queue concurrently func (b *databaseBackend) pushItem(item *queue.Item) error { - select { - case <-b.queueCtx.Done(): - default: + b.RLock() + unlockFunc := b.RUnlock + defer func() { unlockFunc() }() + + if b.credRotationQueue != nil { return b.credRotationQueue.Push(item) } + b.Logger().Warn("no queue found during push item") return nil } @@ -655,9 +658,9 @@ func (b *databaseBackend) pushItem(item *queue.Item) error { // actually available. This is needed because both runTicker and initQueue // operate in go-routines, and could be accessing the queue concurrently func (b *databaseBackend) popFromRotationQueue() (*queue.Item, error) { - select { - case <-b.queueCtx.Done(): - default: + b.RLock() + defer b.RUnlock() + if b.credRotationQueue != nil { return b.credRotationQueue.Pop() } return nil, queue.ErrEmpty @@ -667,9 +670,9 @@ func (b *databaseBackend) popFromRotationQueue() (*queue.Item, error) { // actually available. This is needed because both runTicker and initQueue // operate in go-routines, and could be accessing the queue concurrently func (b *databaseBackend) popFromRotationQueueByKey(name string) (*queue.Item, error) { - select { - case <-b.queueCtx.Done(): - default: + b.RLock() + defer b.RUnlock() + if b.credRotationQueue != nil { item, err := b.credRotationQueue.PopByKey(name) if err != nil { return nil, err diff --git a/builtin/logical/database/rotation_test.go b/builtin/logical/database/rotation_test.go index 9f6e65f9b79ef..863f1a01e3c60 100644 --- a/builtin/logical/database/rotation_test.go +++ b/builtin/logical/database/rotation_test.go @@ -1379,7 +1379,6 @@ func setupMockDB(b *databaseBackend) *mockNewDatabase { mockDB := &mockNewDatabase{} mockDB.On("Initialize", mock.Anything, mock.Anything).Return(v5.InitializeResponse{}, nil) mockDB.On("Close").Return(nil) - mockDB.On("Type").Return("mock", nil) dbw := databaseVersionWrapper{ v5: mockDB, } diff --git a/builtin/logical/database/versioning_large_test.go b/builtin/logical/database/versioning_large_test.go index 0121327367019..723f9dd808def 100644 --- a/builtin/logical/database/versioning_large_test.go +++ b/builtin/logical/database/versioning_large_test.go @@ -290,7 +290,7 @@ func assertStringPrefix(expectedPrefix string) stringAssertion { return func(t *testing.T, str string) { t.Helper() if !strings.HasPrefix(str, expectedPrefix) { - t.Fatalf("Missing prefix %q: Actual: %q", expectedPrefix, str) + t.Fatalf("Missing prefix '%s': Actual: '%s'", expectedPrefix, str) } } } @@ -299,7 +299,7 @@ func assertStringRegex(expectedRegex string) stringAssertion { re := regexp.MustCompile(expectedRegex) return func(t *testing.T, str string) { if !re.MatchString(str) { - t.Fatalf("Actual: %q did not match regexp %q", str, expectedRegex) + t.Fatalf("Actual: '%s' did not match regexp '%s'", str, expectedRegex) } } } diff --git a/builtin/logical/mssql/util.go b/builtin/logical/mssql/util.go index 17c46c6813bb8..362cbd36ad1f9 100644 --- a/builtin/logical/mssql/util.go +++ b/builtin/logical/mssql/util.go @@ -21,7 +21,7 @@ func SplitSQL(sql string) []string { // Query templates a query for us. func Query(tpl string, data map[string]string) string { for k, v := range data { - tpl = strings.ReplaceAll(tpl, fmt.Sprintf("{{%s}}", k), v) + tpl = strings.Replace(tpl, fmt.Sprintf("{{%s}}", k), v, -1) } return tpl diff --git a/builtin/logical/mysql/secret_creds.go b/builtin/logical/mysql/secret_creds.go index 454edbaa927e1..5de5f3c1783af 100644 --- a/builtin/logical/mysql/secret_creds.go +++ b/builtin/logical/mysql/secret_creds.go @@ -18,7 +18,7 @@ const SecretCredsType = "creds" // grants, at least we ensure that the open connection is useless. Dropping the // user will only affect the next connection. const defaultRevocationSQL = ` -REVOKE ALL PRIVILEGES, GRANT OPTION FROM '{{name}}'@'%'; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM '{{name}}'@'%'; DROP USER '{{name}}'@'%' ` @@ -119,7 +119,7 @@ func (b *backend) secretCredsRevoke(ctx context.Context, req *logical.Request, d // This is not a prepared statement because not all commands are supported // 1295: This command is not supported in the prepared statement protocol yet // Reference https://mariadb.com/kb/en/mariadb/prepare-statement/ - query = strings.ReplaceAll(query, "{{name}}", username) + query = strings.Replace(query, "{{name}}", username, -1) _, err = tx.Exec(query) if err != nil { return nil, err diff --git a/builtin/logical/mysql/util.go b/builtin/logical/mysql/util.go index 4ba7c650c208d..313264f905cd9 100644 --- a/builtin/logical/mysql/util.go +++ b/builtin/logical/mysql/util.go @@ -8,7 +8,7 @@ import ( // Query templates a query for us. func Query(tpl string, data map[string]string) string { for k, v := range data { - tpl = strings.ReplaceAll(tpl, fmt.Sprintf("{{%s}}", k), v) + tpl = strings.Replace(tpl, fmt.Sprintf("{{%s}}", k), v, -1) } return tpl diff --git a/builtin/logical/nomad/backend_test.go b/builtin/logical/nomad/backend_test.go index 8452c2b019e41..985ef4c9b09a9 100644 --- a/builtin/logical/nomad/backend_test.go +++ b/builtin/logical/nomad/backend_test.go @@ -184,8 +184,6 @@ func TestBackend_config_Bootstrap(t *testing.T) { expected := map[string]interface{}{ "address": connData["address"].(string), "max_token_name_length": 0, - "ca_cert": "", - "client_cert": "", } if !reflect.DeepEqual(expected, resp.Data) { t.Fatalf("bad: expected:%#v\nactual:%#v\n", expected, resp.Data) @@ -244,59 +242,6 @@ func TestBackend_config_access(t *testing.T) { expected := map[string]interface{}{ "address": connData["address"].(string), "max_token_name_length": 0, - "ca_cert": "", - "client_cert": "", - } - if !reflect.DeepEqual(expected, resp.Data) { - t.Fatalf("bad: expected:%#v\nactual:%#v\n", expected, resp.Data) - } - if resp.Data["token"] != nil { - t.Fatalf("token should not be set in the response") - } -} - -func TestBackend_config_access_with_certs(t *testing.T) { - config := logical.TestBackendConfig() - config.StorageView = &logical.InmemStorage{} - b, err := Factory(context.Background(), config) - if err != nil { - t.Fatal(err) - } - - cleanup, svccfg := prepareTestContainer(t, true) - defer cleanup() - - connData := map[string]interface{}{ - "address": svccfg.URL().String(), - "token": svccfg.Token, - "ca_cert": caCert, - "client_cert": clientCert, - "client_key": clientKey, - } - - confReq := &logical.Request{ - Operation: logical.UpdateOperation, - Path: "config/access", - Storage: config.StorageView, - Data: connData, - } - - resp, err := b.HandleRequest(context.Background(), confReq) - if err != nil || (resp != nil && resp.IsError()) || resp != nil { - t.Fatalf("failed to write configuration: resp:%#v err:%s", resp, err) - } - - confReq.Operation = logical.ReadOperation - resp, err = b.HandleRequest(context.Background(), confReq) - if err != nil || (resp != nil && resp.IsError()) { - t.Fatalf("failed to write configuration: resp:%#v err:%s", resp, err) - } - - expected := map[string]interface{}{ - "address": connData["address"].(string), - "max_token_name_length": 0, - "ca_cert": caCert, - "client_cert": clientCert, } if !reflect.DeepEqual(expected, resp.Data) { t.Fatalf("bad: expected:%#v\nactual:%#v\n", expected, resp.Data) @@ -504,8 +449,6 @@ func TestBackend_max_token_name_length(t *testing.T) { expected := map[string]interface{}{ "address": svccfg.URL().String(), "max_token_name_length": tc.tokenLength, - "ca_cert": "", - "client_cert": "", } expectedMaxTokenNameLength := maxTokenNameLength @@ -610,96 +553,3 @@ func TestBackend_max_token_name_length(t *testing.T) { }) } } - -const caCert = `-----BEGIN CERTIFICATE----- -MIIF7zCCA9egAwIBAgIINVVQic4bju8wDQYJKoZIhvcNAQELBQAwaDELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC1Vuc3BlY2lmaWVkMR8wHQYDVQQLDBZjYS0zODQzMDY2 -NDA5ODI5MjQwNTU5MSIwIAYDVQQDDBl4cHMxNS5sb2NhbC5jaXBoZXJib3kuY29t -MB4XDTIyMDYwMjIxMTgxN1oXDTIzMDcwNTIxMTgxN1owaDELMAkGA1UEBhMCVVMx -FDASBgNVBAoMC1Vuc3BlY2lmaWVkMR8wHQYDVQQLDBZjYS0zODQzMDY2NDA5ODI5 -MjQwNTU5MSIwIAYDVQQDDBl4cHMxNS5sb2NhbC5jaXBoZXJib3kuY29tMIICIjAN -BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA35VilgfqMUKhword7wORXRFyPbpz -8uqO7eRaylMnkAkbk5eoQB/iYfXjJ6ZBs5mJGQVz5ZNvh9EzZsk1J6wqYgbwVKUx -fh4kvW6sXtDirtb4ZQAK7OTLEoapUQGnGcvm+aEYfvC1sTBl4fbex7yyN5FYMJTM -TAUumhdq2pwujaj2xkN9DwZa89Tk7tbj9HE9DTRji7bnciEtrmTAOIOfOrT/1l3x -YW1BwYXpQ0TamJ58pC/iNgEp5FAxKt9d3RggesMA7pvG/f8fNgsa/Tku/PeEXNPA -+Yx4CcAipujmqpBKiKwJ6TOzp80m2zrZ7Da4Av5vVS5GsNJxhFYD1h8hU1ptK9BS -2CaTwBpV421C9BfEmtSAksGDIWYujfiHb6XNaQrt8Hu85GBuPUudVn0lpoXLn2xD -rGK8WEK2gWZ4eez3ZDLbpLui6c1m7AVlMtj374s+LHcD7JIxY475Na7pXmEWReqM -RUyCEq1spOOn70fOdhphhmpY6DoklOTOriPawCLNmkPWRnhrIwqyP1gse9YMqQ2n -LhWUkv/08m/0pb4e5ijVhsZNzv+1PXPWCk968nzt0BMDgJT+0ZiXsaU7FILXuo7Y -Ijgrj7dpXWx2MBdMGPFQdveog7Pa80Yb7r4ERW0DL78TxYC6m/S1p14PHwZpDZzQ -LrPrBcpI5XzI7osCAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAqQwDAYDVR0TBAUw -AwEB/zA0BgNVHR4ELTAroCkwG4IZeHBzMTUubG9jYWwuY2lwaGVyYm95LmNvbTAK -hwh/AAAB/wAAADAkBgNVHREEHTAbghl4cHMxNS5sb2NhbC5jaXBoZXJib3kuY29t -MB0GA1UdDgQWBBR3bHgDp5RpzerMKRkaGDFN/ZeImjANBgkqhkiG9w0BAQsFAAOC -AgEArkuDYYWYHYxIoTeZkQz5L1y0H27ZWPJx5jBBuktPonDLQxBGAwkl6NZbJGLU -v+usII+eyjPKIgjhCiTXJAmeIngwWoN3PHOLMIPe9axuNt6qVoP4dQtzfpPR3buK -CWj9i3H0ixK73klk7QWZiBUDinYfEMSNRpU3G7NsqmqCXD4s5gB+8y9c7+zIiJyN -IaJBWpzI4eQBi/4cBhtM7Xa+CMB/8whhWYR6H+GXGZdNcP5f7bwneMstWKceTadk -IEzFucJHDySpEkIA2A9t33pV54FmEp+JVwvxAH4FABCnjPmhg0j1IonWV5pySWpG -hhEZpnRRH1XfpTA5i6dlyUA5DJjL8X1lYrgOK+LaoR52mQh5JBsMoVHFzN50DiMA -RTsbq4Qzozf23hU1BqW4NOzPTukgSGEcbT/DhXKPPPLL8JD0rPelJPq76X3TJjgZ -C9uMnZaDnxjppDXp5oBIXqC05FDxJ5sSODNOpKGyuzOU2qQLMau33yYOgaSAttBk -r29+LNFJ+0QzMuPjYXPznpxbsI+lrlZ3F2tDGGs8+JVceC1YX+cBEsEOiqNGTIip -/DY3b9gu5oiTwhcFyQW8+WFsirRS/g5t+M40WLKVPdK09z96krFXQMkL6a7LHLY1 -n9ivwj+sTG1XmJYXp8naLg4wdzIUf2fJxaFNI5Yq4elZ8sY= ------END CERTIFICATE-----` - -const clientCert = `-----BEGIN CERTIFICATE----- -MIIEsDCCApigAwIBAgIIRY1JBRIynFYwDQYJKoZIhvcNAQELBQAwaDELMAkGA1UE -BhMCVVMxFDASBgNVBAoMC1Vuc3BlY2lmaWVkMR8wHQYDVQQLDBZjYS0zODQzMDY2 -NDA5ODI5MjQwNTU5MSIwIAYDVQQDDBl4cHMxNS5sb2NhbC5jaXBoZXJib3kuY29t -MB4XDTIyMDYwMjIxMTgxOFoXDTIzMDcwNTIxMTgxOFowRzELMAkGA1UEBhMCVVMx -FDASBgNVBAoMC1Vuc3BlY2lmaWVkMSIwIAYDVQQDDBl4cHMxNS5sb2NhbC5jaXBo -ZXJib3kuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs+XYhsW2 -vTwN7gY3xMxgbNN8d3aoeqCswOp05BBf0Vgv3febahm422ubXXd5Mg2UGiU7sJVe -4tUpDeupVVRX5Qr/hpiXgEyfRDAAAJKqrl65KSS62TCbT/eJZ0ah25HV1evI4uM2 -0kl5QWhtQjDyaVlTS38YFqXXQvpOuU5DG6UbKnpMcpsCPTyUKEJvJ95ZLcz0HJ8I -kIHrnX0Lt0pOhkllj5Nk4cXhU8CFk8IGNz7SVAycrUsffAUMNNEbrIOIfOTPHR1c -q3X9hO4/5pt80uIDMFwwumoA7nQR0AhlKkw9SskCIzJhKwKwssQY7fmovNG0fOEd -/+vSHK7OsYW+gwIDAQABo38wfTAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYI -KwYBBQUHAwIwCQYDVR0TBAIwADAqBgNVHREEIzAhghl4cHMxNS5sb2NhbC5jaXBo -ZXJib3kuY29thwR/AAABMB8GA1UdIwQYMBaAFHdseAOnlGnN6swpGRoYMU39l4ia -MA0GCSqGSIb3DQEBCwUAA4ICAQBUSP4ZJglCCrYkM5Le7McdvfkM5uYv1aQn0sM4 -gbyDEWO0fnv50vLpD3y4ckgHLoD52pAZ0hN8a7rwAUae21GA6DvEchSH5x/yvJiS -7FBlq39sAafe03ZlzDErNYJRkLcnPAqG74lJ1SSsMcs9gCPHM8R7HtNnhAga06L7 -K8/G43dsGZCmEb+xcX2B9McCt8jBG6TJPTGafb3BJ0JTmR/tHdoLFIiNwI+qzd2U -lMnGlkIApULX8tmIMsWO0rjdiFkPWGcmfn9ChC0iDpQOAcKSDBcZlWrDNpzKk0mK -l0TbE6cxcmCUUpiwaXFrbkwVWQw4W0c4b3sWFtWifFbiR1qZ/OT2Y2sHbkbxwvPl -PjjXMDBAdRRwtNcTP1E55I5zvwzzBxUpxOob0miorhTJrZR9So0rgv7Roce4ED6M -WETYa/mGhe+Q7gBQygIVoryfQLgGBsHC+7V4RDvYTazwZkz9nLQxHLI/TAZU5ofM -WqdoUkMd68rxTTEUoMfGbftxjKA0raxGcO7/PjLR3O743EwCqeqYJ7OKWgGRLnui -kIKNUJlZ9umURUFzL++Bx4Pr95jWXb2WYqYYQxhDz0oR5q5smnFm5+/1/MLDMvDU -TrgBK6pey4QF33B/I55H1+7tGdv85Q57Z8UrNi/IQxR2sFlsOTeCwStpBQ56sdZk -Wi4+cQ== ------END CERTIFICATE-----` - -const clientKey = `-----BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCz5diGxba9PA3u -BjfEzGBs03x3dqh6oKzA6nTkEF/RWC/d95tqGbjba5tdd3kyDZQaJTuwlV7i1SkN -66lVVFflCv+GmJeATJ9EMAAAkqquXrkpJLrZMJtP94lnRqHbkdXV68ji4zbSSXlB -aG1CMPJpWVNLfxgWpddC+k65TkMbpRsqekxymwI9PJQoQm8n3lktzPQcnwiQgeud -fQu3Sk6GSWWPk2ThxeFTwIWTwgY3PtJUDJytSx98BQw00Rusg4h85M8dHVyrdf2E -7j/mm3zS4gMwXDC6agDudBHQCGUqTD1KyQIjMmErArCyxBjt+ai80bR84R3/69Ic -rs6xhb6DAgMBAAECggEAPBcja2kxcCZWNNKo4DiwYMmHwtPE1SlEazAlmWSKzP+b -BZbGt/sdj1VzURYuSnTUqqMTPBm41yYCj57PMix5K42v6sKfoIB3lqw94/MZxiLn -0IFvVErzJhP2NqQWPqSI++rFcFwbHMTkFuAN1tVIs73dn9M1NaNxsvKvRyCIM/wz -5YQSDyTkdW4jQM2RvUFOoqwmeyAlQoBRMgQ4bHfLHxmPEjFgw1MAmmG8bJdkupin -MVzhZyKj4Fh80Xa2MU4KokijjG41hmYbg/sjNHaHJFDA92Rwq13dhWytrauJDxa/ -3yj8pHWc23Y3hXvRAf/cibDVzXmmLj49W1i06KuUCQKBgQDj5yF/DJV0IOkhfbol -+f5AGH4ZrEXA/JwA5SxHU+aKhUuPEqK/LeUWqiy3szFjOz2JOnCC0LMN42nsmMyK -sdQEKHp2SPd2wCxsAKZAuxrEi6yBt1mEPFFU5yzvZbdMqYChKJjm9fbRHtuc63s8 -PyVw67Ii9o4ij+PxfTobIs18xwKBgQDKE59w3uUDt2uoqNC8x4m5onL2p2vtcTHC -CxU57mu1+9CRM8N2BEp2VI5JaXjqt6W4u9ISrmOqmsPgTwosAquKpA/nu3bVvR9g -WlN9dh2Xgza0/AFaA9CB++ier8RJq5xFlcasMUmgkhYt3zgKNgRDfjfREWM0yamm -P++hAYRcZQKBgHEuYQk6k6J3ka/rQ54GmEj2oPFZB88+5K7hIWtO9IhIiGzGYYK2 -ZTYrT0fvuxA/5GCZYDTnNnUoQnuYqsQaamOiQqcpt5QG/kiozegJw9JmV0aYauFs -HyweHsfJaQ2uhE4E3mKdNnVGcORuYeZaqdp5gx8v+QibEyXj/g5p60kTAoGBALKp -TMOHXmW9yqKwtvThWoRU+13WQlcJSFvuXpL8mCCrBgkLAhqaypb6RV7ksLKdMhk1 -fhNkOdxBv0LXvv+QUMhgK2vP084/yrjuw3hecOVfboPvduZ2DuiNp2p9rocQAjeH -p8LgRN+Bqbhe7fYhMf3WX1UqEVM/pQ3G43+vjq39AoGAOyD2/hFSIx6BMddUNTHG -BEsMUc/DHYslZebbF1zAWnkKdTt+URhtHAFB2tYRDgkZfwW+wr/w12dJTIkX965o -HO7tI4FgpU9b0i8FTuwYkBfjwp2j0Xd2/VBR8Qpd17qKl3I6NXDsf3ykjGZAvldH -Tll+qwEZpXSRa5OWWTpGV8I= ------END PRIVATE KEY-----` diff --git a/builtin/logical/nomad/path_config_access.go b/builtin/logical/nomad/path_config_access.go index b482a9c1aca86..d834b0b19de36 100644 --- a/builtin/logical/nomad/path_config_access.go +++ b/builtin/logical/nomad/path_config_access.go @@ -95,8 +95,6 @@ func (b *backend) pathConfigAccessRead(ctx context.Context, req *logical.Request Data: map[string]interface{}{ "address": conf.Address, "max_token_name_length": conf.MaxTokenNameLength, - "ca_cert": conf.CACert, - "client_cert": conf.ClientCert, }, }, nil } diff --git a/builtin/logical/pki/backend_test.go b/builtin/logical/pki/backend_test.go index db365a4f89d76..5d3373855f440 100644 --- a/builtin/logical/pki/backend_test.go +++ b/builtin/logical/pki/backend_test.go @@ -12,7 +12,6 @@ import ( "crypto/x509" "crypto/x509/pkix" "encoding/base64" - "encoding/hex" "encoding/json" "encoding/pem" "fmt" @@ -102,7 +101,6 @@ OzQeADTSCn5VidOfjDkIst9UXjMlrFfV9/oJEw5Eiqa6lkNPCGDhfA8= ) func TestPKI_RequireCN(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) resp, err := CBWrite(b, s, "root/generate/internal", map[string]interface{}{ @@ -178,7 +176,6 @@ func TestPKI_RequireCN(t *testing.T) { } func TestPKI_DeviceCert(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) resp, err := CBWrite(b, s, "root/generate/internal", map[string]interface{}{ @@ -247,7 +244,6 @@ func TestPKI_DeviceCert(t *testing.T) { } func TestBackend_InvalidParameter(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) _, err := CBWrite(b, s, "root/generate/internal", map[string]interface{}{ @@ -269,7 +265,6 @@ func TestBackend_InvalidParameter(t *testing.T) { } func TestBackend_CSRValues(t *testing.T) { - t.Parallel() initTest.Do(setCerts) b, _ := createBackendWithStorage(t) @@ -286,7 +281,6 @@ func TestBackend_CSRValues(t *testing.T) { } func TestBackend_URLsCRUD(t *testing.T) { - t.Parallel() initTest.Do(setCerts) b, _ := createBackendWithStorage(t) @@ -305,7 +299,6 @@ func TestBackend_URLsCRUD(t *testing.T) { // Generates and tests steps that walk through the various possibilities // of role flags to ensure that they are properly restricted func TestBackend_Roles(t *testing.T) { - t.Parallel() cases := []struct { name string key, cert *string @@ -581,11 +574,8 @@ func generateURLSteps(t *testing.T, caCert, caKey string, intdata, reqdata map[s Data: map[string]interface{}{ "common_name": "intermediate.cert.com", "csr": csrPem2048, - "signature_bits": 512, "format": "der", "not_before_duration": "2h", - // Let's Encrypt -- R3 SKID - "skid": "14:2E:B3:17:B7:58:56:CB:AE:50:09:40:E6:1F:AF:9D:8B:14:C2:C6", }, Check: func(resp *logical.Response) error { certString := resp.Data["certificate"].(string) @@ -605,21 +595,15 @@ func generateURLSteps(t *testing.T, caCert, caKey string, intdata, reqdata map[s } cert := certs[0] - skid, _ := hex.DecodeString("142EB317B75856CBAE500940E61FAF9D8B14C2C6") - switch { case !reflect.DeepEqual(expected.IssuingCertificates, cert.IssuingCertificateURL): - return fmt.Errorf("IssuingCertificateURL:\nexpected\n%#v\ngot\n%#v\n", expected.IssuingCertificates, cert.IssuingCertificateURL) + return fmt.Errorf("expected\n%#v\ngot\n%#v\n", expected.IssuingCertificates, cert.IssuingCertificateURL) case !reflect.DeepEqual(expected.CRLDistributionPoints, cert.CRLDistributionPoints): - return fmt.Errorf("CRLDistributionPoints:\nexpected\n%#v\ngot\n%#v\n", expected.CRLDistributionPoints, cert.CRLDistributionPoints) + return fmt.Errorf("expected\n%#v\ngot\n%#v\n", expected.CRLDistributionPoints, cert.CRLDistributionPoints) case !reflect.DeepEqual(expected.OCSPServers, cert.OCSPServer): - return fmt.Errorf("OCSPServer:\nexpected\n%#v\ngot\n%#v\n", expected.OCSPServers, cert.OCSPServer) + return fmt.Errorf("expected\n%#v\ngot\n%#v\n", expected.OCSPServers, cert.OCSPServer) case !reflect.DeepEqual([]string{"intermediate.cert.com"}, cert.DNSNames): - return fmt.Errorf("DNSNames\nexpected\n%#v\ngot\n%#v\n", []string{"intermediate.cert.com"}, cert.DNSNames) - case !reflect.DeepEqual(x509.SHA512WithRSA, cert.SignatureAlgorithm): - return fmt.Errorf("Signature Algorithm:\nexpected\n%#v\ngot\n%#v\n", x509.SHA512WithRSA, cert.SignatureAlgorithm) - case !reflect.DeepEqual(skid, cert.SubjectKeyId): - return fmt.Errorf("SKID:\nexpected\n%#v\ngot\n%#v\n", skid, cert.SubjectKeyId) + return fmt.Errorf("expected\n%#v\ngot\n%#v\n", []string{"intermediate.cert.com"}, cert.DNSNames) } if math.Abs(float64(time.Now().Add(-2*time.Hour).Unix()-cert.NotBefore.Unix())) > 10 { @@ -1728,7 +1712,6 @@ func generateRoleSteps(t *testing.T, useCSRs bool) []logicaltest.TestStep { } func TestRolesAltIssuer(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) // Create two issuers. @@ -1826,7 +1809,6 @@ func TestRolesAltIssuer(t *testing.T) { } func TestBackend_PathFetchValidRaw(t *testing.T) { - t.Parallel() b, storage := createBackendWithStorage(t) resp, err := b.HandleRequest(context.Background(), &logical.Request{ @@ -1957,7 +1939,6 @@ func TestBackend_PathFetchValidRaw(t *testing.T) { } func TestBackend_PathFetchCertList(t *testing.T) { - t.Parallel() // create the backend b, storage := createBackendWithStorage(t) @@ -2083,7 +2064,6 @@ func TestBackend_PathFetchCertList(t *testing.T) { } func TestBackend_SignVerbatim(t *testing.T) { - t.Parallel() testCases := []struct { testName string keyType string @@ -2094,7 +2074,6 @@ func TestBackend_SignVerbatim(t *testing.T) { {testName: "Any", keyType: "any"}, } for _, tc := range testCases { - tc := tc t.Run(tc.testName, func(t *testing.T) { runTestSignVerbatim(t, tc.keyType) }) @@ -2150,17 +2129,13 @@ func runTestSignVerbatim(t *testing.T, keyType string) { t.Fatal("pem csr is empty") } - signVerbatimData := map[string]interface{}{ - "csr": pemCSR, - } - if keyType == "rsa" { - signVerbatimData["signature_bits"] = 512 - } resp, err = b.HandleRequest(context.Background(), &logical.Request{ - Operation: logical.UpdateOperation, - Path: "sign-verbatim", - Storage: storage, - Data: signVerbatimData, + Operation: logical.UpdateOperation, + Path: "sign-verbatim", + Storage: storage, + Data: map[string]interface{}{ + "csr": pemCSR, + }, MountPoint: "pki/", }) if resp != nil && resp.IsError() { @@ -2334,7 +2309,6 @@ func runTestSignVerbatim(t *testing.T, keyType string) { } func TestBackend_Root_Idempotency(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) // This is a change within 1.11, we are no longer idempotent across generate/internal calls. @@ -2439,7 +2413,6 @@ func TestBackend_Root_Idempotency(t *testing.T) { } func TestBackend_SignIntermediate_AllowedPastCA(t *testing.T) { - t.Parallel() b_root, s_root := createBackendWithStorage(t) b_int, s_int := createBackendWithStorage(t) var err error @@ -2507,7 +2480,6 @@ func TestBackend_SignIntermediate_AllowedPastCA(t *testing.T) { } func TestBackend_ConsulSignLeafWithLegacyRole(t *testing.T) { - t.Parallel() // create the backend b, s := createBackendWithStorage(t) @@ -2542,7 +2514,6 @@ func TestBackend_ConsulSignLeafWithLegacyRole(t *testing.T) { } func TestBackend_SignSelfIssued(t *testing.T) { - t.Parallel() // create the backend b, storage := createBackendWithStorage(t) @@ -2658,8 +2629,7 @@ func TestBackend_SignSelfIssued(t *testing.T) { t.Fatal(err) } - sc := b.makeStorageContext(context.Background(), storage) - signingBundle, err := sc.fetchCAInfo(defaultRef, ReadOnlyUsage) + signingBundle, err := fetchCAInfo(context.Background(), b, &logical.Request{Storage: storage}, defaultRef, ReadOnlyUsage) if err != nil { t.Fatal(err) } @@ -2683,7 +2653,6 @@ func TestBackend_SignSelfIssued(t *testing.T) { // TestBackend_SignSelfIssued_DifferentTypes tests the functionality of the // require_matching_certificate_algorithms flag. func TestBackend_SignSelfIssued_DifferentTypes(t *testing.T) { - t.Parallel() // create the backend b, storage := createBackendWithStorage(t) @@ -2809,7 +2778,6 @@ func TestBackend_SignSelfIssued_DifferentTypes(t *testing.T) { // here into the form at that site as it will do the right thing so it's pretty // easy to validate. func TestBackend_OID_SANs(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) var err error @@ -3032,7 +3000,6 @@ func TestBackend_OID_SANs(t *testing.T) { } func TestBackend_AllowedSerialNumbers(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) var err error @@ -3139,7 +3106,6 @@ func TestBackend_AllowedSerialNumbers(t *testing.T) { } func TestBackend_URI_SANs(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) var err error @@ -3233,7 +3199,6 @@ func TestBackend_URI_SANs(t *testing.T) { } func TestBackend_AllowedURISANsTemplate(t *testing.T) { - t.Parallel() coreConfig := &vault.CoreConfig{ CredentialBackends: map[string]logical.Factory{ "userpass": userpass.Factory, @@ -3358,7 +3323,6 @@ func TestBackend_AllowedURISANsTemplate(t *testing.T) { } func TestBackend_AllowedDomainsTemplate(t *testing.T) { - t.Parallel() coreConfig := &vault.CoreConfig{ CredentialBackends: map[string]logical.Factory{ "userpass": userpass.Factory, @@ -3490,7 +3454,6 @@ func TestBackend_AllowedDomainsTemplate(t *testing.T) { } func TestReadWriteDeleteRoles(t *testing.T) { - t.Parallel() ctx := context.Background() coreConfig := &vault.CoreConfig{ CredentialBackends: map[string]logical.Factory{ @@ -3552,7 +3515,6 @@ func TestReadWriteDeleteRoles(t *testing.T) { "allowed_serial_numbers": []interface{}{}, "generate_lease": false, "signature_bits": json.Number("256"), - "use_pss": false, "allowed_domains": []interface{}{}, "allowed_uri_sans_template": false, "enforce_hostnames": true, @@ -3591,7 +3553,6 @@ func TestReadWriteDeleteRoles(t *testing.T) { "street_address": []interface{}{}, "code_signing_flag": false, "issuer_ref": "default", - "cn_validations": []interface{}{"email", "hostname"}, } if diff := deep.Equal(expectedData, resp.Data); len(diff) > 0 { @@ -3719,8 +3680,6 @@ func TestBackend_RevokePlusTidy_Intermediate(t *testing.T) { // that we have to deal with more than one interval. // InMemSink rounds down to an interval boundary rather than // starting one at the time of initialization. - // - // This test is not parallelizable. inmemSink := metrics.NewInmemSink( 1000000*time.Hour, 2000000*time.Hour) @@ -3960,7 +3919,6 @@ func TestBackend_RevokePlusTidy_Intermediate(t *testing.T) { } func TestBackend_Root_FullCAChain(t *testing.T) { - t.Parallel() testCases := []struct { testName string keyType string @@ -3970,7 +3928,6 @@ func TestBackend_Root_FullCAChain(t *testing.T) { {testName: "EC", keyType: "ec"}, } for _, tc := range testCases { - tc := tc t.Run(tc.testName, func(t *testing.T) { runFullCAChainTest(t, tc.keyType) }) @@ -4200,7 +4157,6 @@ type IssuanceRegression struct { AllowSubdomains MultiBool AllowLocalhost MultiBool AllowWildcardCertificates MultiBool - CNValidations []string CommonName string Issued bool } @@ -4220,23 +4176,18 @@ func RoleIssuanceRegressionHelper(t *testing.T, b *backend, s logical.Storage, i "allow_subdomains": AllowSubdomains, "allow_localhost": AllowLocalhost, "allow_wildcard_certificates": AllowWildcardCertificates, - "cn_validations": test.CNValidations, // TODO: test across this vector as well. Currently certain wildcard // matching is broken with it enabled (such as x*x.foo). "enforce_hostnames": false, "key_type": "ec", "key_bits": 256, - "no_store": true, - // With the CN Validations field, ensure we prevent CN from appearing - // in SANs. }) if err != nil { t.Fatal(err) } resp, err = CBWrite(b, s, "issue/"+role, map[string]interface{}{ - "common_name": test.CommonName, - "exclude_cn_from_sans": true, + "common_name": test.CommonName, }) haveErr := err != nil || resp == nil @@ -4257,7 +4208,6 @@ func RoleIssuanceRegressionHelper(t *testing.T, b *backend, s logical.Storage, i } func TestBackend_Roles_IssuanceRegression(t *testing.T) { - t.Parallel() // Regression testing of role's issuance policy. testCases := []IssuanceRegression{ // allowed, bare, glob, subdomains, localhost, wildcards, cn, issued @@ -4266,166 +4216,149 @@ func TestBackend_Roles_IssuanceRegression(t *testing.T) { // Allowed contains globs, but globbing not allowed, resulting in all // issuances failing. Note that tests against issuing a wildcard with // a bare domain will be covered later. - /* 0 */ {[]string{"*.*.foo"}, MAny, MFalse, MAny, MAny, MAny, nil, "baz.fud.bar.foo", false}, - /* 1 */ {[]string{"*.*.foo"}, MAny, MFalse, MAny, MAny, MAny, nil, "*.fud.bar.foo", false}, - /* 2 */ {[]string{"*.*.foo"}, MAny, MFalse, MAny, MAny, MAny, nil, "fud.bar.foo", false}, - /* 3 */ {[]string{"*.*.foo"}, MAny, MFalse, MAny, MAny, MAny, nil, "*.bar.foo", false}, - /* 4 */ {[]string{"*.*.foo"}, MAny, MFalse, MAny, MAny, MAny, nil, "bar.foo", false}, - /* 5 */ {[]string{"*.*.foo"}, MAny, MFalse, MAny, MAny, MAny, nil, "*.foo", false}, - /* 6 */ {[]string{"*.foo"}, MAny, MFalse, MAny, MAny, MAny, nil, "foo", false}, - /* 7 */ {[]string{"*.foo"}, MAny, MFalse, MAny, MAny, MAny, nil, "baz.fud.bar.foo", false}, - /* 8 */ {[]string{"*.foo"}, MAny, MFalse, MAny, MAny, MAny, nil, "*.fud.bar.foo", false}, - /* 9 */ {[]string{"*.foo"}, MAny, MFalse, MAny, MAny, MAny, nil, "fud.bar.foo", false}, - /* 10 */ {[]string{"*.foo"}, MAny, MFalse, MAny, MAny, MAny, nil, "*.bar.foo", false}, - /* 11 */ {[]string{"*.foo"}, MAny, MFalse, MAny, MAny, MAny, nil, "bar.foo", false}, - /* 12 */ {[]string{"*.foo"}, MAny, MFalse, MAny, MAny, MAny, nil, "foo", false}, + /* 0 */ {[]string{"*.*.foo"}, MAny, MFalse, MAny, MAny, MAny, "baz.fud.bar.foo", false}, + /* 1 */ {[]string{"*.*.foo"}, MAny, MFalse, MAny, MAny, MAny, "*.fud.bar.foo", false}, + /* 2 */ {[]string{"*.*.foo"}, MAny, MFalse, MAny, MAny, MAny, "fud.bar.foo", false}, + /* 3 */ {[]string{"*.*.foo"}, MAny, MFalse, MAny, MAny, MAny, "*.bar.foo", false}, + /* 4 */ {[]string{"*.*.foo"}, MAny, MFalse, MAny, MAny, MAny, "bar.foo", false}, + /* 5 */ {[]string{"*.*.foo"}, MAny, MFalse, MAny, MAny, MAny, "*.foo", false}, + /* 6 */ {[]string{"*.foo"}, MAny, MFalse, MAny, MAny, MAny, "foo", false}, + /* 7 */ {[]string{"*.foo"}, MAny, MFalse, MAny, MAny, MAny, "baz.fud.bar.foo", false}, + /* 8 */ {[]string{"*.foo"}, MAny, MFalse, MAny, MAny, MAny, "*.fud.bar.foo", false}, + /* 9 */ {[]string{"*.foo"}, MAny, MFalse, MAny, MAny, MAny, "fud.bar.foo", false}, + /* 10 */ {[]string{"*.foo"}, MAny, MFalse, MAny, MAny, MAny, "*.bar.foo", false}, + /* 11 */ {[]string{"*.foo"}, MAny, MFalse, MAny, MAny, MAny, "bar.foo", false}, + /* 12 */ {[]string{"*.foo"}, MAny, MFalse, MAny, MAny, MAny, "foo", false}, // === Localhost sanity === // // Localhost forbidden, not matching allowed domains -> not issued - /* 13 */ {[]string{"*.*.foo"}, MAny, MAny, MAny, MFalse, MAny, nil, "localhost", false}, + /* 13 */ {[]string{"*.*.foo"}, MAny, MAny, MAny, MFalse, MAny, "localhost", false}, // Localhost allowed, not matching allowed domains -> issued - /* 14 */ {[]string{"*.*.foo"}, MAny, MAny, MAny, MTrue, MAny, nil, "localhost", true}, + /* 14 */ {[]string{"*.*.foo"}, MAny, MAny, MAny, MTrue, MAny, "localhost", true}, // Localhost allowed via allowed domains (and bare allowed), not by AllowLocalhost -> issued - /* 15 */ {[]string{"localhost"}, MTrue, MAny, MAny, MFalse, MAny, nil, "localhost", true}, + /* 15 */ {[]string{"localhost"}, MTrue, MAny, MAny, MFalse, MAny, "localhost", true}, // Localhost allowed via allowed domains (and bare not allowed), not by AllowLocalhost -> not issued - /* 16 */ {[]string{"localhost"}, MFalse, MAny, MAny, MFalse, MAny, nil, "localhost", false}, + /* 16 */ {[]string{"localhost"}, MFalse, MAny, MAny, MFalse, MAny, "localhost", false}, // Localhost allowed via allowed domains (but bare not allowed), and by AllowLocalhost -> issued - /* 17 */ {[]string{"localhost"}, MFalse, MAny, MAny, MTrue, MAny, nil, "localhost", true}, + /* 17 */ {[]string{"localhost"}, MFalse, MAny, MAny, MTrue, MAny, "localhost", true}, // === Bare wildcard issuance == // // allowed_domains contains one or more wildcards and bare domains allowed, // resulting in the cert being issued. - /* 18 */ {[]string{"*.foo"}, MTrue, MAny, MAny, MAny, MTrue, nil, "*.foo", true}, - /* 19 */ {[]string{"*.*.foo"}, MTrue, MAny, MAny, MAny, MAny, nil, "*.*.foo", false}, // Does not conform to RFC 6125 + /* 18 */ {[]string{"*.foo"}, MTrue, MAny, MAny, MAny, MTrue, "*.foo", true}, + /* 19 */ {[]string{"*.*.foo"}, MTrue, MAny, MAny, MAny, MAny, "*.*.foo", false}, // Does not conform to RFC 6125 // === Double Leading Glob Testing === // // Allowed contains globs, but glob allowed so certain matches work. // The value of bare and localhost does not impact these results. - /* 20 */ {[]string{"*.*.foo"}, MAny, MTrue, MFalse, MAny, MAny, nil, "baz.fud.bar.foo", true}, // glob domains allow infinite subdomains - /* 21 */ {[]string{"*.*.foo"}, MAny, MTrue, MFalse, MAny, MTrue, nil, "*.fud.bar.foo", true}, // glob domain allows wildcard of subdomains - /* 22 */ {[]string{"*.*.foo"}, MAny, MTrue, MFalse, MAny, MAny, nil, "fud.bar.foo", true}, - /* 23 */ {[]string{"*.*.foo"}, MAny, MTrue, MFalse, MAny, MTrue, nil, "*.bar.foo", true}, // Regression fix: Vault#13530 - /* 24 */ {[]string{"*.*.foo"}, MAny, MTrue, MFalse, MAny, MAny, nil, "bar.foo", false}, - /* 25 */ {[]string{"*.*.foo"}, MAny, MTrue, MFalse, MAny, MAny, nil, "*.foo", false}, - /* 26 */ {[]string{"*.*.foo"}, MAny, MTrue, MFalse, MAny, MAny, nil, "foo", false}, + /* 20 */ {[]string{"*.*.foo"}, MAny, MTrue, MFalse, MAny, MAny, "baz.fud.bar.foo", true}, // glob domains allow infinite subdomains + /* 21 */ {[]string{"*.*.foo"}, MAny, MTrue, MFalse, MAny, MTrue, "*.fud.bar.foo", true}, // glob domain allows wildcard of subdomains + /* 22 */ {[]string{"*.*.foo"}, MAny, MTrue, MFalse, MAny, MAny, "fud.bar.foo", true}, + /* 23 */ {[]string{"*.*.foo"}, MAny, MTrue, MFalse, MAny, MTrue, "*.bar.foo", true}, // Regression fix: Vault#13530 + /* 24 */ {[]string{"*.*.foo"}, MAny, MTrue, MFalse, MAny, MAny, "bar.foo", false}, + /* 25 */ {[]string{"*.*.foo"}, MAny, MTrue, MFalse, MAny, MAny, "*.foo", false}, + /* 26 */ {[]string{"*.*.foo"}, MAny, MTrue, MFalse, MAny, MAny, "foo", false}, // Allowed contains globs, but glob and subdomain both work, so we expect // wildcard issuance to work as well. The value of bare and localhost does // not impact these results. - /* 27 */ {[]string{"*.*.foo"}, MAny, MTrue, MTrue, MAny, MAny, nil, "baz.fud.bar.foo", true}, - /* 28 */ {[]string{"*.*.foo"}, MAny, MTrue, MTrue, MAny, MTrue, nil, "*.fud.bar.foo", true}, - /* 29 */ {[]string{"*.*.foo"}, MAny, MTrue, MTrue, MAny, MAny, nil, "fud.bar.foo", true}, - /* 30 */ {[]string{"*.*.foo"}, MAny, MTrue, MTrue, MAny, MTrue, nil, "*.bar.foo", true}, // Regression fix: Vault#13530 - /* 31 */ {[]string{"*.*.foo"}, MAny, MTrue, MTrue, MAny, MAny, nil, "bar.foo", false}, - /* 32 */ {[]string{"*.*.foo"}, MAny, MTrue, MTrue, MAny, MAny, nil, "*.foo", false}, - /* 33 */ {[]string{"*.*.foo"}, MAny, MTrue, MTrue, MAny, MAny, nil, "foo", false}, + /* 27 */ {[]string{"*.*.foo"}, MAny, MTrue, MTrue, MAny, MAny, "baz.fud.bar.foo", true}, + /* 28 */ {[]string{"*.*.foo"}, MAny, MTrue, MTrue, MAny, MTrue, "*.fud.bar.foo", true}, + /* 29 */ {[]string{"*.*.foo"}, MAny, MTrue, MTrue, MAny, MAny, "fud.bar.foo", true}, + /* 30 */ {[]string{"*.*.foo"}, MAny, MTrue, MTrue, MAny, MTrue, "*.bar.foo", true}, // Regression fix: Vault#13530 + /* 31 */ {[]string{"*.*.foo"}, MAny, MTrue, MTrue, MAny, MAny, "bar.foo", false}, + /* 32 */ {[]string{"*.*.foo"}, MAny, MTrue, MTrue, MAny, MAny, "*.foo", false}, + /* 33 */ {[]string{"*.*.foo"}, MAny, MTrue, MTrue, MAny, MAny, "foo", false}, // === Single Leading Glob Testing === // // Allowed contains globs, but glob allowed so certain matches work. // The value of bare and localhost does not impact these results. - /* 34 */ {[]string{"*.foo"}, MAny, MTrue, MFalse, MAny, MAny, nil, "baz.fud.bar.foo", true}, // glob domains allow infinite subdomains - /* 35 */ {[]string{"*.foo"}, MAny, MTrue, MFalse, MAny, MTrue, nil, "*.fud.bar.foo", true}, // glob domain allows wildcard of subdomains - /* 36 */ {[]string{"*.foo"}, MAny, MTrue, MFalse, MAny, MAny, nil, "fud.bar.foo", true}, // glob domains allow infinite subdomains - /* 37 */ {[]string{"*.foo"}, MAny, MTrue, MFalse, MAny, MTrue, nil, "*.bar.foo", true}, // glob domain allows wildcards of subdomains - /* 38 */ {[]string{"*.foo"}, MAny, MTrue, MFalse, MAny, MAny, nil, "bar.foo", true}, - /* 39 */ {[]string{"*.foo"}, MAny, MTrue, MFalse, MAny, MAny, nil, "foo", false}, + /* 34 */ {[]string{"*.foo"}, MAny, MTrue, MFalse, MAny, MAny, "baz.fud.bar.foo", true}, // glob domains allow infinite subdomains + /* 35 */ {[]string{"*.foo"}, MAny, MTrue, MFalse, MAny, MTrue, "*.fud.bar.foo", true}, // glob domain allows wildcard of subdomains + /* 36 */ {[]string{"*.foo"}, MAny, MTrue, MFalse, MAny, MAny, "fud.bar.foo", true}, // glob domains allow infinite subdomains + /* 37 */ {[]string{"*.foo"}, MAny, MTrue, MFalse, MAny, MTrue, "*.bar.foo", true}, // glob domain allows wildcards of subdomains + /* 38 */ {[]string{"*.foo"}, MAny, MTrue, MFalse, MAny, MAny, "bar.foo", true}, + /* 39 */ {[]string{"*.foo"}, MAny, MTrue, MFalse, MAny, MAny, "foo", false}, // Allowed contains globs, but glob and subdomain both work, so we expect // wildcard issuance to work as well. The value of bare and localhost does // not impact these results. - /* 40 */ {[]string{"*.foo"}, MAny, MTrue, MTrue, MAny, MAny, nil, "baz.fud.bar.foo", true}, - /* 41 */ {[]string{"*.foo"}, MAny, MTrue, MTrue, MAny, MTrue, nil, "*.fud.bar.foo", true}, - /* 42 */ {[]string{"*.foo"}, MAny, MTrue, MTrue, MAny, MAny, nil, "fud.bar.foo", true}, - /* 43 */ {[]string{"*.foo"}, MAny, MTrue, MTrue, MAny, MTrue, nil, "*.bar.foo", true}, - /* 44 */ {[]string{"*.foo"}, MAny, MTrue, MTrue, MAny, MAny, nil, "bar.foo", true}, - /* 45 */ {[]string{"*.foo"}, MAny, MTrue, MTrue, MAny, MAny, nil, "foo", false}, + /* 40 */ {[]string{"*.foo"}, MAny, MTrue, MTrue, MAny, MAny, "baz.fud.bar.foo", true}, + /* 41 */ {[]string{"*.foo"}, MAny, MTrue, MTrue, MAny, MTrue, "*.fud.bar.foo", true}, + /* 42 */ {[]string{"*.foo"}, MAny, MTrue, MTrue, MAny, MAny, "fud.bar.foo", true}, + /* 43 */ {[]string{"*.foo"}, MAny, MTrue, MTrue, MAny, MTrue, "*.bar.foo", true}, + /* 44 */ {[]string{"*.foo"}, MAny, MTrue, MTrue, MAny, MAny, "bar.foo", true}, + /* 45 */ {[]string{"*.foo"}, MAny, MTrue, MTrue, MAny, MAny, "foo", false}, // === Only base domain name === // // Allowed contains only domain components, but subdomains not allowed. This // results in most issuances failing unless we allow bare domains, in which // case only the final issuance for "foo" will succeed. - /* 46 */ {[]string{"foo"}, MAny, MAny, MFalse, MAny, MAny, nil, "baz.fud.bar.foo", false}, - /* 47 */ {[]string{"foo"}, MAny, MAny, MFalse, MAny, MAny, nil, "*.fud.bar.foo", false}, - /* 48 */ {[]string{"foo"}, MAny, MAny, MFalse, MAny, MAny, nil, "fud.bar.foo", false}, - /* 49 */ {[]string{"foo"}, MAny, MAny, MFalse, MAny, MAny, nil, "*.bar.foo", false}, - /* 50 */ {[]string{"foo"}, MAny, MAny, MFalse, MAny, MAny, nil, "bar.foo", false}, - /* 51 */ {[]string{"foo"}, MAny, MAny, MFalse, MAny, MAny, nil, "*.foo", false}, - /* 52 */ {[]string{"foo"}, MFalse, MAny, MFalse, MAny, MAny, nil, "foo", false}, - /* 53 */ {[]string{"foo"}, MTrue, MAny, MFalse, MAny, MAny, nil, "foo", true}, + /* 46 */ {[]string{"foo"}, MAny, MAny, MFalse, MAny, MAny, "baz.fud.bar.foo", false}, + /* 47 */ {[]string{"foo"}, MAny, MAny, MFalse, MAny, MAny, "*.fud.bar.foo", false}, + /* 48 */ {[]string{"foo"}, MAny, MAny, MFalse, MAny, MAny, "fud.bar.foo", false}, + /* 49 */ {[]string{"foo"}, MAny, MAny, MFalse, MAny, MAny, "*.bar.foo", false}, + /* 50 */ {[]string{"foo"}, MAny, MAny, MFalse, MAny, MAny, "bar.foo", false}, + /* 51 */ {[]string{"foo"}, MAny, MAny, MFalse, MAny, MAny, "*.foo", false}, + /* 52 */ {[]string{"foo"}, MFalse, MAny, MFalse, MAny, MAny, "foo", false}, + /* 53 */ {[]string{"foo"}, MTrue, MAny, MFalse, MAny, MAny, "foo", true}, // Allowed contains only domain components, and subdomains are now allowed. // This results in most issuances succeeding, with the exception of the // base foo, which is still governed by base's value. - /* 54 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MAny, nil, "baz.fud.bar.foo", true}, - /* 55 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MTrue, nil, "*.fud.bar.foo", true}, - /* 56 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MAny, nil, "fud.bar.foo", true}, - /* 57 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MTrue, nil, "*.bar.foo", true}, - /* 58 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MAny, nil, "bar.foo", true}, - /* 59 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MTrue, nil, "*.foo", true}, - /* 60 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MTrue, nil, "x*x.foo", true}, // internal wildcards should be allowed per RFC 6125/6.4.3 - /* 61 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MTrue, nil, "*x.foo", true}, // prefix wildcards should be allowed per RFC 6125/6.4.3 - /* 62 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MTrue, nil, "x*.foo", true}, // suffix wildcards should be allowed per RFC 6125/6.4.3 - /* 63 */ {[]string{"foo"}, MFalse, MAny, MTrue, MAny, MAny, nil, "foo", false}, - /* 64 */ {[]string{"foo"}, MTrue, MAny, MTrue, MAny, MAny, nil, "foo", true}, + /* 54 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MAny, "baz.fud.bar.foo", true}, + /* 55 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MTrue, "*.fud.bar.foo", true}, + /* 56 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MAny, "fud.bar.foo", true}, + /* 57 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MTrue, "*.bar.foo", true}, + /* 58 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MAny, "bar.foo", true}, + /* 59 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MTrue, "*.foo", true}, + /* 60 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MTrue, "x*x.foo", true}, // internal wildcards should be allowed per RFC 6125/6.4.3 + /* 61 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MTrue, "*x.foo", true}, // prefix wildcards should be allowed per RFC 6125/6.4.3 + /* 62 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MTrue, "x*.foo", true}, // suffix wildcards should be allowed per RFC 6125/6.4.3 + /* 63 */ {[]string{"foo"}, MFalse, MAny, MTrue, MAny, MAny, "foo", false}, + /* 64 */ {[]string{"foo"}, MTrue, MAny, MTrue, MAny, MAny, "foo", true}, // === Internal Glob Matching === // // Basic glob matching requirements - /* 65 */ {[]string{"x*x.foo"}, MAny, MTrue, MAny, MAny, MAny, nil, "xerox.foo", true}, - /* 66 */ {[]string{"x*x.foo"}, MAny, MTrue, MAny, MAny, MAny, nil, "xylophone.files.pyrex.foo", true}, // globs can match across subdomains - /* 67 */ {[]string{"x*x.foo"}, MAny, MTrue, MAny, MAny, MAny, nil, "xercex.bar.foo", false}, // x.foo isn't matched - /* 68 */ {[]string{"x*x.foo"}, MAny, MTrue, MAny, MAny, MAny, nil, "bar.foo", false}, // x*x isn't matched. - /* 69 */ {[]string{"x*x.foo"}, MAny, MTrue, MAny, MAny, MAny, nil, "*.foo", false}, // unrelated wildcard - /* 70 */ {[]string{"x*x.foo"}, MAny, MTrue, MAny, MAny, MAny, nil, "*.x*x.foo", false}, // Does not conform to RFC 6125 - /* 71 */ {[]string{"x*x.foo"}, MAny, MTrue, MAny, MAny, MAny, nil, "*.xyx.foo", false}, // Globs and Subdomains do not layer per docs. + /* 65 */ {[]string{"x*x.foo"}, MAny, MTrue, MAny, MAny, MAny, "xerox.foo", true}, + /* 66 */ {[]string{"x*x.foo"}, MAny, MTrue, MAny, MAny, MAny, "xylophone.files.pyrex.foo", true}, // globs can match across subdomains + /* 67 */ {[]string{"x*x.foo"}, MAny, MTrue, MAny, MAny, MAny, "xercex.bar.foo", false}, // x.foo isn't matched + /* 68 */ {[]string{"x*x.foo"}, MAny, MTrue, MAny, MAny, MAny, "bar.foo", false}, // x*x isn't matched. + /* 69 */ {[]string{"x*x.foo"}, MAny, MTrue, MAny, MAny, MAny, "*.foo", false}, // unrelated wildcard + /* 70 */ {[]string{"x*x.foo"}, MAny, MTrue, MAny, MAny, MAny, "*.x*x.foo", false}, // Does not conform to RFC 6125 + /* 71 */ {[]string{"x*x.foo"}, MAny, MTrue, MAny, MAny, MAny, "*.xyx.foo", false}, // Globs and Subdomains do not layer per docs. // Various requirements around x*x.foo wildcard matching. - /* 72 */ {[]string{"x*x.foo"}, MFalse, MFalse, MAny, MAny, MAny, nil, "x*x.foo", false}, // base disabled, shouldn't match wildcard - /* 73 */ {[]string{"x*x.foo"}, MFalse, MTrue, MAny, MAny, MTrue, nil, "x*x.foo", true}, // base disallowed, but globbing allowed and should match - /* 74 */ {[]string{"x*x.foo"}, MTrue, MAny, MAny, MAny, MTrue, nil, "x*x.foo", true}, // base allowed, should match wildcard + /* 72 */ {[]string{"x*x.foo"}, MFalse, MFalse, MAny, MAny, MAny, "x*x.foo", false}, // base disabled, shouldn't match wildcard + /* 73 */ {[]string{"x*x.foo"}, MFalse, MTrue, MAny, MAny, MTrue, "x*x.foo", true}, // base disallowed, but globbing allowed and should match + /* 74 */ {[]string{"x*x.foo"}, MTrue, MAny, MAny, MAny, MTrue, "x*x.foo", true}, // base allowed, should match wildcard // Basic glob matching requirements with internal dots. - /* 75 */ {[]string{"x.*.x.foo"}, MAny, MTrue, MAny, MAny, MAny, nil, "xerox.foo", false}, // missing dots - /* 76 */ {[]string{"x.*.x.foo"}, MAny, MTrue, MAny, MAny, MAny, nil, "x.ero.x.foo", true}, - /* 77 */ {[]string{"x.*.x.foo"}, MAny, MTrue, MAny, MAny, MAny, nil, "xylophone.files.pyrex.foo", false}, // missing dots - /* 78 */ {[]string{"x.*.x.foo"}, MAny, MTrue, MAny, MAny, MAny, nil, "x.ylophone.files.pyre.x.foo", true}, // globs can match across subdomains - /* 79 */ {[]string{"x.*.x.foo"}, MAny, MTrue, MAny, MAny, MAny, nil, "xercex.bar.foo", false}, // x.foo isn't matched - /* 80 */ {[]string{"x.*.x.foo"}, MAny, MTrue, MAny, MAny, MAny, nil, "bar.foo", false}, // x.*.x isn't matched. - /* 81 */ {[]string{"x.*.x.foo"}, MAny, MTrue, MAny, MAny, MAny, nil, "*.foo", false}, // unrelated wildcard - /* 82 */ {[]string{"x.*.x.foo"}, MAny, MTrue, MAny, MAny, MAny, nil, "*.x.*.x.foo", false}, // Does not conform to RFC 6125 - /* 83 */ {[]string{"x.*.x.foo"}, MAny, MTrue, MAny, MAny, MAny, nil, "*.x.y.x.foo", false}, // Globs and Subdomains do not layer per docs. + /* 75 */ {[]string{"x.*.x.foo"}, MAny, MTrue, MAny, MAny, MAny, "xerox.foo", false}, // missing dots + /* 76 */ {[]string{"x.*.x.foo"}, MAny, MTrue, MAny, MAny, MAny, "x.ero.x.foo", true}, + /* 77 */ {[]string{"x.*.x.foo"}, MAny, MTrue, MAny, MAny, MAny, "xylophone.files.pyrex.foo", false}, // missing dots + /* 78 */ {[]string{"x.*.x.foo"}, MAny, MTrue, MAny, MAny, MAny, "x.ylophone.files.pyre.x.foo", true}, // globs can match across subdomains + /* 79 */ {[]string{"x.*.x.foo"}, MAny, MTrue, MAny, MAny, MAny, "xercex.bar.foo", false}, // x.foo isn't matched + /* 80 */ {[]string{"x.*.x.foo"}, MAny, MTrue, MAny, MAny, MAny, "bar.foo", false}, // x.*.x isn't matched. + /* 81 */ {[]string{"x.*.x.foo"}, MAny, MTrue, MAny, MAny, MAny, "*.foo", false}, // unrelated wildcard + /* 82 */ {[]string{"x.*.x.foo"}, MAny, MTrue, MAny, MAny, MAny, "*.x.*.x.foo", false}, // Does not conform to RFC 6125 + /* 83 */ {[]string{"x.*.x.foo"}, MAny, MTrue, MAny, MAny, MAny, "*.x.y.x.foo", false}, // Globs and Subdomains do not layer per docs. // === Wildcard restriction testing === // - /* 84 */ {[]string{"*.foo"}, MAny, MTrue, MFalse, MAny, MFalse, nil, "*.fud.bar.foo", false}, // glob domain allows wildcard of subdomains - /* 85 */ {[]string{"*.foo"}, MAny, MTrue, MFalse, MAny, MFalse, nil, "*.bar.foo", false}, // glob domain allows wildcards of subdomains - /* 86 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MFalse, nil, "*.fud.bar.foo", false}, - /* 87 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MFalse, nil, "*.bar.foo", false}, - /* 88 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MFalse, nil, "*.foo", false}, - /* 89 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MFalse, nil, "x*x.foo", false}, - /* 90 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MFalse, nil, "*x.foo", false}, - /* 91 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MFalse, nil, "x*.foo", false}, - /* 92 */ {[]string{"x*x.foo"}, MTrue, MAny, MAny, MAny, MFalse, nil, "x*x.foo", false}, - /* 93 */ {[]string{"*.foo"}, MFalse, MFalse, MAny, MAny, MAny, nil, "*.foo", false}, // Bare and globs forbidden despite (potentially) allowing wildcards. - /* 94 */ {[]string{"x.*.x.foo"}, MAny, MAny, MAny, MAny, MAny, nil, "x.*.x.foo", false}, // Does not conform to RFC 6125 - - // === CN validation allowances === // - /* 95 */ {[]string{"foo"}, MAny, MAny, MAny, MAny, MAny, []string{"disabled"}, "*.fud.bar.foo", true}, - /* 96 */ {[]string{"foo"}, MAny, MAny, MAny, MAny, MAny, []string{"disabled"}, "*.fud.*.foo", true}, - /* 97 */ {[]string{"foo"}, MAny, MAny, MAny, MAny, MAny, []string{"disabled"}, "*.bar.*.bar", true}, - /* 98 */ {[]string{"foo"}, MAny, MAny, MAny, MAny, MAny, []string{"disabled"}, "foo@foo", true}, - /* 99 */ {[]string{"foo"}, MAny, MAny, MAny, MAny, MAny, []string{"disabled"}, "foo@foo@foo", true}, - /* 100 */ {[]string{"foo"}, MAny, MAny, MAny, MAny, MAny, []string{"disabled"}, "bar@bar@bar", true}, - /* 101 */ {[]string{"foo"}, MTrue, MTrue, MTrue, MTrue, MTrue, []string{"email"}, "bar@bar@bar", false}, - /* 102 */ {[]string{"foo"}, MTrue, MTrue, MTrue, MTrue, MTrue, []string{"email"}, "bar@bar", false}, - /* 103 */ {[]string{"foo"}, MTrue, MTrue, MTrue, MTrue, MTrue, []string{"email"}, "bar@foo", true}, - /* 104 */ {[]string{"foo"}, MTrue, MTrue, MTrue, MTrue, MTrue, []string{"hostname"}, "bar@foo", false}, - /* 105 */ {[]string{"foo"}, MTrue, MTrue, MTrue, MTrue, MTrue, []string{"hostname"}, "bar@bar", false}, - /* 106 */ {[]string{"foo"}, MTrue, MTrue, MTrue, MTrue, MTrue, []string{"hostname"}, "bar.foo", true}, - /* 107 */ {[]string{"foo"}, MTrue, MTrue, MTrue, MTrue, MTrue, []string{"hostname"}, "bar.bar", false}, - /* 108 */ {[]string{"foo"}, MTrue, MTrue, MTrue, MTrue, MTrue, []string{"email"}, "bar.foo", false}, - /* 109 */ {[]string{"foo"}, MTrue, MTrue, MTrue, MTrue, MTrue, []string{"email"}, "bar.bar", false}, - } - - if len(testCases) != 110 { + /* 84 */ {[]string{"*.foo"}, MAny, MTrue, MFalse, MAny, MFalse, "*.fud.bar.foo", false}, // glob domain allows wildcard of subdomains + /* 85 */ {[]string{"*.foo"}, MAny, MTrue, MFalse, MAny, MFalse, "*.bar.foo", false}, // glob domain allows wildcards of subdomains + /* 86 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MFalse, "*.fud.bar.foo", false}, + /* 87 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MFalse, "*.bar.foo", false}, + /* 88 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MFalse, "*.foo", false}, + /* 89 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MFalse, "x*x.foo", false}, + /* 90 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MFalse, "*x.foo", false}, + /* 91 */ {[]string{"foo"}, MAny, MAny, MTrue, MAny, MFalse, "x*.foo", false}, + /* 92 */ {[]string{"x*x.foo"}, MTrue, MAny, MAny, MAny, MFalse, "x*x.foo", false}, + /* 93 */ {[]string{"*.foo"}, MFalse, MFalse, MAny, MAny, MAny, "*.foo", false}, // Bare and globs forbidden despite (potentially) allowing wildcards. + /* 94 */ {[]string{"x.*.x.foo"}, MAny, MAny, MAny, MAny, MAny, "x.*.x.foo", false}, // Does not conform to RFC 6125 + } + + if len(testCases) != 95 { t.Fatalf("misnumbered test case entries will make it hard to find bugs: %v", len(testCases)) } @@ -4460,7 +4393,6 @@ type KeySizeRegression struct { // Signature Bits presently is only specified on the role. RoleSignatureBits []int - RoleUsePSS bool // These are tuples; must be of the same length. TestKeyTypes []string @@ -4504,7 +4436,6 @@ func RoleKeySizeRegressionHelper(t *testing.T, b *backend, s logical.Storage, in "key_type": test.RoleKeyType, "key_bits": roleKeyBits, "signature_bits": roleSignatureBits, - "use_pss": test.RoleUsePSS, }) if err != nil { t.Fatal(err) @@ -4530,15 +4461,6 @@ func RoleKeySizeRegressionHelper(t *testing.T, b *backend, s logical.Storage, in t.Fatalf("key size regression test [%d] failed: haveErr: %v, expectErr: %v, err: %v, resp: %v, test case: %v, caKeyType: %v, caKeyBits: %v, role: %v, keyType: %v, keyBits: %v", index, haveErr, test.ExpectError, err, resp, test, caKeyType, caKeyBits, role, keyType, keyBits) } - if resp != nil && test.RoleUsePSS && caKeyType == "rsa" { - leafCert := parseCert(t, resp.Data["certificate"].(string)) - switch leafCert.SignatureAlgorithm { - case x509.SHA256WithRSAPSS, x509.SHA384WithRSAPSS, x509.SHA512WithRSAPSS: - default: - t.Fatalf("key size regression test [%d] failed on role %v: unexpected signature algorithm; expected RSA-type CA to sign a leaf cert with PSS algorithm; got %v", index, role, leafCert.SignatureAlgorithm.String()) - } - } - tested += 1 } } @@ -4555,46 +4477,40 @@ func RoleKeySizeRegressionHelper(t *testing.T, b *backend, s logical.Storage, in } func TestBackend_Roles_KeySizeRegression(t *testing.T) { - t.Parallel() // Regression testing of role's issuance policy. testCases := []KeySizeRegression{ // RSA with default parameters should fail to issue smaller RSA keys // and any size ECDSA/Ed25519 keys. - /* 0 */ {"rsa", []int{0, 2048}, []int{0, 256, 384, 512}, false, []string{"rsa", "ec", "ec", "ec", "ec", "ed25519"}, []int{1024, 224, 256, 384, 521, 0}, true}, + /* 0 */ {"rsa", []int{0, 2048}, []int{0, 256, 384, 512}, []string{"rsa", "ec", "ec", "ec", "ec", "ed25519"}, []int{1024, 224, 256, 384, 521, 0}, true}, // But it should work to issue larger RSA keys. - /* 1 */ {"rsa", []int{0, 2048}, []int{0, 256, 384, 512}, false, []string{"rsa", "rsa"}, []int{2048, 3072}, false}, + /* 1 */ {"rsa", []int{0, 2048}, []int{0, 256, 384, 512}, []string{"rsa", "rsa"}, []int{2048, 3072}, false}, // EC with default parameters should fail to issue smaller EC keys // and any size RSA/Ed25519 keys. - /* 2 */ {"ec", []int{0}, []int{0}, false, []string{"rsa", "ec", "ed25519"}, []int{2048, 224, 0}, true}, + /* 2 */ {"ec", []int{0}, []int{0}, []string{"rsa", "ec", "ed25519"}, []int{2048, 224, 0}, true}, // But it should work to issue larger EC keys. Note that we should be // independent of signature bits as that's computed from the issuer // type (for EC based issuers). - /* 3 */ {"ec", []int{224}, []int{0, 256, 384, 521}, false, []string{"ec", "ec", "ec", "ec"}, []int{224, 256, 384, 521}, false}, - /* 4 */ {"ec", []int{0, 256}, []int{0, 256, 384, 521}, false, []string{"ec", "ec", "ec"}, []int{256, 384, 521}, false}, - /* 5 */ {"ec", []int{384}, []int{0, 256, 384, 521}, false, []string{"ec", "ec"}, []int{384, 521}, false}, - /* 6 */ {"ec", []int{521}, []int{0, 256, 384, 512}, false, []string{"ec"}, []int{521}, false}, + /* 3 */ {"ec", []int{224}, []int{0, 256, 384, 521}, []string{"ec", "ec", "ec", "ec"}, []int{224, 256, 384, 521}, false}, + /* 4 */ {"ec", []int{0, 256}, []int{0, 256, 384, 521}, []string{"ec", "ec", "ec"}, []int{256, 384, 521}, false}, + /* 5 */ {"ec", []int{384}, []int{0, 256, 384, 521}, []string{"ec", "ec"}, []int{384, 521}, false}, + /* 6 */ {"ec", []int{521}, []int{0, 256, 384, 512}, []string{"ec"}, []int{521}, false}, // Ed25519 should reject RSA and EC keys. - /* 7 */ {"ed25519", []int{0}, []int{0}, false, []string{"rsa", "ec", "ec"}, []int{2048, 256, 521}, true}, + /* 7 */ {"ed25519", []int{0}, []int{0}, []string{"rsa", "ec", "ec"}, []int{2048, 256, 521}, true}, // But it should work to issue Ed25519 keys. - /* 8 */ {"ed25519", []int{0}, []int{0}, false, []string{"ed25519"}, []int{0}, false}, + /* 8 */ {"ed25519", []int{0}, []int{0}, []string{"ed25519"}, []int{0}, false}, // Any key type should reject insecure RSA key sizes. - /* 9 */ {"any", []int{0}, []int{0, 256, 384, 512}, false, []string{"rsa", "rsa"}, []int{512, 1024}, true}, + /* 9 */ {"any", []int{0}, []int{0, 256, 384, 512}, []string{"rsa", "rsa"}, []int{512, 1024}, true}, // But work for everything else. - /* 10 */ {"any", []int{0}, []int{0, 256, 384, 512}, false, []string{"rsa", "rsa", "ec", "ec", "ec", "ec", "ed25519"}, []int{2048, 3072, 224, 256, 384, 521, 0}, false}, + /* 10 */ {"any", []int{0}, []int{0, 256, 384, 512}, []string{"rsa", "rsa", "ec", "ec", "ec", "ec", "ed25519"}, []int{2048, 3072, 224, 256, 384, 521, 0}, false}, // RSA with larger than default key size should reject smaller ones. - /* 11 */ {"rsa", []int{3072}, []int{0, 256, 384, 512}, false, []string{"rsa"}, []int{2048}, true}, - - // We should be able to sign with PSS with any CA key type. - /* 12 */ {"rsa", []int{0}, []int{0, 256, 384, 512}, true, []string{"rsa"}, []int{2048}, false}, - /* 13 */ {"ec", []int{0}, []int{0}, true, []string{"ec"}, []int{256}, false}, - /* 14 */ {"ed25519", []int{0}, []int{0}, true, []string{"ed25519"}, []int{0}, false}, + /* 11 */ {"rsa", []int{3072}, []int{0, 256, 384, 512}, []string{"rsa"}, []int{2048}, true}, } - if len(testCases) != 15 { + if len(testCases) != 12 { t.Fatalf("misnumbered test case entries will make it hard to find bugs: %v", len(testCases)) } @@ -4609,7 +4525,6 @@ func TestBackend_Roles_KeySizeRegression(t *testing.T) { } func TestRootWithExistingKey(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) var err error @@ -4742,7 +4657,6 @@ func TestRootWithExistingKey(t *testing.T) { } func TestIntermediateWithExistingKey(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) var err error @@ -4807,7 +4721,6 @@ func TestIntermediateWithExistingKey(t *testing.T) { } func TestIssuanceTTLs(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) resp, err := CBWrite(b, s, "root/generate/internal", map[string]interface{}{ @@ -4882,7 +4795,6 @@ func TestIssuanceTTLs(t *testing.T) { } func TestSealWrappedStorageConfigured(t *testing.T) { - t.Parallel() b, _ := createBackendWithStorage(t) wrappedEntries := b.Backend.PathsSpecial.SealWrapStorage @@ -4893,6 +4805,35 @@ func TestSealWrappedStorageConfigured(t *testing.T) { require.Contains(t, wrappedEntries, "config/key/", "key prefix with trailing / missing from seal wrap.") } +func TestBackend_ConfigCA_WithECParams(t *testing.T) { + t.Parallel() + b, s := createBackendWithStorage(t) + + // Generated key with OpenSSL: + // $ openssl ecparam -out p256.key -name prime256v1 -genkey + // + // Regression test for https://github.com/hashicorp/vault/issues/16667 + resp, err := CBWrite(b, s, "config/ca", map[string]interface{}{ + "pem_bundle": ` +-----BEGIN EC PARAMETERS----- +BggqhkjOPQMBBw== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEINzXthCZdhyV7+wIEBl/ty+ctNsUS99ykTeax6EbYZtvoAoGCCqGSM49 +AwEHoUQDQgAE57NX8bR/nDoW8yRgLswoXBQcjHrdyfuHS0gPwki6BNnfunUzryVb +8f22/JWj6fsEF6AOADZlrswKIbR2Es9e/w== +-----END EC PRIVATE KEY----- + `, + }) + require.NoError(t, err) + require.NotNil(t, resp, "expected ca info") + importedKeys := resp.Data["imported_keys"].([]string) + importedIssuers := resp.Data["imported_issuers"].([]string) + + require.Equal(t, len(importedKeys), 1) + require.Equal(t, len(importedIssuers), 0) +} + var ( initTest sync.Once rsaCAKey string diff --git a/builtin/logical/pki/ca_test.go b/builtin/logical/pki/ca_test.go index 2c33397114259..ec3220ba37c82 100644 --- a/builtin/logical/pki/ca_test.go +++ b/builtin/logical/pki/ca_test.go @@ -26,7 +26,6 @@ import ( ) func TestBackend_CA_Steps(t *testing.T) { - t.Parallel() var b *backend factory := func(ctx context.Context, conf *logical.BackendConfig) (logical.Backend, error) { diff --git a/builtin/logical/pki/ca_util.go b/builtin/logical/pki/ca_util.go index d2a59f34bdd2f..9499908e3556f 100644 --- a/builtin/logical/pki/ca_util.go +++ b/builtin/logical/pki/ca_util.go @@ -17,7 +17,7 @@ import ( "github.com/hashicorp/vault/sdk/logical" ) -func getGenerationParams(sc *storageContext, data *framework.FieldData) (exported bool, format string, role *roleEntry, errorResp *logical.Response) { +func (b *backend) getGenerationParams(ctx context.Context, storage logical.Storage, data *framework.FieldData) (exported bool, format string, role *roleEntry, errorResp *logical.Response) { exportedStr := data.Get("exported").(string) switch exportedStr { case "exported": @@ -37,8 +37,7 @@ func getGenerationParams(sc *storageContext, data *framework.FieldData) (exporte `the "format" path parameter must be "pem", "der", or "pem_bundle"`) return } - - keyType, keyBits, err := sc.getKeyTypeAndBitsForRole(data) + keyType, keyBits, err := getKeyTypeAndBitsForRole(ctx, b, storage, data) if err != nil { errorResp = logical.ErrorResponse(err.Error()) return @@ -49,7 +48,6 @@ func getGenerationParams(sc *storageContext, data *framework.FieldData) (exporte KeyType: keyType, KeyBits: keyBits, SignatureBits: data.Get("signature_bits").(int), - UsePSS: data.Get("use_pss").(bool), AllowLocalhost: true, AllowAnyName: true, AllowIPSANs: true, @@ -66,7 +64,6 @@ func getGenerationParams(sc *storageContext, data *framework.FieldData) (exporte StreetAddress: data.Get("street_address").([]string), PostalCode: data.Get("postal_code").([]string), NotBeforeDuration: time.Duration(data.Get("not_before_duration").(int)) * time.Second, - CNValidations: []string{"disabled"}, } *role.AllowWildcardCertificates = true @@ -77,10 +74,7 @@ func getGenerationParams(sc *storageContext, data *framework.FieldData) (exporte return } -func generateCABundle(sc *storageContext, input *inputBundle, data *certutil.CreationBundle, randomSource io.Reader) (*certutil.ParsedCertBundle, error) { - ctx := sc.Context - b := sc.Backend - +func generateCABundle(ctx context.Context, b *backend, input *inputBundle, data *certutil.CreationBundle, randomSource io.Reader) (*certutil.ParsedCertBundle, error) { if kmsRequested(input) { keyId, err := getManagedKeyId(input.apiData) if err != nil { @@ -95,7 +89,7 @@ func generateCABundle(sc *storageContext, input *inputBundle, data *certutil.Cre return nil, err } - keyEntry, err := sc.getExistingKeyFromRef(keyRef) + keyEntry, err := getExistingKeyFromRef(ctx, input.req.Storage, keyRef) if err != nil { return nil, err } @@ -114,10 +108,7 @@ func generateCABundle(sc *storageContext, input *inputBundle, data *certutil.Cre return certutil.CreateCertificateWithRandomSource(data, randomSource) } -func generateCSRBundle(sc *storageContext, input *inputBundle, data *certutil.CreationBundle, addBasicConstraints bool, randomSource io.Reader) (*certutil.ParsedCSRBundle, error) { - ctx := sc.Context - b := sc.Backend - +func generateCSRBundle(ctx context.Context, b *backend, input *inputBundle, data *certutil.CreationBundle, addBasicConstraints bool, randomSource io.Reader) (*certutil.ParsedCSRBundle, error) { if kmsRequested(input) { keyId, err := getManagedKeyId(input.apiData) if err != nil { @@ -133,7 +124,7 @@ func generateCSRBundle(sc *storageContext, input *inputBundle, data *certutil.Cr return nil, err } - key, err := sc.getExistingKeyFromRef(keyRef) + key, err := getExistingKeyFromRef(ctx, input.req.Storage, keyRef) if err != nil { return nil, err } @@ -159,7 +150,7 @@ func parseCABundle(ctx context.Context, b *backend, bundle *certutil.CertBundle) return bundle.ToParsedCertBundle() } -func (sc *storageContext) getKeyTypeAndBitsForRole(data *framework.FieldData) (string, int, error) { +func getKeyTypeAndBitsForRole(ctx context.Context, b *backend, storage logical.Storage, data *framework.FieldData) (string, int, error) { exportedStr := data.Get("exported").(string) var keyType string var keyBits int @@ -188,7 +179,7 @@ func (sc *storageContext) getKeyTypeAndBitsForRole(data *framework.FieldData) (s return "", 0, errors.New("unable to determine managed key id" + err.Error()) } - pubKeyManagedKey, err := getManagedKeyPublicKey(sc.Context, sc.Backend, keyId) + pubKeyManagedKey, err := getManagedKeyPublicKey(ctx, b, keyId) if err != nil { return "", 0, errors.New("failed to lookup public key from managed key: " + err.Error()) } @@ -196,7 +187,7 @@ func (sc *storageContext) getKeyTypeAndBitsForRole(data *framework.FieldData) (s } if existingKeyRequestedFromFieldData(data) { - existingPubKey, err := sc.getExistingPublicKey(data) + existingPubKey, err := getExistingPublicKey(ctx, b, storage, data) if err != nil { return "", 0, errors.New("failed to lookup public key from existing key: " + err.Error()) } @@ -207,20 +198,20 @@ func (sc *storageContext) getKeyTypeAndBitsForRole(data *framework.FieldData) (s return string(privateKeyType), keyBits, err } -func (sc *storageContext) getExistingPublicKey(data *framework.FieldData) (crypto.PublicKey, error) { +func getExistingPublicKey(ctx context.Context, b *backend, s logical.Storage, data *framework.FieldData) (crypto.PublicKey, error) { keyRef, err := getKeyRefWithErr(data) if err != nil { return nil, err } - id, err := sc.resolveKeyReference(keyRef) + id, err := resolveKeyReference(ctx, s, keyRef) if err != nil { return nil, err } - key, err := sc.fetchKeyById(id) + key, err := fetchKeyById(ctx, s, id) if err != nil { return nil, err } - return getPublicKey(sc.Context, sc.Backend, key) + return getPublicKey(ctx, b, key) } func getKeyTypeAndBitsFromPublicKeyForRole(pubKey crypto.PublicKey) (certutil.PrivateKeyType, int, error) { @@ -241,12 +232,12 @@ func getKeyTypeAndBitsFromPublicKeyForRole(pubKey crypto.PublicKey) (certutil.Pr return keyType, keyBits, nil } -func (sc *storageContext) getExistingKeyFromRef(keyRef string) (*keyEntry, error) { - keyId, err := sc.resolveKeyReference(keyRef) +func getExistingKeyFromRef(ctx context.Context, s logical.Storage, keyRef string) (*keyEntry, error) { + keyId, err := resolveKeyReference(ctx, s, keyRef) if err != nil { return nil, err } - return sc.fetchKeyById(keyId) + return fetchKeyById(ctx, s, keyId) } func existingKeyGeneratorFromBytes(key *keyEntry) certutil.KeyGenerator { diff --git a/builtin/logical/pki/cert_util.go b/builtin/logical/pki/cert_util.go index 142cf9b8ee3e4..23661422b52ac 100644 --- a/builtin/logical/pki/cert_util.go +++ b/builtin/logical/pki/cert_util.go @@ -10,7 +10,6 @@ import ( "crypto/x509/pkix" "encoding/asn1" "encoding/base64" - "encoding/hex" "encoding/pem" "errors" "fmt" @@ -84,29 +83,29 @@ func getFormat(data *framework.FieldData) string { // fetchCAInfo will fetch the CA info, will return an error if no ca info exists, this does NOT support // loading using the legacyBundleShimID and should be used with care. This should be called only once // within the request path otherwise you run the risk of a race condition with the issuer migration on perf-secondaries. -func (sc *storageContext) fetchCAInfo(issuerRef string, usage issuerUsage) (*certutil.CAInfoBundle, error) { +func fetchCAInfo(ctx context.Context, b *backend, req *logical.Request, issuerRef string, usage issuerUsage) (*certutil.CAInfoBundle, error) { var issuerId issuerID - if sc.Backend.useLegacyBundleCaStorage() { + if b.useLegacyBundleCaStorage() { // We have not completed the migration so attempt to load the bundle from the legacy location - sc.Backend.Logger().Info("Using legacy CA bundle as PKI migration has not completed.") + b.Logger().Info("Using legacy CA bundle as PKI migration has not completed.") issuerId = legacyBundleShimID } else { var err error - issuerId, err = sc.resolveIssuerReference(issuerRef) + issuerId, err = resolveIssuerReference(ctx, req.Storage, issuerRef) if err != nil { // Usually a bad label from the user or mis-configured default. return nil, errutil.UserError{Err: err.Error()} } } - return sc.fetchCAInfoByIssuerId(issuerId, usage) + return fetchCAInfoByIssuerId(ctx, b, req, issuerId, usage) } // fetchCAInfoByIssuerId will fetch the CA info, will return an error if no ca info exists for the given issuerId. // This does support the loading using the legacyBundleShimID -func (sc *storageContext) fetchCAInfoByIssuerId(issuerId issuerID, usage issuerUsage) (*certutil.CAInfoBundle, error) { - entry, bundle, err := sc.fetchCertBundleByIssuerId(issuerId, true) +func fetchCAInfoByIssuerId(ctx context.Context, b *backend, req *logical.Request, issuerId issuerID, usage issuerUsage) (*certutil.CAInfoBundle, error) { + entry, bundle, err := fetchCertBundleByIssuerId(ctx, req.Storage, issuerId, true) if err != nil { switch err.(type) { case errutil.UserError: @@ -122,7 +121,7 @@ func (sc *storageContext) fetchCAInfoByIssuerId(issuerId issuerID, usage issuerU return nil, errutil.InternalError{Err: fmt.Sprintf("error while attempting to use issuer %v: %v", issuerId, err)} } - parsedBundle, err := parseCABundle(sc.Context, sc.Backend, bundle) + parsedBundle, err := parseCABundle(ctx, b, bundle) if err != nil { return nil, errutil.InternalError{Err: err.Error()} } @@ -138,10 +137,9 @@ func (sc *storageContext) fetchCAInfoByIssuerId(issuerId issuerID, usage issuerU ParsedCertBundle: *parsedBundle, URLs: nil, LeafNotAfterBehavior: entry.LeafNotAfterBehavior, - RevocationSigAlg: entry.RevocationSigAlg, } - entries, err := getURLs(sc.Context, sc.Storage) + entries, err := getURLs(ctx, req) if err != nil { return nil, errutil.InternalError{Err: fmt.Sprintf("unable to fetch URL information: %v", err)} } @@ -161,7 +159,7 @@ func fetchCertBySerial(ctx context.Context, b *backend, req *logical.Request, pr var certEntry *logical.StorageEntry hyphenSerial := normalizeSerial(serial) - colonSerial := strings.ReplaceAll(strings.ToLower(serial), "-", ":") + colonSerial := strings.Replace(strings.ToLower(serial), "-", ":", -1) switch { // Revoked goes first as otherwise crl get hardcoded paths which fail if @@ -173,8 +171,7 @@ func fetchCertBySerial(ctx context.Context, b *backend, req *logical.Request, pr if err = b.crlBuilder.rebuildIfForced(ctx, b, req); err != nil { return nil, err } - sc := b.makeStorageContext(ctx, req.Storage) - path, err = sc.resolveIssuerCRLPath(defaultRef) + path, err = resolveIssuerCRLPath(ctx, b, req.Storage, defaultRef) if err != nil { return nil, err } @@ -246,54 +243,6 @@ func validateURISAN(b *backend, data *inputBundle, uri string) bool { return valid } -// Validates a given common name, ensuring its either a email or a hostname -// after validating it according to the role parameters, or disables -// validation altogether. -func validateCommonName(b *backend, data *inputBundle, name string) string { - isDisabled := len(data.role.CNValidations) == 1 && data.role.CNValidations[0] == "disabled" - if isDisabled { - return "" - } - - if validateNames(b, data, []string{name}) != "" { - return name - } - - // Validations weren't disabled, but the role lacked CN Validations, so - // don't restrict types. This case is hit in certain existing tests. - if len(data.role.CNValidations) == 0 { - return "" - } - - // If there's an at in the data, ensure email type validation is allowed. - // Otherwise, ensure hostname is allowed. - if strings.Contains(name, "@") { - var allowsEmails bool - for _, validation := range data.role.CNValidations { - if validation == "email" { - allowsEmails = true - break - } - } - if !allowsEmails { - return name - } - } else { - var allowsHostnames bool - for _, validation := range data.role.CNValidations { - if validation == "hostname" { - allowsHostnames = true - break - } - } - if !allowsHostnames { - return name - } - } - - return "" -} - // Given a set of requested names for a certificate, verifies that all of them // match the various toggles set in the role for controlling issuance. // If one does not pass, it is returned in the string argument. @@ -644,15 +593,13 @@ func validateSerialNumber(data *inputBundle, serialNumber string) string { } } -func generateCert(sc *storageContext, +func generateCert(ctx context.Context, + b *backend, input *inputBundle, caSign *certutil.CAInfoBundle, isCA bool, randomSource io.Reader) (*certutil.ParsedCertBundle, error, ) { - ctx := sc.Context - b := sc.Backend - if input.role == nil { return nil, errutil.InternalError{Err: "no role found in data bundle"} } @@ -675,7 +622,7 @@ func generateCert(sc *storageContext, if data.SigningBundle == nil { // Generating a self-signed root certificate - entries, err := getURLs(ctx, sc.Storage) + entries, err := getURLs(ctx, input.req) if err != nil { return nil, errutil.InternalError{Err: fmt.Sprintf("unable to fetch URL information: %v", err)} } @@ -689,7 +636,7 @@ func generateCert(sc *storageContext, } } - parsedBundle, err := generateCABundle(sc, input, data, randomSource) + parsedBundle, err := generateCABundle(ctx, b, input, data, randomSource) if err != nil { return nil, err } @@ -699,9 +646,7 @@ func generateCert(sc *storageContext, // N.B.: This is only meant to be used for generating intermediate CAs. // It skips some sanity checks. -func generateIntermediateCSR(sc *storageContext, input *inputBundle, randomSource io.Reader) (*certutil.ParsedCSRBundle, error) { - b := sc.Backend - +func generateIntermediateCSR(ctx context.Context, b *backend, input *inputBundle, randomSource io.Reader) (*certutil.ParsedCSRBundle, error) { creation, err := generateCreationBundle(b, input, nil, nil) if err != nil { return nil, err @@ -711,7 +656,7 @@ func generateIntermediateCSR(sc *storageContext, input *inputBundle, randomSourc } addBasicConstraints := input.apiData != nil && input.apiData.Get("add_basic_constraints").(bool) - parsedBundle, err := generateCSRBundle(sc, input, creation, addBasicConstraints, randomSource) + parsedBundle, err := generateCSRBundle(ctx, b, input, creation, addBasicConstraints, randomSource) if err != nil { return nil, err } @@ -1106,7 +1051,7 @@ func generateCreationBundle(b *backend, data *inputBundle, caSign *certutil.CAIn // Check the CN. This ensures that the CN is checked even if it's // excluded from SANs. if cn != "" { - badName := validateCommonName(b, data, cn) + badName := validateNames(b, data, []string{cn}) if len(badName) != 0 { return nil, errutil.UserError{Err: fmt.Sprintf( "common name %s not allowed by this role", badName)} @@ -1196,7 +1141,7 @@ func generateCreationBundle(b *backend, data *inputBundle, caSign *certutil.CAIn parsedIP := net.ParseIP(v) if parsedIP == nil { return nil, errutil.UserError{Err: fmt.Sprintf( - "the value %q is not a valid IP address", v)} + "the value '%s' is not a valid IP address", v)} } ipAddresses = append(ipAddresses, parsedIP) } @@ -1251,7 +1196,7 @@ func generateCreationBundle(b *backend, data *inputBundle, caSign *certutil.CAIn if parsedURI == nil || err != nil { return nil, errutil.UserError{ Err: fmt.Sprintf( - "the provided URI Subject Alternative Name %q is not a valid URI", uri), + "the provided URI Subject Alternative Name '%s' is not a valid URI", uri), } } @@ -1342,27 +1287,6 @@ func generateCreationBundle(b *backend, data *inputBundle, caSign *certutil.CAIn } } - // Parse SKID from the request for cross-signing. - var skid []byte - { - if rawSKIDValue, ok := data.apiData.GetOk("skid"); ok { - // Handle removing common separators to make copy/paste from tool - // output easier. Chromium uses space, OpenSSL uses colons, and at - // one point, Vault had preferred dash as a separator for hex - // strings. - var err error - skidValue := rawSKIDValue.(string) - for _, separator := range []string{":", "-", " "} { - skidValue = strings.ReplaceAll(skidValue, separator, "") - } - - skid, err = hex.DecodeString(skidValue) - if err != nil { - return nil, errutil.UserError{Err: fmt.Sprintf("cannot parse requested SKID value as hex: %v", err)} - } - } - } - creation := &certutil.CreationBundle{ Params: &certutil.CreationParameters{ Subject: subject, @@ -1374,7 +1298,6 @@ func generateCreationBundle(b *backend, data *inputBundle, caSign *certutil.CAIn KeyType: data.role.KeyType, KeyBits: data.role.KeyBits, SignatureBits: data.role.SignatureBits, - UsePSS: data.role.UsePSS, NotAfter: notAfter, KeyUsage: x509.KeyUsage(parseKeyUsages(data.role.KeyUsage)), ExtKeyUsage: parseExtKeyUsages(data.role), @@ -1383,7 +1306,6 @@ func generateCreationBundle(b *backend, data *inputBundle, caSign *certutil.CAIn BasicConstraintsValidForNonCA: data.role.BasicConstraintsValidForNonCA, NotBeforeDuration: data.role.NotBeforeDuration, ForceAppendCaChain: caSign != nil, - SKID: skid, }, SigningBundle: caSign, CSR: csr, diff --git a/builtin/logical/pki/cert_util_test.go b/builtin/logical/pki/cert_util_test.go index 635cfce98547a..a631323724eaa 100644 --- a/builtin/logical/pki/cert_util_test.go +++ b/builtin/logical/pki/cert_util_test.go @@ -12,7 +12,6 @@ import ( ) func TestPki_FetchCertBySerial(t *testing.T) { - t.Parallel() b, storage := createBackendWithStorage(t) cases := map[string]struct { @@ -92,7 +91,6 @@ func TestPki_FetchCertBySerial(t *testing.T) { // Demonstrate that multiple OUs in the name are handled in an // order-preserving way. func TestPki_MultipleOUs(t *testing.T) { - t.Parallel() var b backend fields := addCACommonFields(map[string]*framework.FieldSchema{}) @@ -124,7 +122,6 @@ func TestPki_MultipleOUs(t *testing.T) { } func TestPki_PermitFQDNs(t *testing.T) { - t.Parallel() var b backend fields := addCACommonFields(map[string]*framework.FieldSchema{}) @@ -209,8 +206,6 @@ func TestPki_PermitFQDNs(t *testing.T) { } for name, testCase := range cases { - name := name - testCase := testCase t.Run(name, func(t *testing.T) { cb, err := generateCreationBundle(&b, testCase.input, nil, nil) if err != nil { diff --git a/builtin/logical/pki/chain_test.go b/builtin/logical/pki/chain_test.go index 63f4622bb4b03..2338708c9fbad 100644 --- a/builtin/logical/pki/chain_test.go +++ b/builtin/logical/pki/chain_test.go @@ -1,11 +1,9 @@ package pki import ( - "bytes" "context" "crypto/x509" "crypto/x509/pkix" - "encoding/hex" "encoding/pem" "fmt" "strconv" @@ -115,7 +113,6 @@ type CBGenerateIntermediate struct { Existing bool Name string CommonName string - SKID string Parent string ImportErrorMessage string } @@ -154,14 +151,6 @@ func (c CBGenerateIntermediate) Run(t testing.TB, b *backend, s logical.Storage, if len(c.CommonName) > 0 { data["common_name"] = c.CommonName } - if len(c.SKID) > 0 { - // Copy the SKID from an existing, already-issued cert. - otherPEM := knownCerts[c.SKID] - otherCert := ToCertificate(t, otherPEM) - - data["skid"] = hex.EncodeToString(otherCert.SubjectKeyId) - } - resp, err = CBWrite(b, s, url, data) if err != nil { t.Fatalf("failed to sign CSR for issuer (%v): %v / body: %v", c.Name, err, data) @@ -169,17 +158,6 @@ func (c CBGenerateIntermediate) Run(t testing.TB, b *backend, s logical.Storage, knownCerts[c.Name] = strings.TrimSpace(resp.Data["certificate"].(string)) - // Verify SKID if one was requested. - if len(c.SKID) > 0 { - otherPEM := knownCerts[c.SKID] - otherCert := ToCertificate(t, otherPEM) - ourCert := ToCertificate(t, knownCerts[c.Name]) - - if !bytes.Equal(otherCert.SubjectKeyId, ourCert.SubjectKeyId) { - t.Fatalf("Expected two certs to have equal SKIDs but differed: them: %v vs us: %v", otherCert.SubjectKeyId, ourCert.SubjectKeyId) - } - } - // Set the signed intermediate url = "intermediate/set-signed" data = make(map[string]interface{}) @@ -851,7 +829,6 @@ var chainBuildingTestCases = []CBTestScenario{ Existing: true, Name: "cross-old-new", CommonName: "root-new", - SKID: "root-new-a", // Which old issuer is used here doesn't matter as they have // the same CN and key. Parent: "root-old-a", @@ -910,7 +887,6 @@ var chainBuildingTestCases = []CBTestScenario{ Existing: true, Name: "cross-new-old", CommonName: "root-old", - SKID: "root-old-a", // Which new issuer is used here doesn't matter as they have // the same CN and key. Parent: "root-new-a", @@ -1596,7 +1572,6 @@ var chainBuildingTestCases = []CBTestScenario{ } func Test_CAChainBuilding(t *testing.T) { - t.Parallel() for testIndex, testCase := range chainBuildingTestCases { b, s := createBackendWithStorage(t) @@ -1630,10 +1605,9 @@ func BenchmarkChainBuilding(benchies *testing.B) { // Run the benchmark. ctx := context.Background() - sc := b.makeStorageContext(ctx, s) bench.StartTimer() for n := 0; n < bench.N; n++ { - sc.rebuildIssuersChains(nil) + rebuildIssuersChains(ctx, s, nil) } }) } diff --git a/builtin/logical/pki/chain_util.go b/builtin/logical/pki/chain_util.go index 1fac1e774a35a..8774137ffce12 100644 --- a/builtin/logical/pki/chain_util.go +++ b/builtin/logical/pki/chain_util.go @@ -2,9 +2,12 @@ package pki import ( "bytes" + "context" "crypto/x509" "fmt" "sort" + + "github.com/hashicorp/vault/sdk/logical" ) func prettyIssuer(issuerIdEntryMap map[issuerID]*issuerEntry, issuer issuerID) string { @@ -15,7 +18,7 @@ func prettyIssuer(issuerIdEntryMap map[issuerID]*issuerEntry, issuer issuerID) s return "[" + string(issuer) + "]" } -func (sc *storageContext) rebuildIssuersChains(referenceCert *issuerEntry /* optional */) error { +func rebuildIssuersChains(ctx context.Context, s logical.Storage, referenceCert *issuerEntry /* optional */) error { // This function rebuilds the CAChain field of all known issuers. This // function should usually be invoked when a new issuer is added to the // pool of issuers. @@ -39,7 +42,7 @@ func (sc *storageContext) rebuildIssuersChains(referenceCert *issuerEntry /* opt // themselves. // // To begin, we fetch all known issuers from disk. - issuers, err := sc.listIssuers() + issuers, err := listIssuers(ctx, s) if err != nil { return fmt.Errorf("unable to list issuers to build chain: %v", err) } @@ -55,7 +58,7 @@ func (sc *storageContext) rebuildIssuersChains(referenceCert *issuerEntry /* opt // Otherwise, the only entry in the chain (that we know about) is the // certificate itself. referenceCert.CAChain = []string{referenceCert.Certificate} - return sc.writeIssuer(referenceCert) + return writeIssuer(ctx, s, referenceCert) } // Our provided reference cert might not be in the list of issuers. In @@ -112,7 +115,7 @@ func (sc *storageContext) rebuildIssuersChains(referenceCert *issuerEntry /* opt stored = referenceCert } else { // Otherwise, fetch it from disk. - stored, err = sc.fetchIssuerById(identifier) + stored, err = fetchIssuerById(ctx, s, identifier) if err != nil { return fmt.Errorf("unable to fetch issuer %v to build chain: %v", identifier, err) } @@ -416,7 +419,7 @@ func (sc *storageContext) rebuildIssuersChains(referenceCert *issuerEntry /* opt for _, issuer := range issuers { entry := issuerIdEntryMap[issuer] - err := sc.writeIssuer(entry) + err := writeIssuer(ctx, s, entry) if err != nil { pretty := prettyIssuer(issuerIdEntryMap, issuer) return fmt.Errorf("failed to persist issuer (%v) chain to disk: %v", pretty, err) diff --git a/builtin/logical/pki/config_util.go b/builtin/logical/pki/config_util.go index b49eafee74f6d..6a926c2a3736f 100644 --- a/builtin/logical/pki/config_util.go +++ b/builtin/logical/pki/config_util.go @@ -1,11 +1,14 @@ package pki import ( + "context" "strings" + + "github.com/hashicorp/vault/sdk/logical" ) -func (sc *storageContext) isDefaultKeySet() (bool, error) { - config, err := sc.getKeysConfig() +func isDefaultKeySet(ctx context.Context, s logical.Storage) (bool, error) { + config, err := getKeysConfig(ctx, s) if err != nil { return false, err } @@ -13,8 +16,8 @@ func (sc *storageContext) isDefaultKeySet() (bool, error) { return strings.TrimSpace(config.DefaultKeyId.String()) != "", nil } -func (sc *storageContext) isDefaultIssuerSet() (bool, error) { - config, err := sc.getIssuersConfig() +func isDefaultIssuerSet(ctx context.Context, s logical.Storage) (bool, error) { + config, err := getIssuersConfig(ctx, s) if err != nil { return false, err } @@ -22,14 +25,14 @@ func (sc *storageContext) isDefaultIssuerSet() (bool, error) { return strings.TrimSpace(config.DefaultIssuerId.String()) != "", nil } -func (sc *storageContext) updateDefaultKeyId(id keyID) error { - config, err := sc.getKeysConfig() +func updateDefaultKeyId(ctx context.Context, s logical.Storage, id keyID) error { + config, err := getKeysConfig(ctx, s) if err != nil { return err } if config.DefaultKeyId != id { - return sc.setKeysConfig(&keyConfigEntry{ + return setKeysConfig(ctx, s, &keyConfigEntry{ DefaultKeyId: id, }) } @@ -37,14 +40,14 @@ func (sc *storageContext) updateDefaultKeyId(id keyID) error { return nil } -func (sc *storageContext) updateDefaultIssuerId(id issuerID) error { - config, err := sc.getIssuersConfig() +func updateDefaultIssuerId(ctx context.Context, s logical.Storage, id issuerID) error { + config, err := getIssuersConfig(ctx, s) if err != nil { return err } if config.DefaultIssuerId != id { - return sc.setIssuersConfig(&issuerConfigEntry{ + return setIssuersConfig(ctx, s, &issuerConfigEntry{ DefaultIssuerId: id, }) } diff --git a/builtin/logical/pki/crl_test.go b/builtin/logical/pki/crl_test.go index 428777e41da8e..eb0d5fe5d7935 100644 --- a/builtin/logical/pki/crl_test.go +++ b/builtin/logical/pki/crl_test.go @@ -2,7 +2,6 @@ package pki import ( "context" - "encoding/asn1" "strings" "testing" "time" @@ -26,61 +25,6 @@ func TestBackend_CRL_EnableDisableRoot(t *testing.T) { crlEnableDisableTestForBackend(t, b, s, []string{caSerial}) } -func TestBackend_CRL_AllKeyTypeSigAlgos(t *testing.T) { - type testCase struct { - KeyType string - KeyBits int - SigAlgo string - } - - testCases := []testCase{ - {"rsa", 2048, "SHA256WithRSA"}, - {"rsa", 2048, "SHA384WithRSA"}, - {"rsa", 2048, "SHA512WithRSA"}, - {"rsa", 2048, "SHA256WithRSAPSS"}, - {"rsa", 2048, "SHA384WithRSAPSS"}, - {"rsa", 2048, "SHA512WithRSAPSS"}, - {"ec", 256, "ECDSAWithSHA256"}, - {"ec", 384, "ECDSAWithSHA384"}, - {"ec", 521, "ECDSAWithSHA512"}, - {"ed25519", 0, "PureEd25519"}, - } - - for index, tc := range testCases { - t.Logf("tv %v", index) - b, s := createBackendWithStorage(t) - - resp, err := CBWrite(b, s, "root/generate/internal", map[string]interface{}{ - "ttl": "40h", - "common_name": "myvault.com", - "key_type": tc.KeyType, - "key_bits": tc.KeyBits, - }) - if err != nil { - t.Fatalf("tc %v: %v", index, err) - } - caSerial := resp.Data["serial_number"].(string) - - _, err = CBPatch(b, s, "issuer/default", map[string]interface{}{ - "revocation_signature_algorithm": tc.SigAlgo, - }) - if err != nil { - t.Fatalf("tc %v: %v", index, err) - } - - crlEnableDisableTestForBackend(t, b, s, []string{caSerial}) - - crl := getParsedCrlFromBackend(t, b, s, "crl") - if strings.HasSuffix(tc.SigAlgo, "PSS") { - algo := crl.SignatureAlgorithm - pssOid := asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10} - if !algo.Algorithm.Equal(pssOid) { - t.Fatalf("tc %v failed: expected sig-alg to be %v / got %v", index, pssOid, algo) - } - } - } -} - func TestBackend_CRL_EnableDisableIntermediateWithRoot(t *testing.T) { crlEnableDisableIntermediateTestForBackend(t, true) } @@ -236,11 +180,10 @@ func crlEnableDisableTestForBackend(t *testing.T, b *backend, s logical.Storage, func TestBackend_Secondary_CRL_Rebuilding(t *testing.T) { ctx := context.Background() b, s := createBackendWithStorage(t) - sc := b.makeStorageContext(ctx, s) // Write out the issuer/key to storage without going through the api call as replication would. bundle := genCertBundle(t, b, s) - issuer, _, err := sc.writeCaBundle(bundle, "", "") + issuer, _, err := writeCaBundle(ctx, b, s, bundle, "", "") require.NoError(t, err) // Just to validate, before we call the invalidate function, make sure our CRL has not been generated @@ -260,11 +203,10 @@ func TestBackend_Secondary_CRL_Rebuilding(t *testing.T) { func TestCrlRebuilder(t *testing.T) { ctx := context.Background() b, s := createBackendWithStorage(t) - sc := b.makeStorageContext(ctx, s) // Write out the issuer/key to storage without going through the api call as replication would. bundle := genCertBundle(t, b, s) - _, _, err := sc.writeCaBundle(bundle, "", "") + _, _, err := writeCaBundle(ctx, b, s, bundle, "", "") require.NoError(t, err) req := &logical.Request{Storage: s} diff --git a/builtin/logical/pki/crl_util.go b/builtin/logical/pki/crl_util.go index ae8e2f875dc02..42bdd8ea48cc5 100644 --- a/builtin/logical/pki/crl_util.go +++ b/builtin/logical/pki/crl_util.go @@ -113,10 +113,8 @@ func revokeCert(ctx context.Context, b *backend, req *logical.Request, serial st var err error var issuers []issuerID - sc := b.makeStorageContext(ctx, req.Storage) - if !b.useLegacyBundleCaStorage() { - issuers, err = sc.listIssuers() + issuers, err = listIssuers(ctx, req.Storage) if err != nil { return logical.ErrorResponse(fmt.Sprintf("could not fetch issuers list: %v", err)), nil } @@ -127,7 +125,7 @@ func revokeCert(ctx context.Context, b *backend, req *logical.Request, serial st } for _, issuer := range issuers { - _, bundle, caErr := sc.fetchCertBundleByIssuerId(issuer, false) + _, bundle, caErr := fetchCertBundleByIssuerId(ctx, req.Storage, issuer, false) if caErr != nil { switch caErr.(type) { case errutil.UserError: @@ -150,7 +148,7 @@ func revokeCert(ctx context.Context, b *backend, req *logical.Request, serial st return nil, errutil.InternalError{Err: "stored CA information not able to be parsed"} } - colonSerial := strings.ReplaceAll(strings.ToLower(serial), "-", ":") + colonSerial := strings.Replace(strings.ToLower(serial), "-", ":", -1) if colonSerial == certutil.GetHexFormatted(parsedBundle.Certificate.SerialNumber.Bytes(), ":") { return logical.ErrorResponse(fmt.Sprintf("adding issuer (id: %v) to its own CRL is not allowed", issuer)), nil } @@ -287,10 +285,8 @@ func buildCRLs(ctx context.Context, b *backend, req *logical.Request, forceNew b var err error var issuers []issuerID var wasLegacy bool - sc := b.makeStorageContext(ctx, req.Storage) - if !b.useLegacyBundleCaStorage() { - issuers, err = sc.listIssuers() + issuers, err = listIssuers(ctx, req.Storage) if err != nil { return fmt.Errorf("error building CRL: while listing issuers: %v", err) } @@ -302,7 +298,7 @@ func buildCRLs(ctx context.Context, b *backend, req *logical.Request, forceNew b wasLegacy = true } - config, err := sc.getIssuersConfig() + config, err := getIssuersConfig(ctx, req.Storage) if err != nil { return fmt.Errorf("error building CRLs: while getting the default config: %v", err) } @@ -319,7 +315,7 @@ func buildCRLs(ctx context.Context, b *backend, req *logical.Request, forceNew b for _, issuer := range issuers { // We don't strictly need this call, but by requesting the bundle, the // legacy path is automatically ignored. - thisEntry, _, err := sc.fetchCertBundleByIssuerId(issuer, false) + thisEntry, _, err := fetchCertBundleByIssuerId(ctx, req.Storage, issuer, false) if err != nil { return fmt.Errorf("error building CRLs: unable to fetch specified issuer (%v): %v", issuer, err) } @@ -351,7 +347,7 @@ func buildCRLs(ctx context.Context, b *backend, req *logical.Request, forceNew b // Fetch the cluster-local CRL mapping so we know where to write the // CRLs. - crlConfig, err := sc.getLocalCRLConfig() + crlConfig, err := getLocalCRLConfig(ctx, req.Storage) if err != nil { return fmt.Errorf("error building CRLs: unable to fetch cluster-local CRL configuration: %v", err) } @@ -417,7 +413,7 @@ func buildCRLs(ctx context.Context, b *backend, req *logical.Request, forceNew b crlConfig.CRLNumberMap[crlIdentifier] += 1 // Lastly, build the CRL. - if err := buildCRL(sc, forceNew, representative, revokedCerts, crlIdentifier, crlNumber); err != nil { + if err := buildCRL(ctx, b, req, forceNew, representative, revokedCerts, crlIdentifier, crlNumber); err != nil { return fmt.Errorf("error building CRLs: unable to build CRL for issuer (%v): %v", representative, err) } } @@ -466,7 +462,7 @@ func buildCRLs(ctx context.Context, b *backend, req *logical.Request, forceNew b // Finally, persist our potentially updated local CRL config. Only do this // if we didn't have a legacy CRL bundle. if !wasLegacy { - if err := sc.setLocalCRLConfig(crlConfig); err != nil { + if err := setLocalCRLConfig(ctx, req.Storage, crlConfig); err != nil { return fmt.Errorf("error building CRLs: unable to persist updated cluster-local CRL config: %v", err) } } @@ -573,13 +569,13 @@ func getRevokedCertEntries(ctx context.Context, req *logical.Request, issuerIDCe // Builds a CRL by going through the list of revoked certificates and building // a new CRL with the stored revocation times and serial numbers. -func buildCRL(sc *storageContext, forceNew bool, thisIssuerId issuerID, revoked []pkix.RevokedCertificate, identifier crlID, crlNumber int64) error { - crlInfo, err := sc.Backend.CRL(sc.Context, sc.Storage) +func buildCRL(ctx context.Context, b *backend, req *logical.Request, forceNew bool, thisIssuerId issuerID, revoked []pkix.RevokedCertificate, identifier crlID, crlNumber int64) error { + crlInfo, err := b.CRL(ctx, req.Storage) if err != nil { return errutil.InternalError{Err: fmt.Sprintf("error fetching CRL config information: %s", err)} } - crlLifetime := sc.Backend.crlLifetime + crlLifetime := b.crlLifetime var revokedCerts []pkix.RevokedCertificate if crlInfo.Expiry != "" { @@ -607,7 +603,7 @@ func buildCRL(sc *storageContext, forceNew bool, thisIssuerId issuerID, revoked revokedCerts = revoked WRITE: - signingBundle, caErr := sc.fetchCAInfoByIssuerId(thisIssuerId, CRLSigningUsage) + signingBundle, caErr := fetchCAInfoByIssuerId(ctx, b, req, thisIssuerId, CRLSigningUsage) if caErr != nil { switch caErr.(type) { case errutil.UserError: @@ -622,7 +618,6 @@ WRITE: Number: big.NewInt(crlNumber), ThisUpdate: time.Now(), NextUpdate: time.Now().Add(crlLifetime), - SignatureAlgorithm: signingBundle.RevocationSigAlg, } crlBytes, err := x509.CreateRevocationList(rand.Reader, revocationListTemplate, signingBundle.Certificate, signingBundle.PrivateKey) @@ -637,7 +632,7 @@ WRITE: writePath = legacyCRLPath } - err = sc.Storage.Put(sc.Context, &logical.StorageEntry{ + err = req.Storage.Put(ctx, &logical.StorageEntry{ Key: writePath, Value: crlBytes, }) diff --git a/builtin/logical/pki/fields.go b/builtin/logical/pki/fields.go index 3b6ed9773a5af..22100f3888923 100644 --- a/builtin/logical/pki/fields.go +++ b/builtin/logical/pki/fields.go @@ -319,13 +319,6 @@ SHA-2-512. Defaults to 0 to automatically detect based on key length }, } - fields["use_pss"] = &framework.FieldSchema{ - Type: framework.TypeBool, - Default: false, - Description: `Whether or not to use PSS signatures when using a -RSA key-type issuer. Defaults to false.`, - } - fields["key_type"] = &framework.FieldSchema{ Type: framework.TypeString, Default: "rsa", diff --git a/builtin/logical/pki/integation_test.go b/builtin/logical/pki/integation_test.go index ed2b45940baac..4f546b7ed854d 100644 --- a/builtin/logical/pki/integation_test.go +++ b/builtin/logical/pki/integation_test.go @@ -9,7 +9,6 @@ import ( ) func TestIntegration_RotateRootUsesNext(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) resp, err := b.HandleRequest(context.Background(), &logical.Request{ Operation: logical.UpdateOperation, @@ -76,7 +75,6 @@ func TestIntegration_RotateRootUsesNext(t *testing.T) { } func TestIntegration_ReplaceRootNormal(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) // generate roots @@ -114,7 +112,6 @@ func TestIntegration_ReplaceRootNormal(t *testing.T) { } func TestIntegration_ReplaceRootDefaultsToNext(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) // generate roots @@ -151,7 +148,6 @@ func TestIntegration_ReplaceRootDefaultsToNext(t *testing.T) { } func TestIntegration_ReplaceRootBadIssuer(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) // generate roots @@ -201,7 +197,6 @@ func TestIntegration_ReplaceRootBadIssuer(t *testing.T) { } func TestIntegration_SetSignedWithBackwardsPemBundles(t *testing.T) { - t.Parallel() rootBackend, rootStorage := createBackendWithStorage(t) intBackend, intStorage := createBackendWithStorage(t) diff --git a/builtin/logical/pki/key_util.go b/builtin/logical/pki/key_util.go index c40831714625e..8478bbc9987e2 100644 --- a/builtin/logical/pki/key_util.go +++ b/builtin/logical/pki/key_util.go @@ -9,10 +9,11 @@ import ( "github.com/hashicorp/vault/sdk/helper/certutil" "github.com/hashicorp/vault/sdk/helper/errutil" + "github.com/hashicorp/vault/sdk/logical" ) -func comparePublicKey(sc *storageContext, key *keyEntry, publicKey crypto.PublicKey) (bool, error) { - publicKeyForKeyEntry, err := getPublicKey(sc.Context, sc.Backend, key) +func comparePublicKey(ctx context.Context, b *backend, key *keyEntry, publicKey crypto.PublicKey) (bool, error) { + publicKeyForKeyEntry, err := getPublicKey(ctx, b, key) if err != nil { return false, err } @@ -75,7 +76,7 @@ func getPublicKeyFromBytes(keyBytes []byte) (crypto.PublicKey, error) { return signer.Public(), nil } -func importKeyFromBytes(sc *storageContext, keyValue string, keyName string) (*keyEntry, bool, error) { +func importKeyFromBytes(ctx context.Context, b *backend, s logical.Storage, keyValue string, keyName string) (*keyEntry, bool, error) { signer, _, _, err := getSignerFromBytes([]byte(keyValue)) if err != nil { return nil, false, err @@ -85,7 +86,7 @@ func importKeyFromBytes(sc *storageContext, keyValue string, keyName string) (*k return nil, false, errors.New("unsupported private key type within pem bundle") } - key, existed, err := sc.importKey(keyValue, keyName, privateKeyType) + key, existed, err := importKey(ctx, b, s, keyValue, keyName, privateKeyType) if err != nil { return nil, false, err } diff --git a/builtin/logical/pki/path_config_ca.go b/builtin/logical/pki/path_config_ca.go index dd2010e90684f..2dcc406209ac4 100644 --- a/builtin/logical/pki/path_config_ca.go +++ b/builtin/logical/pki/path_config_ca.go @@ -101,8 +101,7 @@ func (b *backend) pathCAIssuersRead(ctx context.Context, req *logical.Request, _ return logical.ErrorResponse("Cannot read defaults until migration has completed"), nil } - sc := b.makeStorageContext(ctx, req.Storage) - config, err := sc.getIssuersConfig() + config, err := getIssuersConfig(ctx, req.Storage) if err != nil { return logical.ErrorResponse("Error loading issuers configuration: " + err.Error()), nil } @@ -129,8 +128,7 @@ func (b *backend) pathCAIssuersWrite(ctx context.Context, req *logical.Request, return logical.ErrorResponse("Invalid issuer specification; must be non-empty and can't be 'default'."), nil } - sc := b.makeStorageContext(ctx, req.Storage) - parsedIssuer, err := sc.resolveIssuerReference(newDefault) + parsedIssuer, err := resolveIssuerReference(ctx, req.Storage, newDefault) if err != nil { return logical.ErrorResponse("Error resolving issuer reference: " + err.Error()), nil } @@ -141,7 +139,7 @@ func (b *backend) pathCAIssuersWrite(ctx context.Context, req *logical.Request, }, } - entry, err := sc.fetchIssuerById(parsedIssuer) + entry, err := fetchIssuerById(ctx, req.Storage, parsedIssuer) if err != nil { return logical.ErrorResponse("Unable to fetch issuer: " + err.Error()), nil } @@ -152,7 +150,7 @@ func (b *backend) pathCAIssuersWrite(ctx context.Context, req *logical.Request, b.Logger().Error(msg) } - err = sc.updateDefaultIssuerId(parsedIssuer) + err = updateDefaultIssuerId(ctx, req.Storage, parsedIssuer) if err != nil { return logical.ErrorResponse("Error updating issuer configuration: " + err.Error()), nil } @@ -206,8 +204,7 @@ func (b *backend) pathKeyDefaultRead(ctx context.Context, req *logical.Request, return logical.ErrorResponse("Cannot read key defaults until migration has completed"), nil } - sc := b.makeStorageContext(ctx, req.Storage) - config, err := sc.getKeysConfig() + config, err := getKeysConfig(ctx, req.Storage) if err != nil { return logical.ErrorResponse("Error loading keys configuration: " + err.Error()), nil } @@ -234,13 +231,12 @@ func (b *backend) pathKeyDefaultWrite(ctx context.Context, req *logical.Request, return logical.ErrorResponse("Invalid key specification; must be non-empty and can't be 'default'."), nil } - sc := b.makeStorageContext(ctx, req.Storage) - parsedKey, err := sc.resolveKeyReference(newDefault) + parsedKey, err := resolveKeyReference(ctx, req.Storage, newDefault) if err != nil { return logical.ErrorResponse("Error resolving issuer reference: " + err.Error()), nil } - err = sc.updateDefaultKeyId(parsedKey) + err = updateDefaultKeyId(ctx, req.Storage, parsedKey) if err != nil { return logical.ErrorResponse("Error updating issuer configuration: " + err.Error()), nil } diff --git a/builtin/logical/pki/path_config_crl.go b/builtin/logical/pki/path_config_crl.go index 3810c97e65931..5692e4eb5bbc6 100644 --- a/builtin/logical/pki/path_config_crl.go +++ b/builtin/logical/pki/path_config_crl.go @@ -12,7 +12,7 @@ import ( // CRLConfig holds basic CRL configuration information type crlConfig struct { - Expiry string `json:"expiry"` + Expiry string `json:"expiry" mapstructure:"expiry"` Disable bool `json:"disable"` } diff --git a/builtin/logical/pki/path_config_urls.go b/builtin/logical/pki/path_config_urls.go index 6162598730a8e..f27d541d6770f 100644 --- a/builtin/logical/pki/path_config_urls.go +++ b/builtin/logical/pki/path_config_urls.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/asaskevich/govalidator" + "github.com/fatih/structs" "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/helper/certutil" "github.com/hashicorp/vault/sdk/logical" @@ -57,8 +58,8 @@ func validateURLs(urls []string) string { return "" } -func getURLs(ctx context.Context, storage logical.Storage) (*certutil.URLEntries, error) { - entry, err := storage.Get(ctx, "urls") +func getURLs(ctx context.Context, req *logical.Request) (*certutil.URLEntries, error) { + entry, err := req.Storage.Get(ctx, "urls") if err != nil { return nil, err } @@ -80,7 +81,7 @@ func getURLs(ctx context.Context, storage logical.Storage) (*certutil.URLEntries return entries, nil } -func writeURLs(ctx context.Context, storage logical.Storage, entries *certutil.URLEntries) error { +func writeURLs(ctx context.Context, req *logical.Request, entries *certutil.URLEntries) error { entry, err := logical.StorageEntryJSON("urls", entries) if err != nil { return err @@ -89,7 +90,7 @@ func writeURLs(ctx context.Context, storage logical.Storage, entries *certutil.U return fmt.Errorf("unable to marshal entry into JSON") } - err = storage.Put(ctx, entry) + err = req.Storage.Put(ctx, entry) if err != nil { return err } @@ -98,24 +99,20 @@ func writeURLs(ctx context.Context, storage logical.Storage, entries *certutil.U } func (b *backend) pathReadURL(ctx context.Context, req *logical.Request, _ *framework.FieldData) (*logical.Response, error) { - entries, err := getURLs(ctx, req.Storage) + entries, err := getURLs(ctx, req) if err != nil { return nil, err } resp := &logical.Response{ - Data: map[string]interface{}{ - "issuing_certificates": entries.IssuingCertificates, - "crl_distribution_points": entries.CRLDistributionPoints, - "ocsp_servers": entries.OCSPServers, - }, + Data: structs.New(entries).Map(), } return resp, nil } func (b *backend) pathWriteURL(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { - entries, err := getURLs(ctx, req.Storage) + entries, err := getURLs(ctx, req) if err != nil { return nil, err } @@ -142,7 +139,7 @@ func (b *backend) pathWriteURL(ctx context.Context, req *logical.Request, data * } } - return nil, writeURLs(ctx, req.Storage, entries) + return nil, writeURLs(ctx, req, entries) } const pathConfigURLsHelpSyn = ` diff --git a/builtin/logical/pki/path_fetch.go b/builtin/logical/pki/path_fetch.go index 02afc7dc5f6b0..f4a2a6632c0f1 100644 --- a/builtin/logical/pki/path_fetch.go +++ b/builtin/logical/pki/path_fetch.go @@ -206,8 +206,7 @@ func (b *backend) pathFetchRead(ctx context.Context, req *logical.Request, data // Prefer fetchCAInfo to fetchCertBySerial for CA certificates. if serial == "ca_chain" || serial == "ca" { - sc := b.makeStorageContext(ctx, req.Storage) - caInfo, err := sc.fetchCAInfo(defaultRef, ReadOnlyUsage) + caInfo, err := fetchCAInfo(ctx, b, req, defaultRef, ReadOnlyUsage) if err != nil { switch err.(type) { case errutil.UserError: diff --git a/builtin/logical/pki/path_fetch_issuers.go b/builtin/logical/pki/path_fetch_issuers.go index 6049db52f63fe..352048783e6b2 100644 --- a/builtin/logical/pki/path_fetch_issuers.go +++ b/builtin/logical/pki/path_fetch_issuers.go @@ -2,7 +2,6 @@ package pki import ( "context" - "crypto/x509" "encoding/pem" "fmt" "strings" @@ -35,13 +34,12 @@ func (b *backend) pathListIssuersHandler(ctx context.Context, req *logical.Reque var responseKeys []string responseInfo := make(map[string]interface{}) - sc := b.makeStorageContext(ctx, req.Storage) - entries, err := sc.listIssuers() + entries, err := listIssuers(ctx, req.Storage) if err != nil { return nil, err } - config, err := sc.getIssuersConfig() + config, err := getIssuersConfig(ctx, req.Storage) if err != nil { return nil, err } @@ -50,7 +48,7 @@ func (b *backend) pathListIssuersHandler(ctx context.Context, req *logical.Reque // listIssuers), but also the name of the issuer. This means we have to // fetch the actual issuer object as well. for _, identifier := range entries { - issuer, err := sc.fetchIssuerById(identifier) + issuer, err := fetchIssuerById(ctx, req.Storage, identifier) if err != nil { return nil, err } @@ -107,17 +105,6 @@ this issuer; valid values are "read-only", "issuing-certificates", and and always set.`, Default: []string{"read-only", "issuing-certificates", "crl-signing"}, } - fields["revocation_signature_algorithm"] = &framework.FieldSchema{ - Type: framework.TypeString, - Description: `Which x509.SignatureAlgorithm name to use for -signing CRLs. This parameter allows differentiation between PKCS#1v1.5 -and PSS keys and choice of signature hash algorithm. The default (empty -string) value is for Go to select the signature algorithm. This can fail -if the underlying key does not support the requested signature algorithm, -which may not be known at modification time (such as with PKCS#11 managed -RSA keys).`, - Default: "", - } return &framework.Path{ // Returns a JSON entry. @@ -168,8 +155,7 @@ func (b *backend) pathGetIssuer(ctx context.Context, req *logical.Request, data return logical.ErrorResponse("missing issuer reference"), nil } - sc := b.makeStorageContext(ctx, req.Storage) - ref, err := sc.resolveIssuerReference(issuerName) + ref, err := resolveIssuerReference(ctx, req.Storage, issuerName) if err != nil { return nil, err } @@ -177,7 +163,7 @@ func (b *backend) pathGetIssuer(ctx context.Context, req *logical.Request, data return logical.ErrorResponse("unable to resolve issuer id for reference: " + issuerName), nil } - issuer, err := sc.fetchIssuerById(ref) + issuer, err := fetchIssuerById(ctx, req.Storage, ref) if err != nil { return nil, err } @@ -191,22 +177,16 @@ func respondReadIssuer(issuer *issuerEntry) (*logical.Response, error) { respManualChain = append(respManualChain, string(entity)) } - revSigAlgStr := issuer.RevocationSigAlg.String() - if issuer.RevocationSigAlg == x509.UnknownSignatureAlgorithm { - revSigAlgStr = "" - } - return &logical.Response{ Data: map[string]interface{}{ - "issuer_id": issuer.ID, - "issuer_name": issuer.Name, - "key_id": issuer.KeyID, - "certificate": issuer.Certificate, - "manual_chain": respManualChain, - "ca_chain": issuer.CAChain, - "leaf_not_after_behavior": issuer.LeafNotAfterBehavior.String(), - "usage": issuer.Usage.Names(), - "revocation_signature_algorithm": revSigAlgStr, + "issuer_id": issuer.ID, + "issuer_name": issuer.Name, + "key_id": issuer.KeyID, + "certificate": issuer.Certificate, + "manual_chain": respManualChain, + "ca_chain": issuer.CAChain, + "leaf_not_after_behavior": issuer.LeafNotAfterBehavior.String(), + "usage": issuer.Usage.Names(), }, }, nil } @@ -226,8 +206,7 @@ func (b *backend) pathUpdateIssuer(ctx context.Context, req *logical.Request, da return logical.ErrorResponse("missing issuer reference"), nil } - sc := b.makeStorageContext(ctx, req.Storage) - ref, err := sc.resolveIssuerReference(issuerName) + ref, err := resolveIssuerReference(ctx, req.Storage, issuerName) if err != nil { return nil, err } @@ -235,12 +214,12 @@ func (b *backend) pathUpdateIssuer(ctx context.Context, req *logical.Request, da return logical.ErrorResponse("unable to resolve issuer id for reference: " + issuerName), nil } - issuer, err := sc.fetchIssuerById(ref) + issuer, err := fetchIssuerById(ctx, req.Storage, ref) if err != nil { return nil, err } - newName, err := getIssuerName(sc, data) + newName, err := getIssuerName(ctx, req.Storage, data) if err != nil && err != errIssuerNameInUse { // If the error is name already in use, and the new name is the // old name for this issuer, we're not actually updating the @@ -276,23 +255,6 @@ func (b *backend) pathUpdateIssuer(ctx context.Context, req *logical.Request, da return logical.ErrorResponse(fmt.Sprintf("Unable to parse specified usages: %v - valid values are %v", rawUsage, AllIssuerUsages.Names())), nil } - // Revocation signature algorithm changes - revSigAlgStr := data.Get("revocation_signature_algorithm").(string) - revSigAlg, present := certutil.SignatureAlgorithmNames[strings.ToLower(revSigAlgStr)] - if !present && revSigAlgStr != "" { - var knownAlgos []string - for algoName := range certutil.SignatureAlgorithmNames { - knownAlgos = append(knownAlgos, algoName) - } - - return logical.ErrorResponse(fmt.Sprintf("Unknown signature algorithm value: %v - valid values are %v", revSigAlg, strings.Join(knownAlgos, ", "))), nil - } else if revSigAlgStr == "" { - revSigAlg = x509.UnknownSignatureAlgorithm - } - if err := issuer.CanMaybeSignWithAlgo(revSigAlg); err != nil { - return nil, err - } - modified := false var oldName string @@ -312,11 +274,6 @@ func (b *backend) pathUpdateIssuer(ctx context.Context, req *logical.Request, da modified = true } - if revSigAlg != issuer.RevocationSigAlg { - issuer.RevocationSigAlg = revSigAlg - modified = true - } - var updateChain bool var constructedChain []issuerID for index, newPathRef := range newPath { @@ -325,7 +282,7 @@ func (b *backend) pathUpdateIssuer(ctx context.Context, req *logical.Request, da newPathRef = string(ref) } - resolvedId, err := sc.resolveIssuerReference(newPathRef) + resolvedId, err := resolveIssuerReference(ctx, req.Storage, newPathRef) if err != nil { return nil, err } @@ -350,14 +307,14 @@ func (b *backend) pathUpdateIssuer(ctx context.Context, req *logical.Request, da // Building the chain will write the issuer to disk; no need to do it // twice. modified = false - err := sc.rebuildIssuersChains(issuer) + err := rebuildIssuersChains(ctx, req.Storage, issuer) if err != nil { return nil, err } } if modified { - err := sc.writeIssuer(issuer) + err := writeIssuer(ctx, req.Storage, issuer) if err != nil { return nil, err } @@ -365,7 +322,7 @@ func (b *backend) pathUpdateIssuer(ctx context.Context, req *logical.Request, da response, err := respondReadIssuer(issuer) if newName != oldName { - addWarningOnDereferencing(sc, oldName, response) + addWarningOnDereferencing(oldName, response, ctx, req.Storage) } return response, err @@ -387,8 +344,7 @@ func (b *backend) pathPatchIssuer(ctx context.Context, req *logical.Request, dat return logical.ErrorResponse("missing issuer reference"), nil } - sc := b.makeStorageContext(ctx, req.Storage) - ref, err := sc.resolveIssuerReference(issuerName) + ref, err := resolveIssuerReference(ctx, req.Storage, issuerName) if err != nil { return nil, err } @@ -396,7 +352,7 @@ func (b *backend) pathPatchIssuer(ctx context.Context, req *logical.Request, dat return logical.ErrorResponse("unable to resolve issuer id for reference: " + issuerName), nil } - issuer, err := sc.fetchIssuerById(ref) + issuer, err := fetchIssuerById(ctx, req.Storage, ref) if err != nil { return nil, err } @@ -409,7 +365,7 @@ func (b *backend) pathPatchIssuer(ctx context.Context, req *logical.Request, dat var oldName string var newName string if ok { - newName, err = getIssuerName(sc, data) + newName, err = getIssuerName(ctx, req.Storage, data) if err != nil && err != errIssuerNameInUse { // If the error is name already in use, and the new name is the // old name for this issuer, we're not actually updating the @@ -466,32 +422,6 @@ func (b *backend) pathPatchIssuer(ctx context.Context, req *logical.Request, dat } } - // Revocation signature algorithm changes - rawRevSigAlg, ok := data.GetOk("revocation_signature_algorithm") - if ok { - revSigAlgStr := rawRevSigAlg.(string) - revSigAlg, present := certutil.SignatureAlgorithmNames[strings.ToLower(revSigAlgStr)] - if !present && revSigAlgStr != "" { - var knownAlgos []string - for algoName := range certutil.SignatureAlgorithmNames { - knownAlgos = append(knownAlgos, algoName) - } - - return logical.ErrorResponse(fmt.Sprintf("Unknown signature algorithm value: %v - valid values are %v", revSigAlg, strings.Join(knownAlgos, ", "))), nil - } else if revSigAlgStr == "" { - revSigAlg = x509.UnknownSignatureAlgorithm - } - - if err := issuer.CanMaybeSignWithAlgo(revSigAlg); err != nil { - return nil, err - } - - if revSigAlg != issuer.RevocationSigAlg { - issuer.RevocationSigAlg = revSigAlg - modified = true - } - } - // Manual Chain Changes newPathData, ok := data.GetOk("manual_chain") if ok { @@ -504,7 +434,7 @@ func (b *backend) pathPatchIssuer(ctx context.Context, req *logical.Request, dat newPathRef = string(ref) } - resolvedId, err := sc.resolveIssuerReference(newPathRef) + resolvedId, err := resolveIssuerReference(ctx, req.Storage, newPathRef) if err != nil { return nil, err } @@ -529,7 +459,7 @@ func (b *backend) pathPatchIssuer(ctx context.Context, req *logical.Request, dat // Building the chain will write the issuer to disk; no need to do it // twice. modified = false - err := sc.rebuildIssuersChains(issuer) + err := rebuildIssuersChains(ctx, req.Storage, issuer) if err != nil { return nil, err } @@ -537,7 +467,7 @@ func (b *backend) pathPatchIssuer(ctx context.Context, req *logical.Request, dat } if modified { - err := sc.writeIssuer(issuer) + err := writeIssuer(ctx, req.Storage, issuer) if err != nil { return nil, err } @@ -545,7 +475,7 @@ func (b *backend) pathPatchIssuer(ctx context.Context, req *logical.Request, dat response, err := respondReadIssuer(issuer) if newName != oldName { - addWarningOnDereferencing(sc, oldName, response) + addWarningOnDereferencing(oldName, response, ctx, req.Storage) } return response, err @@ -561,8 +491,7 @@ func (b *backend) pathGetRawIssuer(ctx context.Context, req *logical.Request, da return logical.ErrorResponse("missing issuer reference"), nil } - sc := b.makeStorageContext(ctx, req.Storage) - ref, err := sc.resolveIssuerReference(issuerName) + ref, err := resolveIssuerReference(ctx, req.Storage, issuerName) if err != nil { return nil, err } @@ -570,7 +499,7 @@ func (b *backend) pathGetRawIssuer(ctx context.Context, req *logical.Request, da return logical.ErrorResponse("unable to resolve issuer id for reference: " + issuerName), nil } - issuer, err := sc.fetchIssuerById(ref) + issuer, err := fetchIssuerById(ctx, req.Storage, ref) if err != nil { return nil, err } @@ -631,8 +560,7 @@ func (b *backend) pathDeleteIssuer(ctx context.Context, req *logical.Request, da return logical.ErrorResponse("missing issuer reference"), nil } - sc := b.makeStorageContext(ctx, req.Storage) - ref, err := sc.resolveIssuerReference(issuerName) + ref, err := resolveIssuerReference(ctx, req.Storage, issuerName) if err != nil { // Return as if we deleted it if we fail to lookup the issuer. if ref == IssuerRefNotFound { @@ -643,28 +571,28 @@ func (b *backend) pathDeleteIssuer(ctx context.Context, req *logical.Request, da response := &logical.Response{} - issuer, err := sc.fetchIssuerById(ref) + issuer, err := fetchIssuerById(ctx, req.Storage, ref) if err != nil { return nil, err } if issuer.Name != "" { - addWarningOnDereferencing(sc, issuer.Name, response) + addWarningOnDereferencing(issuer.Name, response, ctx, req.Storage) } - addWarningOnDereferencing(sc, string(issuer.ID), response) + addWarningOnDereferencing(string(issuer.ID), response, ctx, req.Storage) - wasDefault, err := sc.deleteIssuer(ref) + wasDefault, err := deleteIssuer(ctx, req.Storage, ref) if err != nil { return nil, err } if wasDefault { response.AddWarning(fmt.Sprintf("Deleted issuer %v (via issuer_ref %v); this was configured as the default issuer. Operations without an explicit issuer will not work until a new default is configured.", ref, issuerName)) - addWarningOnDereferencing(sc, defaultRef, response) + addWarningOnDereferencing(defaultRef, response, ctx, req.Storage) } // Since we've deleted an issuer, the chains might've changed. Call the // rebuild code. We shouldn't technically err (as the issuer was deleted // successfully), but log a warning (and to the response) if this fails. - if err := sc.rebuildIssuersChains(nil); err != nil { + if err := rebuildIssuersChains(ctx, req.Storage, nil); err != nil { msg := fmt.Sprintf("Failed to rebuild remaining issuers' chains: %v", err) b.Logger().Error(msg) response.AddWarning(msg) @@ -673,8 +601,8 @@ func (b *backend) pathDeleteIssuer(ctx context.Context, req *logical.Request, da return response, nil } -func addWarningOnDereferencing(sc *storageContext, name string, resp *logical.Response) { - timeout, inUseBy, err := sc.checkForRolesReferencing(name) +func addWarningOnDereferencing(name string, resp *logical.Response, ctx context.Context, s logical.Storage) { + timeout, inUseBy, err := checkForRolesReferencing(name, ctx, s) if err != nil || timeout { if inUseBy == 0 { resp.AddWarning(fmt.Sprint("Unable to check if any roles referenced this issuer by ", name)) @@ -745,8 +673,7 @@ func (b *backend) pathGetIssuerCRL(ctx context.Context, req *logical.Request, da return nil, err } - sc := b.makeStorageContext(ctx, req.Storage) - crlPath, err := sc.resolveIssuerCRLPath(issuerName) + crlPath, err := resolveIssuerCRLPath(ctx, b, req.Storage, issuerName) if err != nil { return nil, err } diff --git a/builtin/logical/pki/path_fetch_keys.go b/builtin/logical/pki/path_fetch_keys.go index 2e718240dc8d4..8ce99b81f6753 100644 --- a/builtin/logical/pki/path_fetch_keys.go +++ b/builtin/logical/pki/path_fetch_keys.go @@ -41,19 +41,18 @@ func (b *backend) pathListKeysHandler(ctx context.Context, req *logical.Request, var responseKeys []string responseInfo := make(map[string]interface{}) - sc := b.makeStorageContext(ctx, req.Storage) - entries, err := sc.listKeys() + entries, err := listKeys(ctx, req.Storage) if err != nil { return nil, err } - config, err := sc.getKeysConfig() + config, err := getKeysConfig(ctx, req.Storage) if err != nil { return nil, err } for _, identifier := range entries { - key, err := sc.fetchKeyById(identifier) + key, err := fetchKeyById(ctx, req.Storage, identifier) if err != nil { return nil, err } @@ -135,8 +134,7 @@ func (b *backend) pathGetKeyHandler(ctx context.Context, req *logical.Request, d return logical.ErrorResponse("missing key reference"), nil } - sc := b.makeStorageContext(ctx, req.Storage) - keyId, err := sc.resolveKeyReference(keyRef) + keyId, err := resolveKeyReference(ctx, req.Storage, keyRef) if err != nil { return nil, err } @@ -144,7 +142,7 @@ func (b *backend) pathGetKeyHandler(ctx context.Context, req *logical.Request, d return logical.ErrorResponse("unable to resolve key id for reference" + keyRef), nil } - key, err := sc.fetchKeyById(keyId) + key, err := fetchKeyById(ctx, req.Storage, keyId) if err != nil { return nil, err } @@ -191,8 +189,7 @@ func (b *backend) pathUpdateKeyHandler(ctx context.Context, req *logical.Request return logical.ErrorResponse("missing key reference"), nil } - sc := b.makeStorageContext(ctx, req.Storage) - keyId, err := sc.resolveKeyReference(keyRef) + keyId, err := resolveKeyReference(ctx, req.Storage, keyRef) if err != nil { return nil, err } @@ -200,7 +197,7 @@ func (b *backend) pathUpdateKeyHandler(ctx context.Context, req *logical.Request return logical.ErrorResponse("unable to resolve key id for reference" + keyRef), nil } - key, err := sc.fetchKeyById(keyId) + key, err := fetchKeyById(ctx, req.Storage, keyId) if err != nil { return nil, err } @@ -213,7 +210,7 @@ func (b *backend) pathUpdateKeyHandler(ctx context.Context, req *logical.Request if newName != key.Name { key.Name = newName - err := sc.writeKey(*key) + err := writeKey(ctx, req.Storage, *key) if err != nil { return nil, err } @@ -249,8 +246,7 @@ func (b *backend) pathDeleteKeyHandler(ctx context.Context, req *logical.Request return logical.ErrorResponse("missing key reference"), nil } - sc := b.makeStorageContext(ctx, req.Storage) - keyId, err := sc.resolveKeyReference(keyRef) + keyId, err := resolveKeyReference(ctx, req.Storage, keyRef) if err != nil { if keyId == KeyRefNotFound { // We failed to lookup the key, we should ignore any error here and reply as if it was deleted. @@ -259,7 +255,7 @@ func (b *backend) pathDeleteKeyHandler(ctx context.Context, req *logical.Request return nil, err } - keyInUse, issuerId, err := sc.isKeyInUse(keyId.String()) + keyInUse, issuerId, err := isKeyInUse(keyId.String(), ctx, req.Storage) if err != nil { return nil, err } @@ -267,7 +263,7 @@ func (b *backend) pathDeleteKeyHandler(ctx context.Context, req *logical.Request return logical.ErrorResponse(fmt.Sprintf("Failed to Delete Key. Key in Use by Issuer: %s", issuerId)), nil } - wasDefault, err := sc.deleteKey(keyId) + wasDefault, err := deleteKey(ctx, req.Storage, keyId) if err != nil { return nil, err } diff --git a/builtin/logical/pki/path_intermediate.go b/builtin/logical/pki/path_intermediate.go index b33c22f36808a..bc388f4008869 100644 --- a/builtin/logical/pki/path_intermediate.go +++ b/builtin/logical/pki/path_intermediate.go @@ -66,26 +66,20 @@ func (b *backend) pathGenerateIntermediate(ctx context.Context, req *logical.Req // Nasty hack part two. :-) For generation of CSRs, certutil presently doesn't // support configuration of this. However, because we need generation parameters, // which create a role and attempt to read this parameter, we need to provide - // a value (which will be ignored). Hence, we stub in the missing parameters here, + // a value (which will be ignored). Hence, we stub in the missing parameter here, // including its schema, just enough for it to work.. data.Schema["signature_bits"] = &framework.FieldSchema{ Type: framework.TypeInt, Default: 0, } data.Raw["signature_bits"] = 0 - data.Schema["use_pss"] = &framework.FieldSchema{ - Type: framework.TypeBool, - Default: false, - } - data.Raw["use_pss"] = false - sc := b.makeStorageContext(ctx, req.Storage) - exported, format, role, errorResp := getGenerationParams(sc, data) + exported, format, role, errorResp := b.getGenerationParams(ctx, req.Storage, data) if errorResp != nil { return errorResp, nil } - keyName, err := getKeyName(sc, data) + keyName, err := getKeyName(ctx, req.Storage, data) if err != nil { return logical.ErrorResponse(err.Error()), nil } @@ -95,7 +89,7 @@ func (b *backend) pathGenerateIntermediate(ctx context.Context, req *logical.Req req: req, apiData: data, } - parsedBundle, err := generateIntermediateCSR(sc, input, b.Backend.GetRandomReader()) + parsedBundle, err := generateIntermediateCSR(ctx, b, input, b.Backend.GetRandomReader()) if err != nil { switch err.(type) { case errutil.UserError: @@ -114,7 +108,7 @@ func (b *backend) pathGenerateIntermediate(ctx context.Context, req *logical.Req Data: map[string]interface{}{}, } - entries, err := getURLs(ctx, req.Storage) + entries, err := getURLs(ctx, req) if err == nil && len(entries.OCSPServers) == 0 && len(entries.IssuingCertificates) == 0 && len(entries.CRLDistributionPoints) == 0 { // If the operator hasn't configured any of the URLs prior to // generating this issuer, we should add a warning to the response, @@ -155,7 +149,7 @@ func (b *backend) pathGenerateIntermediate(ctx context.Context, req *logical.Req } } - myKey, _, err := sc.importKey(csrb.PrivateKey, keyName, csrb.PrivateKeyType) + myKey, _, err := importKey(ctx, b, req.Storage, csrb.PrivateKey, keyName, csrb.PrivateKeyType) if err != nil { return nil, err } diff --git a/builtin/logical/pki/path_issue_sign.go b/builtin/logical/pki/path_issue_sign.go index 79b47bdf2bea2..17cdc93d835cc 100644 --- a/builtin/logical/pki/path_issue_sign.go +++ b/builtin/logical/pki/path_issue_sign.go @@ -139,25 +139,6 @@ this value to an empty list.`, Description: `A comma-separated string or list of extended key usage oids.`, } - ret.Fields["signature_bits"] = &framework.FieldSchema{ - Type: framework.TypeInt, - Default: 0, - Description: `The number of bits to use in the signature -algorithm; accepts 256 for SHA-2-256, 384 for SHA-2-384, and 512 for -SHA-2-512. Defaults to 0 to automatically detect based on key length -(SHA-2-256 for RSA keys, and matching the curve size for NIST P-Curves).`, - DisplayAttrs: &framework.DisplayAttributes{ - Value: 0, - }, - } - - ret.Fields["use_pss"] = &framework.FieldSchema{ - Type: framework.TypeBool, - Default: false, - Description: `Whether or not to use PSS signatures when using a -RSA key-type issuer. Defaults to false.`, - } - return ret } @@ -212,13 +193,10 @@ func (b *backend) pathSignVerbatim(ctx context.Context, req *logical.Request, da AllowedOtherSANs: []string{"*"}, AllowedSerialNumbers: []string{"*"}, AllowedURISANs: []string{"*"}, - CNValidations: []string{"disabled"}, GenerateLease: new(bool), KeyUsage: data.Get("key_usage").([]string), ExtKeyUsage: data.Get("ext_key_usage").([]string), ExtKeyUsageOIDs: data.Get("ext_key_usage_oids").([]string), - SignatureBits: data.Get("signature_bits").(int), - UsePSS: data.Get("use_pss").(bool), } *entry.AllowWildcardCertificates = true @@ -287,8 +265,7 @@ func (b *backend) pathIssueSignCert(ctx context.Context, req *logical.Request, d } var caErr error - sc := b.makeStorageContext(ctx, req.Storage) - signingBundle, caErr := sc.fetchCAInfo(issuerName, IssuanceUsage) + signingBundle, caErr := fetchCAInfo(ctx, b, req, issuerName, IssuanceUsage) if caErr != nil { switch caErr.(type) { case errutil.UserError: @@ -310,7 +287,7 @@ func (b *backend) pathIssueSignCert(ctx context.Context, req *logical.Request, d if useCSR { parsedBundle, err = signCert(b, input, signingBundle, false, useCSRValues) } else { - parsedBundle, err = generateCert(sc, input, signingBundle, false, rand.Reader) + parsedBundle, err = generateCert(ctx, b, input, signingBundle, false, rand.Reader) } if err != nil { switch err.(type) { diff --git a/builtin/logical/pki/path_manage_issuers.go b/builtin/logical/pki/path_manage_issuers.go index f6eb73bb1771a..32fc3374e4039 100644 --- a/builtin/logical/pki/path_manage_issuers.go +++ b/builtin/logical/pki/path_manage_issuers.go @@ -82,7 +82,6 @@ with Active Directory Certificate Services.`, // signed certificate's bits (that's on the /sign-intermediate // endpoints). Remove it from the list of fields to avoid confusion. delete(ret.Fields, "signature_bits") - delete(ret.Fields, "use_pss") return ret } @@ -192,6 +191,12 @@ func (b *backend) pathImportIssuers(ctx context.Context, req *logical.Request, d issuers = append(issuers, pemBlockString) case "CRL", "X509 CRL": // Ignore any CRL entries. + case "EC PARAMS", "EC PARAMETERS": + // Ignore any EC parameter entries. This is an optional block + // that some implementations send, to ensure some semblance of + // compatibility with weird curves. Go doesn't support custom + // curves and 99% of software doesn't either, so discard them + // without parsing them. default: // Otherwise, treat them as keys. keys = append(keys, pemBlockString) @@ -202,11 +207,9 @@ func (b *backend) pathImportIssuers(ctx context.Context, req *logical.Request, d return logical.ErrorResponse("private keys found in the PEM bundle but not allowed by the path; use /issuers/import/bundle"), nil } - sc := b.makeStorageContext(ctx, req.Storage) - for keyIndex, keyPem := range keys { // Handle import of private key. - key, existing, err := importKeyFromBytes(sc, keyPem, "") + key, existing, err := importKeyFromBytes(ctx, b, req.Storage, keyPem, "") if err != nil { return logical.ErrorResponse(fmt.Sprintf("Error parsing key %v: %v", keyIndex, err)), nil } @@ -217,7 +220,7 @@ func (b *backend) pathImportIssuers(ctx context.Context, req *logical.Request, d } for certIndex, certPem := range issuers { - cert, existing, err := sc.importIssuer(certPem, "") + cert, existing, err := importIssuer(ctx, b, req.Storage, certPem, "") if err != nil { return logical.ErrorResponse(fmt.Sprintf("Error parsing issuer %v: %v\n%v", certIndex, err, certPem)), nil } @@ -239,13 +242,6 @@ func (b *backend) pathImportIssuers(ctx context.Context, req *logical.Request, d if len(createdIssuers) > 0 { err := b.crlBuilder.rebuild(ctx, b, req, true) if err != nil { - // Before returning, check if the error message includes the - // string "PSS". If so, it indicates we might've wanted to modify - // this issuer, so convert the error to a warning. - if strings.Contains(err.Error(), "PSS") || strings.Contains(err.Error(), "pss") { - err = fmt.Errorf("Rebuilding the CRL failed with a message relating to the PSS signature algorithm. This likely means the revocation_signature_algorithm needs to be set on the newly imported issuer(s) because a managed key supports only the PSS algorithm; by default PKCS#1v1.5 was used to build the CRLs. CRLs will not be generated until this has been addressed, however the import was successful. The original error is reproduced below:\n\n\t%v", err) - } - return nil, err } } @@ -254,7 +250,7 @@ func (b *backend) pathImportIssuers(ctx context.Context, req *logical.Request, d // do this unconditionally if the issuer or key was modified, so the admin // is always warned. But if unrelated key material was imported, we do // not warn. - config, err := sc.getIssuersConfig() + config, err := getIssuersConfig(ctx, req.Storage) if err == nil && len(config.DefaultIssuerId) > 0 { // We can use the mapping above to check the issuer mapping. if keyId, ok := issuerKeyMap[string(config.DefaultIssuerId)]; ok && len(keyId) == 0 { @@ -288,13 +284,6 @@ func (b *backend) pathImportIssuers(ctx context.Context, req *logical.Request, d } } - // Also while we're here, we should let the user know the next steps. - // In particular, if there's no default AIA URLs configuration, we should - // tell the user that's probably next. - if entries, err := getURLs(ctx, req.Storage); err == nil && len(entries.IssuingCertificates) == 0 && len(entries.CRLDistributionPoints) == 0 && len(entries.OCSPServers) == 0 { - response.AddWarning("This mount hasn't configured any authority access information fields; this may make it harder for systems to find missing certificates in the chain or to validate revocation status of certificates. Consider updating /config/urls with this information.") - } - return response, nil } diff --git a/builtin/logical/pki/path_manage_keys.go b/builtin/logical/pki/path_manage_keys.go index 90119ce4e8a1e..264508e348600 100644 --- a/builtin/logical/pki/path_manage_keys.go +++ b/builtin/logical/pki/path_manage_keys.go @@ -80,8 +80,7 @@ func (b *backend) pathGenerateKeyHandler(ctx context.Context, req *logical.Reque return logical.ErrorResponse("Can not generate keys until migration has completed"), nil } - sc := b.makeStorageContext(ctx, req.Storage) - keyName, err := getKeyName(sc, data) + keyName, err := getKeyName(ctx, req.Storage, data) if err != nil { // Fail Immediately if Key Name is in Use, etc... return logical.ErrorResponse(err.Error()), nil } @@ -128,7 +127,7 @@ func (b *backend) pathGenerateKeyHandler(ctx context.Context, req *logical.Reque return nil, err } - key, _, err := sc.importKey(privateKeyPemString, keyName, keyBundle.PrivateKeyType) + key, _, err := importKey(ctx, b, req.Storage, privateKeyPemString, keyName, keyBundle.PrivateKeyType) if err != nil { return nil, err } @@ -189,9 +188,8 @@ func (b *backend) pathImportKeyHandler(ctx context.Context, req *logical.Request return logical.ErrorResponse("Cannot import keys until migration has completed"), nil } - sc := b.makeStorageContext(ctx, req.Storage) pemBundle := data.Get("pem_bundle").(string) - keyName, err := getKeyName(sc, data) + keyName, err := getKeyName(ctx, req.Storage, data) if err != nil { return logical.ErrorResponse(err.Error()), nil } @@ -231,7 +229,7 @@ func (b *backend) pathImportKeyHandler(ctx context.Context, req *logical.Request return logical.ErrorResponse("only a single key can be present within the pem_bundle for importing"), nil } - key, existed, err := importKeyFromBytes(sc, keys[0], keyName) + key, existed, err := importKeyFromBytes(ctx, b, req.Storage, keys[0], keyName) if err != nil { return logical.ErrorResponse(err.Error()), nil } diff --git a/builtin/logical/pki/path_manage_keys_test.go b/builtin/logical/pki/path_manage_keys_test.go index 979f8a203d4ab..b8a67d073c897 100644 --- a/builtin/logical/pki/path_manage_keys_test.go +++ b/builtin/logical/pki/path_manage_keys_test.go @@ -16,7 +16,6 @@ import ( ) func TestPKI_PathManageKeys_GenerateInternalKeys(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) tests := []struct { @@ -34,7 +33,6 @@ func TestPKI_PathManageKeys_GenerateInternalKeys(t *testing.T) { {"error-bad-type", "dskjfkdsfjdkf", []int{0}, true}, } for _, tt := range tests { - tt := tt for _, keyBitParam := range tt.keyBits { keyName := fmt.Sprintf("%s-%d", tt.name, keyBitParam) t.Run(keyName, func(t *testing.T) { @@ -81,7 +79,6 @@ func TestPKI_PathManageKeys_GenerateInternalKeys(t *testing.T) { } func TestPKI_PathManageKeys_GenerateExportedKeys(t *testing.T) { - t.Parallel() // We tested a lot of the logic above within the internal test, so just make sure we honor the exported contract b, s := createBackendWithStorage(t) @@ -114,7 +111,6 @@ func TestPKI_PathManageKeys_GenerateExportedKeys(t *testing.T) { } func TestPKI_PathManageKeys_ImportKeyBundle(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) bundle1, err := certutil.CreateKeyBundle("ec", 224, rand.Reader) @@ -247,7 +243,6 @@ func TestPKI_PathManageKeys_ImportKeyBundle(t *testing.T) { } func TestPKI_PathManageKeys_DeleteDefaultKeyWarns(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) resp, err := b.HandleRequest(context.Background(), &logical.Request{ @@ -275,7 +270,6 @@ func TestPKI_PathManageKeys_DeleteDefaultKeyWarns(t *testing.T) { } func TestPKI_PathManageKeys_DeleteUsedKeyFails(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) resp, err := b.HandleRequest(context.Background(), &logical.Request{ @@ -302,7 +296,6 @@ func TestPKI_PathManageKeys_DeleteUsedKeyFails(t *testing.T) { } func TestPKI_PathManageKeys_UpdateKeyDetails(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) resp, err := b.HandleRequest(context.Background(), &logical.Request{ @@ -355,7 +348,6 @@ func TestPKI_PathManageKeys_UpdateKeyDetails(t *testing.T) { } func TestPKI_PathManageKeys_ImportKeyBundleBadData(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) resp, err := b.HandleRequest(context.Background(), &logical.Request{ @@ -389,7 +381,6 @@ func TestPKI_PathManageKeys_ImportKeyBundleBadData(t *testing.T) { } func TestPKI_PathManageKeys_ImportKeyRejectsMultipleKeys(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) bundle1, err := certutil.CreateKeyBundle("ec", 224, rand.Reader) @@ -418,10 +409,9 @@ func TestPKI_PathManageKeys_ImportKeyRejectsMultipleKeys(t *testing.T) { require.True(t, resp.IsError(), "should have received an error response importing a pem bundle with more than 1 key") ctx := context.Background() - sc := b.makeStorageContext(ctx, s) - keys, _ := sc.listKeys() + keys, _ := listKeys(ctx, s) for _, keyId := range keys { - id, _ := sc.fetchKeyById(keyId) + id, _ := fetchKeyById(ctx, s, keyId) t.Logf("%s:%s", id.ID, id.Name) } } diff --git a/builtin/logical/pki/path_revoke.go b/builtin/logical/pki/path_revoke.go index fa061e4d48323..52c5c63e7837c 100644 --- a/builtin/logical/pki/path_revoke.go +++ b/builtin/logical/pki/path_revoke.go @@ -68,7 +68,7 @@ func (b *backend) pathRevokeWrite(ctx context.Context, req *logical.Request, dat // We store and identify by lowercase colon-separated hex, but other // utilities use dashes and/or uppercase, so normalize - serial = strings.ReplaceAll(strings.ToLower(serial), "-", ":") + serial = strings.Replace(strings.ToLower(serial), "-", ":", -1) b.revokeStorageLock.Lock() defer b.revokeStorageLock.Unlock() diff --git a/builtin/logical/pki/path_roles.go b/builtin/logical/pki/path_roles.go index f20c79eb53321..da446d65d107b 100644 --- a/builtin/logical/pki/path_roles.go +++ b/builtin/logical/pki/path_roles.go @@ -12,7 +12,6 @@ import ( "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/helper/certutil" "github.com/hashicorp/vault/sdk/helper/consts" - "github.com/hashicorp/vault/sdk/helper/errutil" "github.com/hashicorp/vault/sdk/logical" ) @@ -238,13 +237,6 @@ SHA-2-512. Defaults to 0 to automatically detect based on key length (SHA-2-256 for RSA keys, and matching the curve size for NIST P-Curves).`, }, - "use_pss": { - Type: framework.TypeBool, - Default: false, - Description: `Whether or not to use PSS signatures when using a -RSA key-type issuer. Defaults to false.`, - }, - "key_usage": { Type: framework.TypeCommaStringSlice, Default: []string{"DigitalSignature", "KeyAgreement", "KeyEncipherment"}, @@ -392,21 +384,6 @@ for "generate_lease".`, }, }, - "cn_validations": { - Type: framework.TypeCommaStringSlice, - Default: []string{"email", "hostname"}, - Description: `List of allowed validations to run against the -Common Name field. Values can include 'email' to validate the CN is a email -address, 'hostname' to validate the CN is a valid hostname (potentially -including wildcards). When multiple validations are specified, these take -OR semantics (either email OR hostname are allowed). The special value -'disabled' allows disabling all CN name validations, allowing for arbitrary -non-Hostname, non-Email address CNs.`, - DisplayAttrs: &framework.DisplayAttributes{ - Name: "Common Name Validations", - }, - }, - "policy_identifiers": { Type: framework.TypeCommaStringSlice, Description: `A comma-separated string or list of policy OIDs, or a JSON list of qualified policy @@ -588,18 +565,6 @@ func (b *backend) getRole(ctx context.Context, s logical.Storage, n string) (*ro modified = true } - // Update CN Validations to be the present default, "email,hostname" - if len(result.CNValidations) == 0 { - result.CNValidations = []string{"email", "hostname"} - modified = true - } - - // Ensure the role is valid after updating. - _, err = validateRole(b, &result, ctx, s) - if err != nil { - return nil, err - } - if modified && (b.System().LocalMount() || !b.System().ReplicationState().HasState(consts.ReplicationPerformanceSecondary)) { jsonEntry, err := logical.StorageEntryJSON("role/"+n, &result) if err != nil { @@ -680,7 +645,6 @@ func (b *backend) pathRoleCreate(ctx context.Context, req *logical.Request, data KeyType: data.Get("key_type").(string), KeyBits: data.Get("key_bits").(int), SignatureBits: data.Get("signature_bits").(int), - UsePSS: data.Get("use_pss").(bool), UseCSRCommonName: data.Get("use_csr_common_name").(bool), UseCSRSANs: data.Get("use_csr_sans").(bool), KeyUsage: data.Get("key_usage").([]string), @@ -696,7 +660,6 @@ func (b *backend) pathRoleCreate(ctx context.Context, req *logical.Request, data GenerateLease: new(bool), NoStore: data.Get("no_store").(bool), RequireCN: data.Get("require_cn").(bool), - CNValidations: data.Get("cn_validations").([]string), AllowedSerialNumbers: data.Get("allowed_serial_numbers").([]string), PolicyIdentifiers: getPolicyIdentifier(data, nil), BasicConstraintsValidForNonCA: data.Get("basic_constraints_valid_for_non_ca").(bool), @@ -735,9 +698,6 @@ func (b *backend) pathRoleCreate(ctx context.Context, req *logical.Request, data } } else { *entry.GenerateLease = data.Get("generate_lease").(bool) - if *entry.GenerateLease { - warning = "it is encouraged to disable generate_lease and rely on PKI's native capabilities when possible; this option can cause Vault-wide issues with large numbers of issued certificates" - } } resp, err := validateRole(b, entry, ctx, req.Storage) @@ -805,8 +765,7 @@ func validateRole(b *backend, entry *roleEntry, ctx context.Context, s logical.S } // Check that the issuers reference set resolves to something if !b.useLegacyBundleCaStorage() { - sc := b.makeStorageContext(ctx, s) - issuerId, err := sc.resolveIssuerReference(entry.Issuer) + issuerId, err := resolveIssuerReference(ctx, s, entry.Issuer) if err != nil { if issuerId == IssuerRefNotFound { resp = &logical.Response{} @@ -822,12 +781,6 @@ func validateRole(b *backend, entry *roleEntry, ctx context.Context, s logical.S } - // Ensures CNValidations are alright - entry.CNValidations, err = checkCNValidations(entry.CNValidations) - if err != nil { - return nil, errutil.UserError{Err: err.Error()} - } - return resp, nil } @@ -880,7 +833,6 @@ func (b *backend) pathRolePatch(ctx context.Context, req *logical.Request, data KeyType: getWithExplicitDefault(data, "key_type", oldEntry.KeyType).(string), KeyBits: getWithExplicitDefault(data, "key_bits", oldEntry.KeyBits).(int), SignatureBits: getWithExplicitDefault(data, "signature_bits", oldEntry.SignatureBits).(int), - UsePSS: getWithExplicitDefault(data, "use_pss", oldEntry.UsePSS).(bool), UseCSRCommonName: getWithExplicitDefault(data, "use_csr_common_name", oldEntry.UseCSRCommonName).(bool), UseCSRSANs: getWithExplicitDefault(data, "use_csr_sans", oldEntry.UseCSRSANs).(bool), KeyUsage: getWithExplicitDefault(data, "key_usage", oldEntry.KeyUsage).([]string), @@ -896,7 +848,6 @@ func (b *backend) pathRolePatch(ctx context.Context, req *logical.Request, data GenerateLease: new(bool), NoStore: getWithExplicitDefault(data, "no_store", oldEntry.NoStore).(bool), RequireCN: getWithExplicitDefault(data, "require_cn", oldEntry.RequireCN).(bool), - CNValidations: getWithExplicitDefault(data, "cn_validations", oldEntry.CNValidations).([]string), AllowedSerialNumbers: getWithExplicitDefault(data, "allowed_serial_numbers", oldEntry.AllowedSerialNumbers).([]string), PolicyIdentifiers: getPolicyIdentifier(data, &oldEntry.PolicyIdentifiers), BasicConstraintsValidForNonCA: getWithExplicitDefault(data, "basic_constraints_valid_for_non_ca", oldEntry.BasicConstraintsValidForNonCA).(bool), @@ -942,10 +893,6 @@ func (b *backend) pathRolePatch(ctx context.Context, req *logical.Request, data } else { entry.GenerateLease = oldEntry.GenerateLease } - - if *entry.GenerateLease { - warning = "it is encouraged to disable generate_lease and rely on PKI's native capabilities when possible; this option can cause Vault-wide issues with large numbers of issued certificates" - } } resp, err := validateRole(b, entry, ctx, req.Storage) @@ -1053,61 +1000,59 @@ func parseExtKeyUsages(role *roleEntry) certutil.CertExtKeyUsage { type roleEntry struct { LeaseMax string `json:"lease_max"` Lease string `json:"lease"` - DeprecatedMaxTTL string `json:"max_ttl"` - DeprecatedTTL string `json:"ttl"` - TTL time.Duration `json:"ttl_duration"` - MaxTTL time.Duration `json:"max_ttl_duration"` - AllowLocalhost bool `json:"allow_localhost"` - AllowedBaseDomain string `json:"allowed_base_domain"` + DeprecatedMaxTTL string `json:"max_ttl" mapstructure:"max_ttl"` + DeprecatedTTL string `json:"ttl" mapstructure:"ttl"` + TTL time.Duration `json:"ttl_duration" mapstructure:"ttl_duration"` + MaxTTL time.Duration `json:"max_ttl_duration" mapstructure:"max_ttl_duration"` + AllowLocalhost bool `json:"allow_localhost" mapstructure:"allow_localhost"` + AllowedBaseDomain string `json:"allowed_base_domain" mapstructure:"allowed_base_domain"` AllowedDomainsOld string `json:"allowed_domains,omitempty"` - AllowedDomains []string `json:"allowed_domains_list"` + AllowedDomains []string `json:"allowed_domains_list" mapstructure:"allowed_domains"` AllowedDomainsTemplate bool `json:"allowed_domains_template"` AllowBaseDomain bool `json:"allow_base_domain"` - AllowBareDomains bool `json:"allow_bare_domains"` - AllowTokenDisplayName bool `json:"allow_token_displayname"` - AllowSubdomains bool `json:"allow_subdomains"` - AllowGlobDomains bool `json:"allow_glob_domains"` - AllowWildcardCertificates *bool `json:"allow_wildcard_certificates,omitempty"` - AllowAnyName bool `json:"allow_any_name"` - EnforceHostnames bool `json:"enforce_hostnames"` - AllowIPSANs bool `json:"allow_ip_sans"` - ServerFlag bool `json:"server_flag"` - ClientFlag bool `json:"client_flag"` - CodeSigningFlag bool `json:"code_signing_flag"` - EmailProtectionFlag bool `json:"email_protection_flag"` - UseCSRCommonName bool `json:"use_csr_common_name"` - UseCSRSANs bool `json:"use_csr_sans"` - KeyType string `json:"key_type"` - KeyBits int `json:"key_bits"` - UsePSS bool `json:"use_pss"` - SignatureBits int `json:"signature_bits"` - MaxPathLength *int `json:",omitempty"` + AllowBareDomains bool `json:"allow_bare_domains" mapstructure:"allow_bare_domains"` + AllowTokenDisplayName bool `json:"allow_token_displayname" mapstructure:"allow_token_displayname"` + AllowSubdomains bool `json:"allow_subdomains" mapstructure:"allow_subdomains"` + AllowGlobDomains bool `json:"allow_glob_domains" mapstructure:"allow_glob_domains"` + AllowWildcardCertificates *bool `json:"allow_wildcard_certificates,omitempty" mapstructure:"allow_wildcard_certificates"` + AllowAnyName bool `json:"allow_any_name" mapstructure:"allow_any_name"` + EnforceHostnames bool `json:"enforce_hostnames" mapstructure:"enforce_hostnames"` + AllowIPSANs bool `json:"allow_ip_sans" mapstructure:"allow_ip_sans"` + ServerFlag bool `json:"server_flag" mapstructure:"server_flag"` + ClientFlag bool `json:"client_flag" mapstructure:"client_flag"` + CodeSigningFlag bool `json:"code_signing_flag" mapstructure:"code_signing_flag"` + EmailProtectionFlag bool `json:"email_protection_flag" mapstructure:"email_protection_flag"` + UseCSRCommonName bool `json:"use_csr_common_name" mapstructure:"use_csr_common_name"` + UseCSRSANs bool `json:"use_csr_sans" mapstructure:"use_csr_sans"` + KeyType string `json:"key_type" mapstructure:"key_type"` + KeyBits int `json:"key_bits" mapstructure:"key_bits"` + SignatureBits int `json:"signature_bits" mapstructure:"signature_bits"` + MaxPathLength *int `json:",omitempty" mapstructure:"max_path_length"` KeyUsageOld string `json:"key_usage,omitempty"` - KeyUsage []string `json:"key_usage_list"` - ExtKeyUsage []string `json:"extended_key_usage_list"` + KeyUsage []string `json:"key_usage_list" mapstructure:"key_usage"` + ExtKeyUsage []string `json:"extended_key_usage_list" mapstructure:"extended_key_usage"` OUOld string `json:"ou,omitempty"` - OU []string `json:"ou_list"` + OU []string `json:"ou_list" mapstructure:"ou"` OrganizationOld string `json:"organization,omitempty"` - Organization []string `json:"organization_list"` - Country []string `json:"country"` - Locality []string `json:"locality"` - Province []string `json:"province"` - StreetAddress []string `json:"street_address"` - PostalCode []string `json:"postal_code"` + Organization []string `json:"organization_list" mapstructure:"organization"` + Country []string `json:"country" mapstructure:"country"` + Locality []string `json:"locality" mapstructure:"locality"` + Province []string `json:"province" mapstructure:"province"` + StreetAddress []string `json:"street_address" mapstructure:"street_address"` + PostalCode []string `json:"postal_code" mapstructure:"postal_code"` GenerateLease *bool `json:"generate_lease,omitempty"` - NoStore bool `json:"no_store"` - RequireCN bool `json:"require_cn"` - CNValidations []string `json:"cn_validations"` - AllowedOtherSANs []string `json:"allowed_other_sans"` - AllowedSerialNumbers []string `json:"allowed_serial_numbers"` - AllowedURISANs []string `json:"allowed_uri_sans"` + NoStore bool `json:"no_store" mapstructure:"no_store"` + RequireCN bool `json:"require_cn" mapstructure:"require_cn"` + AllowedOtherSANs []string `json:"allowed_other_sans" mapstructure:"allowed_other_sans"` + AllowedSerialNumbers []string `json:"allowed_serial_numbers" mapstructure:"allowed_serial_numbers"` + AllowedURISANs []string `json:"allowed_uri_sans" mapstructure:"allowed_uri_sans"` AllowedURISANsTemplate bool `json:"allowed_uri_sans_template"` - PolicyIdentifiers []string `json:"policy_identifiers"` - ExtKeyUsageOIDs []string `json:"ext_key_usage_oids"` - BasicConstraintsValidForNonCA bool `json:"basic_constraints_valid_for_non_ca"` - NotBeforeDuration time.Duration `json:"not_before_duration"` - NotAfter string `json:"not_after"` - Issuer string `json:"issuer"` + PolicyIdentifiers []string `json:"policy_identifiers" mapstructure:"policy_identifiers"` + ExtKeyUsageOIDs []string `json:"ext_key_usage_oids" mapstructure:"ext_key_usage_oids"` + BasicConstraintsValidForNonCA bool `json:"basic_constraints_valid_for_non_ca" mapstructure:"basic_constraints_valid_for_non_ca"` + NotBeforeDuration time.Duration `json:"not_before_duration" mapstructure:"not_before_duration"` + NotAfter string `json:"not_after" mapstructure:"not_after"` + Issuer string `json:"issuer" mapstructure:"issuer"` } func (r *roleEntry) ToResponseData() map[string]interface{} { @@ -1135,7 +1080,6 @@ func (r *roleEntry) ToResponseData() map[string]interface{} { "key_type": r.KeyType, "key_bits": r.KeyBits, "signature_bits": r.SignatureBits, - "use_pss": r.UsePSS, "key_usage": r.KeyUsage, "ext_key_usage": r.ExtKeyUsage, "ext_key_usage_oids": r.ExtKeyUsageOIDs, @@ -1151,7 +1095,6 @@ func (r *roleEntry) ToResponseData() map[string]interface{} { "allowed_serial_numbers": r.AllowedSerialNumbers, "allowed_uri_sans": r.AllowedURISANs, "require_cn": r.RequireCN, - "cn_validations": r.CNValidations, "policy_identifiers": r.PolicyIdentifiers, "basic_constraints_valid_for_non_ca": r.BasicConstraintsValidForNonCA, "not_before_duration": int64(r.NotBeforeDuration.Seconds()), @@ -1167,52 +1110,6 @@ func (r *roleEntry) ToResponseData() map[string]interface{} { return responseData } -func checkCNValidations(validations []string) ([]string, error) { - var haveDisabled bool - var haveEmail bool - var haveHostname bool - - var result []string - - if len(validations) == 0 { - return []string{"email", "hostname"}, nil - } - - for _, validation := range validations { - switch strings.ToLower(validation) { - case "disabled": - if haveDisabled { - return nil, fmt.Errorf("cn_validations value incorrect: `disabled` specified multiple times") - } - haveDisabled = true - case "email": - if haveEmail { - return nil, fmt.Errorf("cn_validations value incorrect: `email` specified multiple times") - } - haveEmail = true - case "hostname": - if haveHostname { - return nil, fmt.Errorf("cn_validations value incorrect: `hostname` specified multiple times") - } - haveHostname = true - default: - return nil, fmt.Errorf("cn_validations value incorrect: unknown type: `%s`", validation) - } - - result = append(result, strings.ToLower(validation)) - } - - if !haveDisabled && !haveEmail && !haveHostname { - return nil, fmt.Errorf("cn_validations value incorrect: must specify a value (`email` and/or `hostname`) or `disabled`") - } - - if haveDisabled && (haveEmail || haveHostname) { - return nil, fmt.Errorf("cn_validations value incorrect: cannot specify `disabled` along with `email` or `hostname`") - } - - return result, nil -} - const pathListRolesHelpSyn = `List the existing roles in this backend` const pathListRolesHelpDesc = `Roles will be listed by the role name.` diff --git a/builtin/logical/pki/path_roles_test.go b/builtin/logical/pki/path_roles_test.go index 34952d4772209..97c465b27c7b5 100644 --- a/builtin/logical/pki/path_roles_test.go +++ b/builtin/logical/pki/path_roles_test.go @@ -8,16 +8,17 @@ import ( "encoding/pem" "fmt" "testing" + "time" "github.com/go-errors/errors" "github.com/hashicorp/go-secure-stdlib/strutil" "github.com/hashicorp/vault/sdk/logical" + "github.com/mitchellh/mapstructure" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestPki_RoleGenerateLease(t *testing.T) { - t.Parallel() var resp *logical.Response var err error b, storage := createBackendWithStorage(t) @@ -58,21 +59,22 @@ func TestPki_RoleGenerateLease(t *testing.T) { t.Fatalf("generate_lease should not be set by default") } - // To test upgrade of generate_lease, we read the storage entry, - // modify it to remove generate_lease, and rewrite it. - entry, err := storage.Get(context.Background(), "role/testrole") - if err != nil || entry == nil { - t.Fatal(err) - } - + // Update values due to switching of ttl type + resp.Data["ttl_duration"] = resp.Data["ttl"] + resp.Data["ttl"] = (time.Duration(resp.Data["ttl"].(int64)) * time.Second).String() + resp.Data["max_ttl_duration"] = resp.Data["max_ttl"] + resp.Data["max_ttl"] = (time.Duration(resp.Data["max_ttl"].(int64)) * time.Second).String() + // role.GenerateLease will be nil after the decode var role roleEntry - if err := entry.DecodeJSON(&role); err != nil { + err = mapstructure.Decode(resp.Data, &role) + if err != nil { t.Fatal(err) } + // Make it explicit role.GenerateLease = nil - entry, err = logical.StorageEntryJSON("role/testrole", role) + entry, err := logical.StorageEntryJSON("role/testrole", role) if err != nil { t.Fatal(err) } @@ -122,7 +124,6 @@ func TestPki_RoleGenerateLease(t *testing.T) { } func TestPki_RoleKeyUsage(t *testing.T) { - t.Parallel() var resp *logical.Response var err error b, storage := createBackendWithStorage(t) @@ -156,23 +157,26 @@ func TestPki_RoleKeyUsage(t *testing.T) { t.Fatalf("key_usage should have 2 values") } - // To test the upgrade of KeyUsageOld into KeyUsage, we read - // the storage entry, modify it to set KUO and unset KU, and - // rewrite it. - entry, err := storage.Get(context.Background(), "role/testrole") - if err != nil || entry == nil { - t.Fatal(err) - } - + // Update values due to switching of ttl type + resp.Data["ttl_duration"] = resp.Data["ttl"] + resp.Data["ttl"] = (time.Duration(resp.Data["ttl"].(int64)) * time.Second).String() + resp.Data["max_ttl_duration"] = resp.Data["max_ttl"] + resp.Data["max_ttl"] = (time.Duration(resp.Data["max_ttl"].(int64)) * time.Second).String() + // Check that old key usage value is nil var role roleEntry - if err := entry.DecodeJSON(&role); err != nil { + err = mapstructure.Decode(resp.Data, &role) + if err != nil { t.Fatal(err) } + if role.KeyUsageOld != "" { + t.Fatalf("old key usage storage value should be blank") + } + // Make it explicit role.KeyUsageOld = "KeyEncipherment,DigitalSignature" role.KeyUsage = nil - entry, err = logical.StorageEntryJSON("role/testrole", role) + entry, err := logical.StorageEntryJSON("role/testrole", role) if err != nil { t.Fatal(err) } @@ -213,7 +217,6 @@ func TestPki_RoleKeyUsage(t *testing.T) { } func TestPki_RoleOUOrganizationUpgrade(t *testing.T) { - t.Parallel() var resp *logical.Response var err error b, storage := createBackendWithStorage(t) @@ -252,23 +255,31 @@ func TestPki_RoleOUOrganizationUpgrade(t *testing.T) { t.Fatalf("organization should have 2 values") } - // To test upgrade of O/OU, we read the storage entry, modify it to set - // the old O/OU value over the new one, and rewrite it. - entry, err := storage.Get(context.Background(), "role/testrole") - if err != nil || entry == nil { - t.Fatal(err) - } - + // Update values due to switching of ttl type + resp.Data["ttl_duration"] = resp.Data["ttl"] + resp.Data["ttl"] = (time.Duration(resp.Data["ttl"].(int64)) * time.Second).String() + resp.Data["max_ttl_duration"] = resp.Data["max_ttl"] + resp.Data["max_ttl"] = (time.Duration(resp.Data["max_ttl"].(int64)) * time.Second).String() + // Check that old key usage value is nil var role roleEntry - if err := entry.DecodeJSON(&role); err != nil { + err = mapstructure.Decode(resp.Data, &role) + if err != nil { t.Fatal(err) } + if role.OUOld != "" { + t.Fatalf("old ou storage value should be blank") + } + if role.OrganizationOld != "" { + t.Fatalf("old organization storage value should be blank") + } + + // Make it explicit role.OUOld = "abc,123" role.OU = nil role.OrganizationOld = "org1,org2" role.Organization = nil - entry, err = logical.StorageEntryJSON("role/testrole", role) + entry, err := logical.StorageEntryJSON("role/testrole", role) if err != nil { t.Fatal(err) } @@ -319,7 +330,6 @@ func TestPki_RoleOUOrganizationUpgrade(t *testing.T) { } func TestPki_RoleAllowedDomains(t *testing.T) { - t.Parallel() var resp *logical.Response var err error b, storage := createBackendWithStorage(t) @@ -352,21 +362,26 @@ func TestPki_RoleAllowedDomains(t *testing.T) { t.Fatalf("allowed_domains should have 2 values") } - // To test upgrade of allowed_domains, we read the storage entry, - // set the old one, and rewrite it. - entry, err := storage.Get(context.Background(), "role/testrole") - if err != nil || entry == nil { - t.Fatal(err) - } - + // Update values due to switching of ttl type + resp.Data["ttl_duration"] = resp.Data["ttl"] + resp.Data["ttl"] = (time.Duration(resp.Data["ttl"].(int64)) * time.Second).String() + resp.Data["max_ttl_duration"] = resp.Data["max_ttl"] + resp.Data["max_ttl"] = (time.Duration(resp.Data["max_ttl"].(int64)) * time.Second).String() + // Check that old key usage value is nil var role roleEntry - if err := entry.DecodeJSON(&role); err != nil { + err = mapstructure.Decode(resp.Data, &role) + if err != nil { t.Fatal(err) } + if role.AllowedDomainsOld != "" { + t.Fatalf("old allowed_domains storage value should be blank") + } + + // Make it explicit role.AllowedDomainsOld = "foobar.com,*example.com" role.AllowedDomains = nil - entry, err = logical.StorageEntryJSON("role/testrole", role) + entry, err := logical.StorageEntryJSON("role/testrole", role) if err != nil { t.Fatal(err) } @@ -407,7 +422,6 @@ func TestPki_RoleAllowedDomains(t *testing.T) { } func TestPki_RoleAllowedURISANs(t *testing.T) { - t.Parallel() var resp *logical.Response var err error b, storage := createBackendWithStorage(t) @@ -442,7 +456,6 @@ func TestPki_RoleAllowedURISANs(t *testing.T) { } func TestPki_RolePkixFields(t *testing.T) { - t.Parallel() var resp *logical.Response var err error b, storage := createBackendWithStorage(t) @@ -534,7 +547,6 @@ func TestPki_RolePkixFields(t *testing.T) { } func TestPki_RoleNoStore(t *testing.T) { - t.Parallel() var resp *logical.Response var err error b, storage := createBackendWithStorage(t) @@ -655,7 +667,6 @@ func TestPki_RoleNoStore(t *testing.T) { } func TestPki_CertsLease(t *testing.T) { - t.Parallel() var resp *logical.Response var err error b, storage := createBackendWithStorage(t) @@ -737,7 +748,6 @@ func TestPki_CertsLease(t *testing.T) { } func TestPki_RolePatch(t *testing.T) { - t.Parallel() type TestCase struct { Field string Before interface{} @@ -1017,7 +1027,6 @@ func TestPki_RolePatch(t *testing.T) { } func TestPKI_RolePolicyInformation_Flat(t *testing.T) { - t.Parallel() type TestCase struct { Input interface{} ASN interface{} diff --git a/builtin/logical/pki/path_root.go b/builtin/logical/pki/path_root.go index 7ef6151b8d6cd..28bc7d22aac7c 100644 --- a/builtin/logical/pki/path_root.go +++ b/builtin/logical/pki/path_root.go @@ -54,14 +54,13 @@ func (b *backend) pathCADeleteRoot(ctx context.Context, req *logical.Request, _ b.issuersLock.Lock() defer b.issuersLock.Unlock() - sc := b.makeStorageContext(ctx, req.Storage) if !b.useLegacyBundleCaStorage() { - issuers, err := sc.listIssuers() + issuers, err := listIssuers(ctx, req.Storage) if err != nil { return nil, err } - keys, err := sc.listKeys() + keys, err := listKeys(ctx, req.Storage) if err != nil { return nil, err } @@ -69,12 +68,12 @@ func (b *backend) pathCADeleteRoot(ctx context.Context, req *logical.Request, _ // Delete all issuers and keys. Ignore deleting the default since we're // explicitly deleting everything. for _, issuer := range issuers { - if _, err = sc.deleteIssuer(issuer); err != nil { + if _, err = deleteIssuer(ctx, req.Storage, issuer); err != nil { return nil, err } } for _, key := range keys { - if _, err = sc.deleteKey(key); err != nil { + if _, err = deleteKey(ctx, req.Storage, key); err != nil { return nil, err } } @@ -109,9 +108,7 @@ func (b *backend) pathCAGenerateRoot(ctx context.Context, req *logical.Request, return logical.ErrorResponse("Can not create root CA until migration has completed"), nil } - sc := b.makeStorageContext(ctx, req.Storage) - - exported, format, role, errorResp := getGenerationParams(sc, data) + exported, format, role, errorResp := b.getGenerationParams(ctx, req.Storage, data) if errorResp != nil { return errorResp, nil } @@ -122,7 +119,7 @@ func (b *backend) pathCAGenerateRoot(ctx context.Context, req *logical.Request, role.MaxPathLength = &maxPathLength } - issuerName, err := getIssuerName(sc, data) + issuerName, err := getIssuerName(ctx, req.Storage, data) if err != nil { return logical.ErrorResponse(err.Error()), nil } @@ -130,13 +127,13 @@ func (b *backend) pathCAGenerateRoot(ctx context.Context, req *logical.Request, // only do it if its not in use. if strings.HasPrefix(req.Path, "root/rotate/") && len(issuerName) == 0 { // err is nil when the issuer name is in use. - _, err = sc.resolveIssuerReference("next") + _, err = resolveIssuerReference(ctx, req.Storage, "next") if err != nil { issuerName = "next" } } - keyName, err := getKeyName(sc, data) + keyName, err := getKeyName(ctx, req.Storage, data) if err != nil { return logical.ErrorResponse(err.Error()), nil } @@ -146,7 +143,7 @@ func (b *backend) pathCAGenerateRoot(ctx context.Context, req *logical.Request, apiData: data, role: role, } - parsedBundle, err := generateCert(sc, input, nil, true, b.Backend.GetRandomReader()) + parsedBundle, err := generateCert(ctx, b, input, nil, true, b.Backend.GetRandomReader()) if err != nil { switch err.(type) { case errutil.UserError: @@ -184,7 +181,7 @@ func (b *backend) pathCAGenerateRoot(ctx context.Context, req *logical.Request, if len(parsedBundle.Certificate.OCSPServer) == 0 && len(parsedBundle.Certificate.IssuingCertificateURL) == 0 && len(parsedBundle.Certificate.CRLDistributionPoints) == 0 { // If the operator hasn't configured any of the URLs prior to // generating this issuer, we should add a warning to the response, - // informing them they might want to do so prior to issuing leaves. + // informing them they might want to do so and re-generate the issuer. resp.AddWarning("This mount hasn't configured any authority access information fields; this may make it harder for systems to find missing certificates in the chain or to validate revocation status of certificates. Consider updating /config/urls with this information.") } @@ -227,7 +224,7 @@ func (b *backend) pathCAGenerateRoot(ctx context.Context, req *logical.Request, } // Store it as the CA bundle - myIssuer, myKey, err := sc.writeCaBundle(cb, issuerName, keyName) + myIssuer, myKey, err := writeCaBundle(ctx, b, req.Storage, cb, issuerName, keyName) if err != nil { return nil, err } @@ -236,25 +233,6 @@ func (b *backend) pathCAGenerateRoot(ctx context.Context, req *logical.Request, resp.Data["key_id"] = myKey.ID resp.Data["key_name"] = myKey.Name - // Update the issuer to reflect the PSS status here for revocation; this - // allows CRL building to succeed if the root is using a managed key with - // only PSS support. - if input.role.KeyType == "rsa" && input.role.UsePSS { - // The one time that it is safe (and good) to copy the - // SignatureAlgorithm field off the certificate (for the purposes of - // detecting PSS support) is when we've freshly generated it AND it - // is a root (exactly this endpoint). - // - // For intermediates, this doesn't hold (not this endpoint) as that - // reflects the parent key's preferences. For imports, this doesn't - // hold as the old system might've allowed other signature types that - // the new system (whether Vault or a managed key) doesn't. - myIssuer.RevocationSigAlg = parsedBundle.Certificate.SignatureAlgorithm - if err := sc.writeIssuer(myIssuer); err != nil { - return nil, fmt.Errorf("unable to store PSS-updated issuer: %v", err) - } - } - // Also store it as just the certificate identified by serial number, so it // can be revoked err = req.Storage.Put(ctx, &logical.StorageEntry{ @@ -308,14 +286,11 @@ func (b *backend) pathIssuerSignIntermediate(ctx context.Context, req *logical.R AllowWildcardCertificates: new(bool), EnforceHostnames: false, KeyType: "any", - SignatureBits: data.Get("signature_bits").(int), - UsePSS: data.Get("use_pss").(bool), AllowedOtherSANs: []string{"*"}, AllowedSerialNumbers: []string{"*"}, AllowedURISANs: []string{"*"}, NotAfter: data.Get("not_after").(string), NotBeforeDuration: time.Duration(data.Get("not_before_duration").(int)) * time.Second, - CNValidations: []string{"disabled"}, } *role.AllowWildcardCertificates = true @@ -324,8 +299,7 @@ func (b *backend) pathIssuerSignIntermediate(ctx context.Context, req *logical.R } var caErr error - sc := b.makeStorageContext(ctx, req.Storage) - signingBundle, caErr := sc.fetchCAInfo(issuerName, IssuanceUsage) + signingBundle, caErr := fetchCAInfo(ctx, b, req, issuerName, IssuanceUsage) if caErr != nil { switch caErr.(type) { case errutil.UserError: @@ -484,8 +458,7 @@ func (b *backend) pathIssuerSignSelfIssued(ctx context.Context, req *logical.Req } var caErr error - sc := b.makeStorageContext(ctx, req.Storage) - signingBundle, caErr := sc.fetchCAInfo(issuerName, IssuanceUsage) + signingBundle, caErr := fetchCAInfo(ctx, b, req, issuerName, IssuanceUsage) if caErr != nil { switch caErr.(type) { case errutil.UserError: diff --git a/builtin/logical/pki/path_sign_issuers.go b/builtin/logical/pki/path_sign_issuers.go index cadbac5553f36..96b7666065bb4 100644 --- a/builtin/logical/pki/path_sign_issuers.go +++ b/builtin/logical/pki/path_sign_issuers.go @@ -7,15 +7,15 @@ import ( func pathIssuerSignIntermediate(b *backend) *framework.Path { pattern := "issuer/" + framework.GenericNameRegex(issuerRefParam) + "/sign-intermediate" - return buildPathIssuerSignIntermediateRaw(b, pattern) + return pathIssuerSignIntermediateRaw(b, pattern) } func pathSignIntermediate(b *backend) *framework.Path { pattern := "root/sign-intermediate" - return buildPathIssuerSignIntermediateRaw(b, pattern) + return pathIssuerSignIntermediateRaw(b, pattern) } -func buildPathIssuerSignIntermediateRaw(b *backend, pattern string) *framework.Path { +func pathIssuerSignIntermediateRaw(b *backend, pattern string) *framework.Path { fields := addIssuerRefField(map[string]*framework.FieldSchema{}) path := &framework.Path{ Pattern: pattern, @@ -55,43 +55,6 @@ the non-repudiation flag; into the issued certificate.`, } - fields["signature_bits"] = &framework.FieldSchema{ - Type: framework.TypeInt, - Default: 0, - Description: `The number of bits to use in the signature -algorithm; accepts 256 for SHA-2-256, 384 for SHA-2-384, and 512 for -SHA-2-512. Defaults to 0 to automatically detect based on key length -(SHA-2-256 for RSA keys, and matching the curve size for NIST P-Curves).`, - DisplayAttrs: &framework.DisplayAttributes{ - Value: 0, - }, - } - - fields["skid"] = &framework.FieldSchema{ - Type: framework.TypeString, - Default: "", - Description: `Value for the Subject Key Identifier field -(RFC 5280 Section 4.2.1.2). This value should ONLY be used when -cross-signing to mimic the existing certificate's SKID value; this -is necessary to allow certain TLS implementations (such as OpenSSL) -which use SKID/AKID matches in chain building to restrict possible -valid chains. - -Specified as a string in hex format. Default is empty, allowing -Vault to automatically calculate the SKID according to method one -in the above RFC section.`, - DisplayAttrs: &framework.DisplayAttributes{ - Value: "", - }, - } - - fields["use_pss"] = &framework.FieldSchema{ - Type: framework.TypeBool, - Default: false, - Description: `Whether or not to use PSS signatures when using a -RSA key-type issuer. Defaults to false.`, - } - return path } diff --git a/builtin/logical/pki/storage.go b/builtin/logical/pki/storage.go index 3019a09510371..f1ae918e80d68 100644 --- a/builtin/logical/pki/storage.go +++ b/builtin/logical/pki/storage.go @@ -56,10 +56,10 @@ const ( ) type keyEntry struct { - ID keyID `json:"id"` - Name string `json:"name"` - PrivateKeyType certutil.PrivateKeyType `json:"private_key_type"` - PrivateKey string `json:"private_key"` + ID keyID `json:"id" structs:"id" mapstructure:"id"` + Name string `json:"name" structs:"name" mapstructure:"name"` + PrivateKeyType certutil.PrivateKeyType `json:"private_key_type" structs:"private_key_type" mapstructure:"private_key_type"` + PrivateKey string `json:"private_key" structs:"private_key" mapstructure:"private_key"` } func (e keyEntry) getManagedKeyUUID() (UUIDKey, error) { @@ -136,47 +136,32 @@ func NewIssuerUsageFromNames(names []string) (issuerUsage, error) { } type issuerEntry struct { - ID issuerID `json:"id"` - Name string `json:"name"` - KeyID keyID `json:"key_id"` - Certificate string `json:"certificate"` - CAChain []string `json:"ca_chain"` - ManualChain []issuerID `json:"manual_chain"` - SerialNumber string `json:"serial_number"` - LeafNotAfterBehavior certutil.NotAfterBehavior `json:"not_after_behavior"` - Usage issuerUsage `json:"usage"` - RevocationSigAlg x509.SignatureAlgorithm `json:"revocation_signature_algorithm"` + ID issuerID `json:"id" structs:"id" mapstructure:"id"` + Name string `json:"name" structs:"name" mapstructure:"name"` + KeyID keyID `json:"key_id" structs:"key_id" mapstructure:"key_id"` + Certificate string `json:"certificate" structs:"certificate" mapstructure:"certificate"` + CAChain []string `json:"ca_chain" structs:"ca_chain" mapstructure:"ca_chain"` + ManualChain []issuerID `json:"manual_chain" structs:"manual_chain" mapstructure:"manual_chain"` + SerialNumber string `json:"serial_number" structs:"serial_number" mapstructure:"serial_number"` + LeafNotAfterBehavior certutil.NotAfterBehavior `json:"not_after_behavior" structs:"not_after_behavior" mapstructure:"not_after_behavior"` + Usage issuerUsage `json:"usage" structs:"usage" mapstructure:"usage"` } type localCRLConfigEntry struct { - IssuerIDCRLMap map[issuerID]crlID `json:"issuer_id_crl_map"` - CRLNumberMap map[crlID]int64 `json:"crl_number_map"` + IssuerIDCRLMap map[issuerID]crlID `json:"issuer_id_crl_map" structs:"issuer_id_crl_map" mapstructure:"issuer_id_crl_map"` + CRLNumberMap map[crlID]int64 `json:"crl_number_map" structs:"crl_number_map" mapstructure:"crl_number_map"` } type keyConfigEntry struct { - DefaultKeyId keyID `json:"default"` + DefaultKeyId keyID `json:"default" structs:"default" mapstructure:"default"` } type issuerConfigEntry struct { - DefaultIssuerId issuerID `json:"default"` + DefaultIssuerId issuerID `json:"default" structs:"default" mapstructure:"default"` } -type storageContext struct { - Context context.Context - Storage logical.Storage - Backend *backend -} - -func (b *backend) makeStorageContext(ctx context.Context, s logical.Storage) *storageContext { - return &storageContext{ - Context: ctx, - Storage: s, - Backend: b, - } -} - -func (sc *storageContext) listKeys() ([]keyID, error) { - strList, err := sc.Storage.List(sc.Context, keyPrefix) +func listKeys(ctx context.Context, s logical.Storage) ([]keyID, error) { + strList, err := s.List(ctx, keyPrefix) if err != nil { return nil, err } @@ -189,12 +174,12 @@ func (sc *storageContext) listKeys() ([]keyID, error) { return keyIds, nil } -func (sc *storageContext) fetchKeyById(keyId keyID) (*keyEntry, error) { +func fetchKeyById(ctx context.Context, s logical.Storage, keyId keyID) (*keyEntry, error) { if len(keyId) == 0 { return nil, errutil.InternalError{Err: fmt.Sprintf("unable to fetch pki key: empty key identifier")} } - entry, err := sc.Storage.Get(sc.Context, keyPrefix+keyId.String()) + entry, err := s.Get(ctx, keyPrefix+keyId.String()) if err != nil { return nil, errutil.InternalError{Err: fmt.Sprintf("unable to fetch pki key: %v", err)} } @@ -211,7 +196,7 @@ func (sc *storageContext) fetchKeyById(keyId keyID) (*keyEntry, error) { return &key, nil } -func (sc *storageContext) writeKey(key keyEntry) error { +func writeKey(ctx context.Context, s logical.Storage, key keyEntry) error { keyId := key.ID json, err := logical.StorageEntryJSON(keyPrefix+keyId.String(), key) @@ -219,11 +204,11 @@ func (sc *storageContext) writeKey(key keyEntry) error { return err } - return sc.Storage.Put(sc.Context, json) + return s.Put(ctx, json) } -func (sc *storageContext) deleteKey(id keyID) (bool, error) { - config, err := sc.getKeysConfig() +func deleteKey(ctx context.Context, s logical.Storage, id keyID) (bool, error) { + config, err := getKeysConfig(ctx, s) if err != nil { return false, err } @@ -232,15 +217,15 @@ func (sc *storageContext) deleteKey(id keyID) (bool, error) { if config.DefaultKeyId == id { wasDefault = true config.DefaultKeyId = keyID("") - if err := sc.setKeysConfig(config); err != nil { + if err := setKeysConfig(ctx, s, config); err != nil { return wasDefault, err } } - return wasDefault, sc.Storage.Delete(sc.Context, keyPrefix+id.String()) + return wasDefault, s.Delete(ctx, keyPrefix+id.String()) } -func (sc *storageContext) importKey(keyValue string, keyName string, keyType certutil.PrivateKeyType) (*keyEntry, bool, error) { +func importKey(ctx context.Context, b *backend, s logical.Storage, keyValue string, keyName string, keyType certutil.PrivateKeyType) (*keyEntry, bool, error) { // importKey imports the specified PEM-format key (from keyValue) into // the new PKI storage format. The first return field is a reference to // the new key; the second is whether or not the key already existed @@ -255,7 +240,7 @@ func (sc *storageContext) importKey(keyValue string, keyName string, keyType cer // Before we can import a known key, we first need to know if the key // exists in storage already. This means iterating through all known // keys and comparing their private value against this value. - knownKeys, err := sc.listKeys() + knownKeys, err := listKeys(ctx, s) if err != nil { return nil, false, err } @@ -267,7 +252,7 @@ func (sc *storageContext) importKey(keyValue string, keyName string, keyType cer if err != nil { return nil, false, errutil.InternalError{Err: fmt.Sprintf("failed extracting managed key uuid from key: %v", err)} } - pkForImportingKey, err = getManagedKeyPublicKey(sc.Context, sc.Backend, managedKeyUUID) + pkForImportingKey, err = getManagedKeyPublicKey(ctx, b, managedKeyUUID) if err != nil { return nil, false, err } @@ -280,11 +265,11 @@ func (sc *storageContext) importKey(keyValue string, keyName string, keyType cer foundExistingKeyWithName := false for _, identifier := range knownKeys { - existingKey, err := sc.fetchKeyById(identifier) + existingKey, err := fetchKeyById(ctx, s, identifier) if err != nil { return nil, false, err } - areEqual, err := comparePublicKey(sc, existingKey, pkForImportingKey) + areEqual, err := comparePublicKey(ctx, b, existingKey, pkForImportingKey) if err != nil { return nil, false, err } @@ -315,7 +300,7 @@ func (sc *storageContext) importKey(keyValue string, keyName string, keyType cer result.PrivateKeyType = keyType // Finally, we can write the key to storage. - if err := sc.writeKey(result); err != nil { + if err := writeKey(ctx, s, result); err != nil { return nil, false, err } @@ -323,19 +308,19 @@ func (sc *storageContext) importKey(keyValue string, keyName string, keyType cer // one of them has a missing KeyId link, and if so, point it back to // ourselves. We fetch the list of issuers up front, even when don't need // it, to give ourselves a better chance of succeeding below. - knownIssuers, err := sc.listIssuers() + knownIssuers, err := listIssuers(ctx, s) if err != nil { return nil, false, err } - issuerDefaultSet, err := sc.isDefaultIssuerSet() + issuerDefaultSet, err := isDefaultIssuerSet(ctx, s) if err != nil { return nil, false, err } // Now, for each issuer, try and compute the issuer<->key link if missing. for _, identifier := range knownIssuers { - existingIssuer, err := sc.fetchIssuerById(identifier) + existingIssuer, err := fetchIssuerById(ctx, s, identifier) if err != nil { return nil, false, err } @@ -363,14 +348,14 @@ func (sc *storageContext) importKey(keyValue string, keyName string, keyType cer // These public keys are equal, so this key entry must be the // corresponding private key to this issuer; update it accordingly. existingIssuer.KeyID = result.ID - if err := sc.writeIssuer(existingIssuer); err != nil { + if err := writeIssuer(ctx, s, existingIssuer); err != nil { return nil, false, err } // If there was no prior default value set and/or we had no known // issuers when we started, set this issuer as default. if !issuerDefaultSet { - err = sc.updateDefaultIssuerId(existingIssuer.ID) + err = updateDefaultIssuerId(ctx, s, existingIssuer.ID) if err != nil { return nil, false, err } @@ -381,12 +366,12 @@ func (sc *storageContext) importKey(keyValue string, keyName string, keyType cer // If there was no prior default value set and/or we had no known // keys when we started, set this key as default. - keyDefaultSet, err := sc.isDefaultKeySet() + keyDefaultSet, err := isDefaultKeySet(ctx, s) if err != nil { return nil, false, err } if len(knownKeys) == 0 || !keyDefaultSet { - if err = sc.updateDefaultKeyId(result.ID); err != nil { + if err = updateDefaultKeyId(ctx, s, result.ID); err != nil { return nil, false, err } } @@ -428,53 +413,8 @@ func (i issuerEntry) EnsureUsage(usage issuerUsage) error { return fmt.Errorf("unknown delta between usages: %v -> %v / for issuer [%v]", usage.Names(), i.Usage.Names(), issuerRef) } -func (i issuerEntry) CanMaybeSignWithAlgo(algo x509.SignatureAlgorithm) error { - // Hack: Go isn't kind enough expose its lovely signatureAlgorithmDetails - // informational struct for our usage. However, we don't want to actually - // fetch the private key and attempt a signature with this algo (as we'll - // mint new, previously unsigned material in the process that could maybe - // be potentially abused if it leaks). - // - // So... - // - // ...we maintain our own mapping of cert.PKI<->sigAlgos. Notably, we - // exclude DSA support as the PKI engine has never supported DSA keys. - if algo == x509.UnknownSignatureAlgorithm { - // Special cased to indicate upgrade and letting Go automatically - // chose the correct value. - return nil - } - - cert, err := i.GetCertificate() - if err != nil { - return fmt.Errorf("unable to parse issuer's potential signature algorithm types: %v", err) - } - - switch cert.PublicKeyAlgorithm { - case x509.RSA: - switch algo { - case x509.SHA256WithRSA, x509.SHA384WithRSA, x509.SHA512WithRSA, - x509.SHA256WithRSAPSS, x509.SHA384WithRSAPSS, - x509.SHA512WithRSAPSS: - return nil - } - case x509.ECDSA: - switch algo { - case x509.ECDSAWithSHA256, x509.ECDSAWithSHA384, x509.ECDSAWithSHA512: - return nil - } - case x509.Ed25519: - switch algo { - case x509.PureEd25519: - return nil - } - } - - return fmt.Errorf("unable to use issuer of type %v to sign with %v key type", cert.PublicKeyAlgorithm.String(), algo.String()) -} - -func (sc *storageContext) listIssuers() ([]issuerID, error) { - strList, err := sc.Storage.List(sc.Context, issuerPrefix) +func listIssuers(ctx context.Context, s logical.Storage) ([]issuerID, error) { + strList, err := s.List(ctx, issuerPrefix) if err != nil { return nil, err } @@ -487,10 +427,10 @@ func (sc *storageContext) listIssuers() ([]issuerID, error) { return issuerIds, nil } -func (sc *storageContext) resolveKeyReference(reference string) (keyID, error) { +func resolveKeyReference(ctx context.Context, s logical.Storage, reference string) (keyID, error) { if reference == defaultRef { // Handle fetching the default key. - config, err := sc.getKeysConfig() + config, err := getKeysConfig(ctx, s) if err != nil { return keyID("config-error"), err } @@ -503,7 +443,7 @@ func (sc *storageContext) resolveKeyReference(reference string) (keyID, error) { // Lookup by a direct get first to see if our reference is an ID, this is quick and cached. if len(reference) == uuidLength { - entry, err := sc.Storage.Get(sc.Context, keyPrefix+reference) + entry, err := s.Get(ctx, keyPrefix+reference) if err != nil { return keyID("key-read"), err } @@ -513,12 +453,12 @@ func (sc *storageContext) resolveKeyReference(reference string) (keyID, error) { } // ... than to pull all keys from storage. - keys, err := sc.listKeys() + keys, err := listKeys(ctx, s) if err != nil { return keyID("list-error"), err } for _, keyId := range keys { - key, err := sc.fetchKeyById(keyId) + key, err := fetchKeyById(ctx, s, keyId) if err != nil { return keyID("key-read"), err } @@ -533,12 +473,12 @@ func (sc *storageContext) resolveKeyReference(reference string) (keyID, error) { } // fetchIssuerById returns an issuerEntry based on issuerId, if none found an error is returned. -func (sc *storageContext) fetchIssuerById(issuerId issuerID) (*issuerEntry, error) { +func fetchIssuerById(ctx context.Context, s logical.Storage, issuerId issuerID) (*issuerEntry, error) { if len(issuerId) == 0 { return nil, errutil.InternalError{Err: fmt.Sprintf("unable to fetch pki issuer: empty issuer identifier")} } - entry, err := sc.Storage.Get(sc.Context, issuerPrefix+issuerId.String()) + entry, err := s.Get(ctx, issuerPrefix+issuerId.String()) if err != nil { return nil, errutil.InternalError{Err: fmt.Sprintf("unable to fetch pki issuer: %v", err)} } @@ -555,7 +495,7 @@ func (sc *storageContext) fetchIssuerById(issuerId issuerID) (*issuerEntry, erro return &issuer, nil } -func (sc *storageContext) writeIssuer(issuer *issuerEntry) error { +func writeIssuer(ctx context.Context, s logical.Storage, issuer *issuerEntry) error { issuerId := issuer.ID json, err := logical.StorageEntryJSON(issuerPrefix+issuerId.String(), issuer) @@ -563,11 +503,11 @@ func (sc *storageContext) writeIssuer(issuer *issuerEntry) error { return err } - return sc.Storage.Put(sc.Context, json) + return s.Put(ctx, json) } -func (sc *storageContext) deleteIssuer(id issuerID) (bool, error) { - config, err := sc.getIssuersConfig() +func deleteIssuer(ctx context.Context, s logical.Storage, id issuerID) (bool, error) { + config, err := getIssuersConfig(ctx, s) if err != nil { return false, err } @@ -576,15 +516,15 @@ func (sc *storageContext) deleteIssuer(id issuerID) (bool, error) { if config.DefaultIssuerId == id { wasDefault = true config.DefaultIssuerId = issuerID("") - if err := sc.setIssuersConfig(config); err != nil { + if err := setIssuersConfig(ctx, s, config); err != nil { return wasDefault, err } } - return wasDefault, sc.Storage.Delete(sc.Context, issuerPrefix+id.String()) + return wasDefault, s.Delete(ctx, issuerPrefix+id.String()) } -func (sc *storageContext) importIssuer(certValue string, issuerName string) (*issuerEntry, bool, error) { +func importIssuer(ctx context.Context, b *backend, s logical.Storage, certValue string, issuerName string) (*issuerEntry, bool, error) { // importIssuers imports the specified PEM-format certificate (from // certValue) into the new PKI storage format. The first return field is a // reference to the new issuer; the second is whether or not the issuer @@ -622,14 +562,14 @@ func (sc *storageContext) importIssuer(certValue string, issuerName string) (*is // Before we can import a known issuer, we first need to know if the issuer // exists in storage already. This means iterating through all known // issuers and comparing their private value against this value. - knownIssuers, err := sc.listIssuers() + knownIssuers, err := listIssuers(ctx, s) if err != nil { return nil, false, err } foundExistingIssuerWithName := false for _, identifier := range knownIssuers { - existingIssuer, err := sc.fetchIssuerById(identifier) + existingIssuer, err := fetchIssuerById(ctx, s, identifier) if err != nil { return nil, false, err } @@ -675,7 +615,7 @@ func (sc *storageContext) importIssuer(certValue string, issuerName string) (*is // one of them a public key matching this certificate, and if so, update our // link accordingly. We fetch the list of keys up front, even may not need // it, to give ourselves a better chance of succeeding below. - knownKeys, err := sc.listKeys() + knownKeys, err := listKeys(ctx, s) if err != nil { return nil, false, err } @@ -684,12 +624,12 @@ func (sc *storageContext) importIssuer(certValue string, issuerName string) (*is // writing issuer to storage as we won't need to update the key, only // the issuer. for _, identifier := range knownKeys { - existingKey, err := sc.fetchKeyById(identifier) + existingKey, err := fetchKeyById(ctx, s, identifier) if err != nil { return nil, false, err } - equal, err := comparePublicKey(sc, existingKey, issuerCert.PublicKey) + equal, err := comparePublicKey(ctx, b, existingKey, issuerCert.PublicKey) if err != nil { return nil, false, err } @@ -706,18 +646,18 @@ func (sc *storageContext) importIssuer(certValue string, issuerName string) (*is // Finally, rebuild the chains. In this process, because the provided // reference issuer is non-nil, we'll save this issuer to storage. - if err := sc.rebuildIssuersChains(&result); err != nil { + if err := rebuildIssuersChains(ctx, s, &result); err != nil { return nil, false, err } // If there was no prior default value set and/or we had no known // issuers when we started, set this issuer as default. - issuerDefaultSet, err := sc.isDefaultIssuerSet() + issuerDefaultSet, err := isDefaultIssuerSet(ctx, s) if err != nil { return nil, false, err } if (len(knownIssuers) == 0 || !issuerDefaultSet) && len(result.KeyID) != 0 { - if err = sc.updateDefaultIssuerId(result.ID); err != nil { + if err = updateDefaultIssuerId(ctx, s, result.ID); err != nil { return nil, false, err } } @@ -730,17 +670,17 @@ func areCertificatesEqual(cert1 *x509.Certificate, cert2 *x509.Certificate) bool return bytes.Compare(cert1.Raw, cert2.Raw) == 0 } -func (sc *storageContext) setLocalCRLConfig(mapping *localCRLConfigEntry) error { +func setLocalCRLConfig(ctx context.Context, s logical.Storage, mapping *localCRLConfigEntry) error { json, err := logical.StorageEntryJSON(storageLocalCRLConfig, mapping) if err != nil { return err } - return sc.Storage.Put(sc.Context, json) + return s.Put(ctx, json) } -func (sc *storageContext) getLocalCRLConfig() (*localCRLConfigEntry, error) { - entry, err := sc.Storage.Get(sc.Context, storageLocalCRLConfig) +func getLocalCRLConfig(ctx context.Context, s logical.Storage) (*localCRLConfigEntry, error) { + entry, err := s.Get(ctx, storageLocalCRLConfig) if err != nil { return nil, err } @@ -763,17 +703,17 @@ func (sc *storageContext) getLocalCRLConfig() (*localCRLConfigEntry, error) { return mapping, nil } -func (sc *storageContext) setKeysConfig(config *keyConfigEntry) error { +func setKeysConfig(ctx context.Context, s logical.Storage, config *keyConfigEntry) error { json, err := logical.StorageEntryJSON(storageKeyConfig, config) if err != nil { return err } - return sc.Storage.Put(sc.Context, json) + return s.Put(ctx, json) } -func (sc *storageContext) getKeysConfig() (*keyConfigEntry, error) { - entry, err := sc.Storage.Get(sc.Context, storageKeyConfig) +func getKeysConfig(ctx context.Context, s logical.Storage) (*keyConfigEntry, error) { + entry, err := s.Get(ctx, storageKeyConfig) if err != nil { return nil, err } @@ -788,17 +728,17 @@ func (sc *storageContext) getKeysConfig() (*keyConfigEntry, error) { return keyConfig, nil } -func (sc *storageContext) setIssuersConfig(config *issuerConfigEntry) error { +func setIssuersConfig(ctx context.Context, s logical.Storage, config *issuerConfigEntry) error { json, err := logical.StorageEntryJSON(storageIssuerConfig, config) if err != nil { return err } - return sc.Storage.Put(sc.Context, json) + return s.Put(ctx, json) } -func (sc *storageContext) getIssuersConfig() (*issuerConfigEntry, error) { - entry, err := sc.Storage.Get(sc.Context, storageIssuerConfig) +func getIssuersConfig(ctx context.Context, s logical.Storage) (*issuerConfigEntry, error) { + entry, err := s.Get(ctx, storageIssuerConfig) if err != nil { return nil, err } @@ -817,10 +757,10 @@ func (sc *storageContext) getIssuersConfig() (*issuerConfigEntry, error) { // returning the converted issuerID or an error if not found. This method will not properly resolve the // special legacyBundleShimID value as we do not want to confuse our special value and a user-provided name of the // same value. -func (sc *storageContext) resolveIssuerReference(reference string) (issuerID, error) { +func resolveIssuerReference(ctx context.Context, s logical.Storage, reference string) (issuerID, error) { if reference == defaultRef { // Handle fetching the default issuer. - config, err := sc.getIssuersConfig() + config, err := getIssuersConfig(ctx, s) if err != nil { return issuerID("config-error"), err } @@ -833,7 +773,7 @@ func (sc *storageContext) resolveIssuerReference(reference string) (issuerID, er // Lookup by a direct get first to see if our reference is an ID, this is quick and cached. if len(reference) == uuidLength { - entry, err := sc.Storage.Get(sc.Context, issuerPrefix+reference) + entry, err := s.Get(ctx, issuerPrefix+reference) if err != nil { return issuerID("issuer-read"), err } @@ -843,13 +783,13 @@ func (sc *storageContext) resolveIssuerReference(reference string) (issuerID, er } // ... than to pull all issuers from storage. - issuers, err := sc.listIssuers() + issuers, err := listIssuers(ctx, s) if err != nil { return issuerID("list-error"), err } for _, issuerId := range issuers { - issuer, err := sc.fetchIssuerById(issuerId) + issuer, err := fetchIssuerById(ctx, s, issuerId) if err != nil { return issuerID("issuer-read"), err } @@ -863,17 +803,17 @@ func (sc *storageContext) resolveIssuerReference(reference string) (issuerID, er return IssuerRefNotFound, errutil.UserError{Err: fmt.Sprintf("unable to find PKI issuer for reference: %v", reference)} } -func (sc *storageContext) resolveIssuerCRLPath(reference string) (string, error) { - if sc.Backend.useLegacyBundleCaStorage() { +func resolveIssuerCRLPath(ctx context.Context, b *backend, s logical.Storage, reference string) (string, error) { + if b.useLegacyBundleCaStorage() { return legacyCRLPath, nil } - issuer, err := sc.resolveIssuerReference(reference) + issuer, err := resolveIssuerReference(ctx, s, reference) if err != nil { return legacyCRLPath, err } - crlConfig, err := sc.getLocalCRLConfig() + crlConfig, err := getLocalCRLConfig(ctx, s) if err != nil { return legacyCRLPath, err } @@ -888,11 +828,11 @@ func (sc *storageContext) resolveIssuerCRLPath(reference string) (string, error) // Builds a certutil.CertBundle from the specified issuer identifier, // optionally loading the key or not. This method supports loading legacy // bundles using the legacyBundleShimID issuerId, and if no entry is found will return an error. -func (sc *storageContext) fetchCertBundleByIssuerId(id issuerID, loadKey bool) (*issuerEntry, *certutil.CertBundle, error) { +func fetchCertBundleByIssuerId(ctx context.Context, s logical.Storage, id issuerID, loadKey bool) (*issuerEntry, *certutil.CertBundle, error) { if id == legacyBundleShimID { // We have not completed the migration, or started a request in legacy mode, so // attempt to load the bundle from the legacy location - issuer, bundle, err := getLegacyCertBundle(sc.Context, sc.Storage) + issuer, bundle, err := getLegacyCertBundle(ctx, s) if err != nil { return nil, nil, err } @@ -903,7 +843,7 @@ func (sc *storageContext) fetchCertBundleByIssuerId(id issuerID, loadKey bool) ( return issuer, bundle, err } - issuer, err := sc.fetchIssuerById(id) + issuer, err := fetchIssuerById(ctx, s, id) if err != nil { return nil, nil, err } @@ -915,7 +855,7 @@ func (sc *storageContext) fetchCertBundleByIssuerId(id issuerID, loadKey bool) ( // Fetch the key if it exists. Sometimes we don't need the key immediately. if loadKey && issuer.KeyID != keyID("") { - key, err := sc.fetchKeyById(issuer.KeyID) + key, err := fetchKeyById(ctx, s, issuer.KeyID) if err != nil { return nil, nil, err } @@ -927,19 +867,19 @@ func (sc *storageContext) fetchCertBundleByIssuerId(id issuerID, loadKey bool) ( return issuer, &bundle, nil } -func (sc *storageContext) writeCaBundle(caBundle *certutil.CertBundle, issuerName string, keyName string) (*issuerEntry, *keyEntry, error) { - myKey, _, err := sc.importKey(caBundle.PrivateKey, keyName, caBundle.PrivateKeyType) +func writeCaBundle(ctx context.Context, b *backend, s logical.Storage, caBundle *certutil.CertBundle, issuerName string, keyName string) (*issuerEntry, *keyEntry, error) { + myKey, _, err := importKey(ctx, b, s, caBundle.PrivateKey, keyName, caBundle.PrivateKeyType) if err != nil { return nil, nil, err } - myIssuer, _, err := sc.importIssuer(caBundle.Certificate, issuerName) + myIssuer, _, err := importIssuer(ctx, b, s, caBundle.Certificate, issuerName) if err != nil { return nil, nil, err } for _, cert := range caBundle.CAChain { - if _, _, err = sc.importIssuer(cert, ""); err != nil { + if _, _, err = importIssuer(ctx, b, s, cert, ""); err != nil { return nil, nil, err } } @@ -967,14 +907,14 @@ func genUuid() string { return aUuid } -func (sc *storageContext) isKeyInUse(keyId string) (inUse bool, issuerId string, err error) { - knownIssuers, err := sc.listIssuers() +func isKeyInUse(keyId string, ctx context.Context, s logical.Storage) (inUse bool, issuerId string, err error) { + knownIssuers, err := listIssuers(ctx, s) if err != nil { return true, "", err } for _, issuerId := range knownIssuers { - issuerEntry, err := sc.fetchIssuerById(issuerId) + issuerEntry, err := fetchIssuerById(ctx, s, issuerId) if err != nil { return true, issuerId.String(), errutil.InternalError{Err: fmt.Sprintf("unable to fetch pki issuer: %v", err)} } @@ -989,8 +929,8 @@ func (sc *storageContext) isKeyInUse(keyId string) (inUse bool, issuerId string, return false, "", nil } -func (sc *storageContext) checkForRolesReferencing(issuerId string) (timeout bool, inUseBy int32, err error) { - roleEntries, err := sc.Storage.List(sc.Context, "role/") +func checkForRolesReferencing(issuerId string, ctx context.Context, storage logical.Storage) (timeout bool, inUseBy int32, err error) { + roleEntries, err := storage.List(ctx, "role/") if err != nil { return false, 0, err } @@ -999,7 +939,7 @@ func (sc *storageContext) checkForRolesReferencing(issuerId string) (timeout boo checkedRoles := 0 for _, roleName := range roleEntries { - entry, err := sc.Storage.Get(sc.Context, "role/"+roleName) + entry, err := storage.Get(ctx, "role/"+roleName) if err != nil { return false, 0, err } diff --git a/builtin/logical/pki/storage_migrations.go b/builtin/logical/pki/storage_migrations.go index c56815a3d27b2..e431f95e33fe6 100644 --- a/builtin/logical/pki/storage_migrations.go +++ b/builtin/logical/pki/storage_migrations.go @@ -21,11 +21,11 @@ const ( ) type legacyBundleMigrationLog struct { - Hash string `json:"hash"` - Created time.Time `json:"created"` - CreatedIssuer issuerID `json:"issuer_id"` - CreatedKey keyID `json:"key_id"` - MigrationVersion int `json:"migrationVersion"` + Hash string `json:"hash" structs:"hash" mapstructure:"hash"` + Created time.Time `json:"created" structs:"created" mapstructure:"created"` + CreatedIssuer issuerID `json:"issuer_id" structs:"issuer_id" mapstructure:"issuer_id"` + CreatedKey keyID `json:"key_id" structs:"key_id" mapstructure:"key_id"` + MigrationVersion int `json:"migrationVersion" structs:"migrationVersion" mapstructure:"migrationVersion"` } type migrationInfo struct { @@ -89,8 +89,7 @@ func migrateStorage(ctx context.Context, b *backend, s logical.Storage) error { migrationName := fmt.Sprintf("current-%d", time.Now().Unix()) b.Logger().Info("performing PKI migration to new keys/issuers layout") - sc := b.makeStorageContext(ctx, s) - anIssuer, aKey, err := sc.writeCaBundle(migrationInfo.legacyBundle, migrationName, migrationName) + anIssuer, aKey, err := writeCaBundle(ctx, b, s, migrationInfo.legacyBundle, migrationName, migrationName) if err != nil { return err } diff --git a/builtin/logical/pki/storage_migrations_test.go b/builtin/logical/pki/storage_migrations_test.go index 78ac24fb43795..c6382298075b4 100644 --- a/builtin/logical/pki/storage_migrations_test.go +++ b/builtin/logical/pki/storage_migrations_test.go @@ -12,11 +12,9 @@ import ( ) func Test_migrateStorageEmptyStorage(t *testing.T) { - t.Parallel() startTime := time.Now() ctx := context.Background() b, s := createBackendWithStorage(t) - sc := b.makeStorageContext(ctx, s) // Reset the version the helper above set to 1. b.pkiStorageVersion.Store(0) @@ -26,11 +24,11 @@ func Test_migrateStorageEmptyStorage(t *testing.T) { err := b.initialize(ctx, request) require.NoError(t, err) - issuerIds, err := sc.listIssuers() + issuerIds, err := listIssuers(ctx, s) require.NoError(t, err) require.Empty(t, issuerIds) - keyIds, err := sc.listKeys() + keyIds, err := listKeys(ctx, s) require.NoError(t, err) require.Empty(t, keyIds) @@ -61,12 +59,9 @@ func Test_migrateStorageEmptyStorage(t *testing.T) { } func Test_migrateStorageSimpleBundle(t *testing.T) { - t.Parallel() startTime := time.Now() ctx := context.Background() b, s := createBackendWithStorage(t) - sc := b.makeStorageContext(ctx, s) - // Reset the version the helper above set to 1. b.pkiStorageVersion.Store(0) require.True(t, b.useLegacyBundleCaStorage(), "pre migration we should have been told to use legacy storage.") @@ -82,11 +77,11 @@ func Test_migrateStorageSimpleBundle(t *testing.T) { require.NoError(t, err) require.NoError(t, err) - issuerIds, err := sc.listIssuers() + issuerIds, err := listIssuers(ctx, s) require.NoError(t, err) require.Equal(t, 1, len(issuerIds)) - keyIds, err := sc.listKeys() + keyIds, err := listKeys(ctx, s) require.NoError(t, err) require.Equal(t, 1, len(keyIds)) @@ -103,13 +98,13 @@ func Test_migrateStorageSimpleBundle(t *testing.T) { issuerId := issuerIds[0] keyId := keyIds[0] - issuer, err := sc.fetchIssuerById(issuerId) + issuer, err := fetchIssuerById(ctx, s, issuerId) require.NoError(t, err) require.True(t, strings.HasPrefix(issuer.Name, "current-"), "expected issuer name to start with current- was %s", issuer.Name) require.Equal(t, certutil.ErrNotAfterBehavior, issuer.LeafNotAfterBehavior) - key, err := sc.fetchKeyById(keyId) + key, err := fetchKeyById(ctx, s, keyId) require.NoError(t, err) require.True(t, strings.HasPrefix(key.Name, "current-"), "expected key name to start with current- was %s", key.Name) @@ -133,11 +128,11 @@ func Test_migrateStorageSimpleBundle(t *testing.T) { require.Equal(t, bundle, certBundle) // Make sure we setup the default values - keysConfig, err := sc.getKeysConfig() + keysConfig, err := getKeysConfig(ctx, s) require.NoError(t, err) require.Equal(t, &keyConfigEntry{DefaultKeyId: keyId}, keysConfig) - issuersConfig, err := sc.getIssuersConfig() + issuersConfig, err := getIssuersConfig(ctx, s) require.NoError(t, err) require.Equal(t, &issuerConfigEntry{DefaultIssuerId: issuerId}, issuersConfig) @@ -169,7 +164,6 @@ func Test_migrateStorageSimpleBundle(t *testing.T) { } func TestExpectedOpsWork_PreMigration(t *testing.T) { - t.Parallel() ctx := context.Background() b, s := createBackendWithStorage(t) // Reset the version the helper above set to 1. diff --git a/builtin/logical/pki/storage_test.go b/builtin/logical/pki/storage_test.go index 6adc2aa12495c..48337bb4e636b 100644 --- a/builtin/logical/pki/storage_test.go +++ b/builtin/logical/pki/storage_test.go @@ -14,16 +14,14 @@ import ( var ctx = context.Background() func Test_ConfigsRoundTrip(t *testing.T) { - t.Parallel() - b, s := createBackendWithStorage(t) - sc := b.makeStorageContext(ctx, s) + _, s := createBackendWithStorage(t) // Verify we handle nothing stored properly - keyConfigEmpty, err := sc.getKeysConfig() + keyConfigEmpty, err := getKeysConfig(ctx, s) require.NoError(t, err) require.Equal(t, &keyConfigEntry{}, keyConfigEmpty) - issuerConfigEmpty, err := sc.getIssuersConfig() + issuerConfigEmpty, err := getIssuersConfig(ctx, s) require.NoError(t, err) require.Equal(t, &issuerConfigEntry{}, issuerConfigEmpty) @@ -35,70 +33,66 @@ func Test_ConfigsRoundTrip(t *testing.T) { DefaultIssuerId: genIssuerId(), } - err = sc.setKeysConfig(origKeyConfig) + err = setKeysConfig(ctx, s, origKeyConfig) require.NoError(t, err) - err = sc.setIssuersConfig(origIssuerConfig) + err = setIssuersConfig(ctx, s, origIssuerConfig) require.NoError(t, err) - keyConfig, err := sc.getKeysConfig() + keyConfig, err := getKeysConfig(ctx, s) require.NoError(t, err) require.Equal(t, origKeyConfig, keyConfig) - issuerConfig, err := sc.getIssuersConfig() + issuerConfig, err := getIssuersConfig(ctx, s) require.NoError(t, err) require.Equal(t, origIssuerConfig, issuerConfig) } func Test_IssuerRoundTrip(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) - sc := b.makeStorageContext(ctx, s) issuer1, key1 := genIssuerAndKey(t, b, s) issuer2, key2 := genIssuerAndKey(t, b, s) // We get an error when issuer id not found - _, err := sc.fetchIssuerById(issuer1.ID) + _, err := fetchIssuerById(ctx, s, issuer1.ID) require.Error(t, err) // We get an error when key id not found - _, err = sc.fetchKeyById(key1.ID) + _, err = fetchKeyById(ctx, s, key1.ID) require.Error(t, err) // Now write out our issuers and keys - err = sc.writeKey(key1) + err = writeKey(ctx, s, key1) require.NoError(t, err) - err = sc.writeIssuer(&issuer1) + err = writeIssuer(ctx, s, &issuer1) require.NoError(t, err) - err = sc.writeKey(key2) + err = writeKey(ctx, s, key2) require.NoError(t, err) - err = sc.writeIssuer(&issuer2) + err = writeIssuer(ctx, s, &issuer2) require.NoError(t, err) - fetchedKey1, err := sc.fetchKeyById(key1.ID) + fetchedKey1, err := fetchKeyById(ctx, s, key1.ID) require.NoError(t, err) - fetchedIssuer1, err := sc.fetchIssuerById(issuer1.ID) + fetchedIssuer1, err := fetchIssuerById(ctx, s, issuer1.ID) require.NoError(t, err) require.Equal(t, &key1, fetchedKey1) require.Equal(t, &issuer1, fetchedIssuer1) - keys, err := sc.listKeys() + keys, err := listKeys(ctx, s) require.NoError(t, err) require.ElementsMatch(t, []keyID{key1.ID, key2.ID}, keys) - issuers, err := sc.listIssuers() + issuers, err := listIssuers(ctx, s) require.NoError(t, err) require.ElementsMatch(t, []issuerID{issuer1.ID, issuer2.ID}, issuers) } func Test_KeysIssuerImport(t *testing.T) { - t.Parallel() b, s := createBackendWithStorage(t) - sc := b.makeStorageContext(ctx, s) issuer1, key1 := genIssuerAndKey(t, b, s) issuer2, key2 := genIssuerAndKey(t, b, s) @@ -109,21 +103,21 @@ func Test_KeysIssuerImport(t *testing.T) { issuer1.ID = "" issuer1.KeyID = "" - key1Ref1, existing, err := sc.importKey(key1.PrivateKey, "key1", key1.PrivateKeyType) + key1Ref1, existing, err := importKey(ctx, b, s, key1.PrivateKey, "key1", key1.PrivateKeyType) require.NoError(t, err) require.False(t, existing) require.Equal(t, strings.TrimSpace(key1.PrivateKey), strings.TrimSpace(key1Ref1.PrivateKey)) // Make sure if we attempt to re-import the same private key, no import/updates occur. // So the existing flag should be set to true, and we do not update the existing Name field. - key1Ref2, existing, err := sc.importKey(key1.PrivateKey, "ignore-me", key1.PrivateKeyType) + key1Ref2, existing, err := importKey(ctx, b, s, key1.PrivateKey, "ignore-me", key1.PrivateKeyType) require.NoError(t, err) require.True(t, existing) require.Equal(t, key1.PrivateKey, key1Ref1.PrivateKey) require.Equal(t, key1Ref1.ID, key1Ref2.ID) require.Equal(t, key1Ref1.Name, key1Ref2.Name) - issuer1Ref1, existing, err := sc.importIssuer(issuer1.Certificate, "issuer1") + issuer1Ref1, existing, err := importIssuer(ctx, b, s, issuer1.Certificate, "issuer1") require.NoError(t, err) require.False(t, existing) require.Equal(t, strings.TrimSpace(issuer1.Certificate), strings.TrimSpace(issuer1Ref1.Certificate)) @@ -132,7 +126,7 @@ func Test_KeysIssuerImport(t *testing.T) { // Make sure if we attempt to re-import the same issuer, no import/updates occur. // So the existing flag should be set to true, and we do not update the existing Name field. - issuer1Ref2, existing, err := sc.importIssuer(issuer1.Certificate, "ignore-me") + issuer1Ref2, existing, err := importIssuer(ctx, b, s, issuer1.Certificate, "ignore-me") require.NoError(t, err) require.True(t, existing) require.Equal(t, strings.TrimSpace(issuer1.Certificate), strings.TrimSpace(issuer1Ref1.Certificate)) @@ -140,14 +134,14 @@ func Test_KeysIssuerImport(t *testing.T) { require.Equal(t, key1Ref1.ID, issuer1Ref2.KeyID) require.Equal(t, issuer1Ref1.Name, issuer1Ref2.Name) - err = sc.writeIssuer(&issuer2) + err = writeIssuer(ctx, s, &issuer2) require.NoError(t, err) - err = sc.writeKey(key2) + err = writeKey(ctx, s, key2) require.NoError(t, err) // Same double import tests as above, but make sure if the previous was created through writeIssuer not importIssuer. - issuer2Ref, existing, err := sc.importIssuer(issuer2.Certificate, "ignore-me") + issuer2Ref, existing, err := importIssuer(ctx, b, s, issuer2.Certificate, "ignore-me") require.NoError(t, err) require.True(t, existing) require.Equal(t, strings.TrimSpace(issuer2.Certificate), strings.TrimSpace(issuer2Ref.Certificate)) @@ -156,7 +150,7 @@ func Test_KeysIssuerImport(t *testing.T) { require.Equal(t, issuer2.KeyID, issuer2Ref.KeyID) // Same double import tests as above, but make sure if the previous was created through writeKey not importKey. - key2Ref, existing, err := sc.importKey(key2.PrivateKey, "ignore-me", key2.PrivateKeyType) + key2Ref, existing, err := importKey(ctx, b, s, key2.PrivateKey, "ignore-me", key2.PrivateKeyType) require.NoError(t, err) require.True(t, existing) require.Equal(t, key2.PrivateKey, key2Ref.PrivateKey) @@ -201,8 +195,7 @@ func genCertBundle(t *testing.T, b *backend, s logical.Storage) *certutil.CertBu "ttl": 3600, }, } - sc := b.makeStorageContext(ctx, s) - _, _, role, respErr := getGenerationParams(sc, apiData) + _, _, role, respErr := b.getGenerationParams(ctx, s, apiData) require.Nil(t, respErr) input := &inputBundle{ @@ -214,7 +207,7 @@ func genCertBundle(t *testing.T, b *backend, s logical.Storage) *certutil.CertBu apiData: apiData, role: role, } - parsedCertBundle, err := generateCert(sc, input, nil, true, b.GetRandomReader()) + parsedCertBundle, err := generateCert(ctx, b, input, nil, true, b.GetRandomReader()) require.NoError(t, err) certBundle, err := parsedCertBundle.ToCertBundle() diff --git a/builtin/logical/pki/test_helpers.go b/builtin/logical/pki/test_helpers.go index 80e9a7bc51951..e91dce2bbd11b 100644 --- a/builtin/logical/pki/test_helpers.go +++ b/builtin/logical/pki/test_helpers.go @@ -284,10 +284,6 @@ func CBWrite(b *backend, s logical.Storage, path string, data map[string]interfa return CBReq(b, s, logical.UpdateOperation, path, data) } -func CBPatch(b *backend, s logical.Storage, path string, data map[string]interface{}) (*logical.Response, error) { - return CBReq(b, s, logical.PatchOperation, path, data) -} - func CBList(b *backend, s logical.Storage, path string) (*logical.Response, error) { return CBReq(b, s, logical.ListOperation, path, make(map[string]interface{})) } diff --git a/builtin/logical/pki/util.go b/builtin/logical/pki/util.go index 35887d8585df4..f855e0d690651 100644 --- a/builtin/logical/pki/util.go +++ b/builtin/logical/pki/util.go @@ -1,6 +1,7 @@ package pki import ( + "context" "crypto" "fmt" "regexp" @@ -8,6 +9,8 @@ import ( "github.com/hashicorp/vault/sdk/helper/certutil" + "github.com/hashicorp/vault/sdk/logical" + "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/helper/errutil" @@ -26,11 +29,11 @@ var ( ) func normalizeSerial(serial string) string { - return strings.ReplaceAll(strings.ToLower(serial), ":", "-") + return strings.Replace(strings.ToLower(serial), ":", "-", -1) } func denormalizeSerial(serial string) string { - return strings.ReplaceAll(strings.ToLower(serial), "-", ":") + return strings.Replace(strings.ToLower(serial), "-", ":", -1) } func kmsRequested(input *inputBundle) bool { @@ -138,7 +141,7 @@ func getManagedKeyNameOrUUID(data *framework.FieldData) (name string, UUID strin return keyName, keyUUID, nil } -func getIssuerName(sc *storageContext, data *framework.FieldData) (string, error) { +func getIssuerName(ctx context.Context, s logical.Storage, data *framework.FieldData) (string, error) { issuerName := "" issuerNameIface, ok := data.GetOk("issuer_name") if ok { @@ -151,7 +154,7 @@ func getIssuerName(sc *storageContext, data *framework.FieldData) (string, error if !nameMatcher.MatchString(issuerName) { return issuerName, errutil.UserError{Err: "issuer name contained invalid characters"} } - issuerId, err := sc.resolveIssuerReference(issuerName) + issuerId, err := resolveIssuerReference(ctx, s, issuerName) if err == nil { return issuerName, errIssuerNameInUse } @@ -163,7 +166,7 @@ func getIssuerName(sc *storageContext, data *framework.FieldData) (string, error return issuerName, nil } -func getKeyName(sc *storageContext, data *framework.FieldData) (string, error) { +func getKeyName(ctx context.Context, s logical.Storage, data *framework.FieldData) (string, error) { keyName := "" keyNameIface, ok := data.GetOk(keyNameParam) if ok { @@ -176,7 +179,7 @@ func getKeyName(sc *storageContext, data *framework.FieldData) (string, error) { if !nameMatcher.MatchString(keyName) { return "", errutil.UserError{Err: "key name contained invalid characters"} } - keyId, err := sc.resolveKeyReference(keyName) + keyId, err := resolveKeyReference(ctx, s, keyName) if err == nil { return "", errKeyNameInUse } diff --git a/builtin/logical/postgresql/query.go b/builtin/logical/postgresql/query.go index e250a6fe3bda0..e4f7f59ddfccc 100644 --- a/builtin/logical/postgresql/query.go +++ b/builtin/logical/postgresql/query.go @@ -8,7 +8,7 @@ import ( // Query templates a query for us. func Query(tpl string, data map[string]string) string { for k, v := range data { - tpl = strings.ReplaceAll(tpl, fmt.Sprintf("{{%s}}", k), v) + tpl = strings.Replace(tpl, fmt.Sprintf("{{%s}}", k), v, -1) } return tpl diff --git a/builtin/logical/rabbitmq/backend_test.go b/builtin/logical/rabbitmq/backend_test.go index 89659796b5e5c..9e146750f2424 100644 --- a/builtin/logical/rabbitmq/backend_test.go +++ b/builtin/logical/rabbitmq/backend_test.go @@ -132,7 +132,7 @@ func TestBackend_roleCrud(t *testing.T) { func TestBackend_roleWithPasswordPolicy(t *testing.T) { if os.Getenv(logicaltest.TestEnvVar) == "" { - t.Skip(fmt.Sprintf("Acceptance tests skipped unless env %q set", logicaltest.TestEnvVar)) + t.Skip(fmt.Sprintf("Acceptance tests skipped unless env '%s' set", logicaltest.TestEnvVar)) return } diff --git a/builtin/logical/ssh/backend.go b/builtin/logical/ssh/backend.go index fe4f40b334c97..c7250d0361751 100644 --- a/builtin/logical/ssh/backend.go +++ b/builtin/logical/ssh/backend.go @@ -61,7 +61,6 @@ func Backend(conf *logical.BackendConfig) (*backend, error) { pathVerify(&b), pathConfigCA(&b), pathSign(&b), - pathIssue(&b), pathFetchPublicKey(&b), }, diff --git a/builtin/logical/ssh/backend_test.go b/builtin/logical/ssh/backend_test.go index 6f2741185702c..2664f6225c21a 100644 --- a/builtin/logical/ssh/backend_test.go +++ b/builtin/logical/ssh/backend_test.go @@ -340,147 +340,6 @@ func TestBackend_AllowedUsersTemplate_WithStaticPrefix(t *testing.T) { ) } -func TestBackend_DefaultUserTemplate(t *testing.T) { - testDefaultUserTemplate(t, - "{{ identity.entity.metadata.ssh_username }}", - testUserName, - map[string]string{ - "ssh_username": testUserName, - }, - ) -} - -func TestBackend_DefaultUserTemplate_WithStaticPrefix(t *testing.T) { - testDefaultUserTemplate(t, - "user-{{ identity.entity.metadata.ssh_username }}", - "user-"+testUserName, - map[string]string{ - "ssh_username": testUserName, - }, - ) -} - -func TestBackend_DefaultUserTemplateFalse_AllowedUsersTemplateTrue(t *testing.T) { - cluster, userpassToken := getSshCaTestCluster(t, testUserName) - defer cluster.Cleanup() - client := cluster.Cores[0].Client - - // set metadata "ssh_username" to userpass username - tokenLookupResponse, err := client.Logical().Write("/auth/token/lookup", map[string]interface{}{ - "token": userpassToken, - }) - if err != nil { - t.Fatal(err) - } - entityID := tokenLookupResponse.Data["entity_id"].(string) - _, err = client.Logical().Write("/identity/entity/id/"+entityID, map[string]interface{}{ - "metadata": map[string]string{ - "ssh_username": testUserName, - }, - }) - if err != nil { - t.Fatal(err) - } - - _, err = client.Logical().Write("ssh/roles/my-role", map[string]interface{}{ - "key_type": testCaKeyType, - "allow_user_certificates": true, - "default_user": "{{identity.entity.metadata.ssh_username}}", - // disable user templating but not allowed_user_template and the request should fail - "default_user_template": false, - "allowed_users": "{{identity.entity.metadata.ssh_username}}", - "allowed_users_template": true, - }) - if err != nil { - t.Fatal(err) - } - - // sign SSH key as userpass user - client.SetToken(userpassToken) - _, err = client.Logical().Write("ssh/sign/my-role", map[string]interface{}{ - "public_key": testCAPublicKey, - }) - if err == nil { - t.Errorf("signing request should fail when default_user is not in the allowed_users list, because allowed_users_template is true and default_user_template is not") - } - - expectedErrStr := "{{identity.entity.metadata.ssh_username}} is not a valid value for valid_principals" - if !strings.Contains(err.Error(), expectedErrStr) { - t.Errorf("expected error to include %q but it was: %q", expectedErrStr, err.Error()) - } -} - -func TestBackend_DefaultUserTemplateFalse_AllowedUsersTemplateFalse(t *testing.T) { - cluster, userpassToken := getSshCaTestCluster(t, testUserName) - defer cluster.Cleanup() - client := cluster.Cores[0].Client - - // set metadata "ssh_username" to userpass username - tokenLookupResponse, err := client.Logical().Write("/auth/token/lookup", map[string]interface{}{ - "token": userpassToken, - }) - if err != nil { - t.Fatal(err) - } - entityID := tokenLookupResponse.Data["entity_id"].(string) - _, err = client.Logical().Write("/identity/entity/id/"+entityID, map[string]interface{}{ - "metadata": map[string]string{ - "ssh_username": testUserName, - }, - }) - if err != nil { - t.Fatal(err) - } - - _, err = client.Logical().Write("ssh/roles/my-role", map[string]interface{}{ - "key_type": testCaKeyType, - "allow_user_certificates": true, - "default_user": "{{identity.entity.metadata.ssh_username}}", - "default_user_template": false, - "allowed_users": "{{identity.entity.metadata.ssh_username}}", - "allowed_users_template": false, - }) - if err != nil { - t.Fatal(err) - } - - // sign SSH key as userpass user - client.SetToken(userpassToken) - signResponse, err := client.Logical().Write("ssh/sign/my-role", map[string]interface{}{ - "public_key": testCAPublicKey, - }) - if err != nil { - t.Fatal(err) - } - - // check for the expected valid principals of certificate - signedKey := signResponse.Data["signed_key"].(string) - key, _ := base64.StdEncoding.DecodeString(strings.Split(signedKey, " ")[1]) - parsedKey, err := ssh.ParsePublicKey(key) - if err != nil { - t.Fatal(err) - } - actualPrincipals := parsedKey.(*ssh.Certificate).ValidPrincipals - if len(actualPrincipals) < 1 { - t.Fatal( - fmt.Sprintf("No ValidPrincipals returned: should have been %v", - []string{"{{identity.entity.metadata.ssh_username}}"}), - ) - } - if len(actualPrincipals) > 1 { - t.Error( - fmt.Sprintf("incorrect number ValidPrincipals, expected only 1: %v should be %v", - actualPrincipals, []string{"{{identity.entity.metadata.ssh_username}}"}), - ) - } - if actualPrincipals[0] != "{{identity.entity.metadata.ssh_username}}" { - t.Fatal( - fmt.Sprintf("incorrect ValidPrincipals: %v should be %v", - actualPrincipals, []string{"{{identity.entity.metadata.ssh_username}}"}), - ) - } -} - func newTestingFactory(t *testing.T) func(ctx context.Context, conf *logical.BackendConfig) (logical.Backend, error) { return func(ctx context.Context, conf *logical.BackendConfig) (logical.Backend, error) { defaultLeaseTTLVal := 2 * time.Minute @@ -1920,50 +1779,6 @@ func TestSSHBackend_ValidateNotBeforeDuration(t *testing.T) { logicaltest.Test(t, testCase) } -func TestSSHBackend_IssueSign(t *testing.T) { - config := logical.TestBackendConfig() - - b, err := Factory(context.Background(), config) - if err != nil { - t.Fatalf("Cannot create backend: %s", err) - } - - testCase := logicaltest.TestCase{ - LogicalBackend: b, - Steps: []logicaltest.TestStep{ - configCaStep(testCAPublicKey, testCAPrivateKey), - - createRoleStep("testing", map[string]interface{}{ - "key_type": "otp", - "default_user": "user", - }), - // Key pair not issued with invalid role key type - issueSSHKeyPairStep("testing", "rsa", 0, true, "role key type 'otp' not allowed to issue key pairs"), - - createRoleStep("testing", map[string]interface{}{ - "key_type": "ca", - "allow_user_key_ids": false, - "allow_user_certificates": true, - "allowed_user_key_lengths": map[string]interface{}{ - "ssh-rsa": []int{2048, 3072, 4096}, - "ecdsa-sha2-nistp521": 0, - "ed25519": 0, - }, - }), - // Key_type not in allowed_user_key_types_lengths - issueSSHKeyPairStep("testing", "ec", 256, true, "provided key_type value not in allowed_user_key_types"), - // Key_bits not in allowed_user_key_types_lengths for provided key_type - issueSSHKeyPairStep("testing", "rsa", 2560, true, "provided key_bits value not in list of role's allowed_user_key_types"), - // key_type `rsa` and key_bits `2048` successfully created - issueSSHKeyPairStep("testing", "rsa", 2048, false, ""), - // key_type `ed22519` and key_bits `0` successfully created - issueSSHKeyPairStep("testing", "ed25519", 0, false, ""), - }, - } - - logicaltest.Test(t, testCase) -} - func getSshCaTestCluster(t *testing.T, userIdentity string) (*vault.TestCluster, string) { coreConfig := &vault.CoreConfig{ CredentialBackends: map[string]logical.Factory{ @@ -2034,68 +1849,8 @@ func getSshCaTestCluster(t *testing.T, userIdentity string) (*vault.TestCluster, return cluster, userpassToken } -func testDefaultUserTemplate(t *testing.T, testDefaultUserTemplate string, - expectedValidPrincipal string, testEntityMetadata map[string]string, -) { - cluster, userpassToken := getSshCaTestCluster(t, testUserName) - defer cluster.Cleanup() - client := cluster.Cores[0].Client - - // set metadata "ssh_username" to userpass username - tokenLookupResponse, err := client.Logical().Write("/auth/token/lookup", map[string]interface{}{ - "token": userpassToken, - }) - if err != nil { - t.Fatal(err) - } - entityID := tokenLookupResponse.Data["entity_id"].(string) - _, err = client.Logical().Write("/identity/entity/id/"+entityID, map[string]interface{}{ - "metadata": testEntityMetadata, - }) - if err != nil { - t.Fatal(err) - } - - _, err = client.Logical().Write("ssh/roles/my-role", map[string]interface{}{ - "key_type": testCaKeyType, - "allow_user_certificates": true, - "default_user": testDefaultUserTemplate, - "default_user_template": true, - "allowed_users": testDefaultUserTemplate, - "allowed_users_template": true, - }) - if err != nil { - t.Fatal(err) - } - - // sign SSH key as userpass user - client.SetToken(userpassToken) - signResponse, err := client.Logical().Write("ssh/sign/my-role", map[string]interface{}{ - "public_key": testCAPublicKey, - }) - if err != nil { - t.Fatal(err) - } - - // check for the expected valid principals of certificate - signedKey := signResponse.Data["signed_key"].(string) - key, _ := base64.StdEncoding.DecodeString(strings.Split(signedKey, " ")[1]) - parsedKey, err := ssh.ParsePublicKey(key) - if err != nil { - t.Fatal(err) - } - actualPrincipals := parsedKey.(*ssh.Certificate).ValidPrincipals - if actualPrincipals[0] != expectedValidPrincipal { - t.Fatal( - fmt.Sprintf("incorrect ValidPrincipals: %v should be %v", - actualPrincipals, []string{expectedValidPrincipal}), - ) - } -} - func testAllowedUsersTemplate(t *testing.T, testAllowedUsersTemplate string, - expectedValidPrincipal string, testEntityMetadata map[string]string, -) { + expectedValidPrincipal string, testEntityMetadata map[string]string) { cluster, userpassToken := getSshCaTestCluster(t, testUserName) defer cluster.Cleanup() client := cluster.Cores[0].Client @@ -2174,8 +1929,7 @@ func signCertificateStep( role, keyID string, certType int, validPrincipals []string, criticalOptionPermissions, extensionPermissions map[string]string, ttl time.Duration, - requestParameters map[string]interface{}, -) logicaltest.TestStep { + requestParameters map[string]interface{}) logicaltest.TestStep { return logicaltest.TestStep{ Operation: logical.UpdateOperation, Path: "sign/" + role, @@ -2204,42 +1958,6 @@ func signCertificateStep( } } -func issueSSHKeyPairStep(role, keyType string, keyBits int, expectError bool, errorMsg string) logicaltest.TestStep { - return logicaltest.TestStep{ - Operation: logical.UpdateOperation, - Path: "issue/" + role, - Data: map[string]interface{}{ - "key_type": keyType, - "key_bits": keyBits, - }, - ErrorOk: true, - Check: func(resp *logical.Response) error { - if expectError { - var err error - if resp.Data["error"] != errorMsg { - err = fmt.Errorf("actual error message \"%s\" different from expected error message \"%s\"", resp.Data["error"], errorMsg) - } - - return err - } - - if resp.IsError() { - return fmt.Errorf("unexpected error response returned: %v", resp.Error()) - } - - if resp.Data["private_key_type"] != keyType { - return fmt.Errorf("response private_key_type (%s) does not match the provided key_type (%s)", resp.Data["private_key_type"], keyType) - } - - if resp.Data["signed_key"] == "" { - return errors.New("certificate/signed_key should not be empty") - } - - return nil - }, - } -} - func validateSSHCertificate(cert *ssh.Certificate, keyID string, certType int, validPrincipals []string, criticalOptionPermissions, extensionPermissions map[string]string, ttl time.Duration, ) error { diff --git a/builtin/logical/ssh/path_issue.go b/builtin/logical/ssh/path_issue.go deleted file mode 100644 index 77b644590fd04..0000000000000 --- a/builtin/logical/ssh/path_issue.go +++ /dev/null @@ -1,183 +0,0 @@ -package ssh - -import ( - "context" - "crypto/rand" - "errors" - "fmt" - - "github.com/hashicorp/vault/sdk/framework" - "github.com/hashicorp/vault/sdk/logical" -) - -type keySpecs struct { - Type string - Bits int -} - -func pathIssue(b *backend) *framework.Path { - return &framework.Path{ - Pattern: "issue/" + framework.GenericNameWithAtRegex("role"), - - Operations: map[logical.Operation]framework.OperationHandler{ - logical.UpdateOperation: &framework.PathOperation{ - Callback: b.pathIssue, - }, - }, - Fields: map[string]*framework.FieldSchema{ - "role": { - Type: framework.TypeString, - Description: `The desired role with configuration for this request.`, - }, - "key_type": { - Type: framework.TypeString, - Description: "Specifies the desired key type; must be `rsa`, `ed25519` or `ec`", - Default: "rsa", - }, - "key_bits": { - Type: framework.TypeInt, - Description: "Specifies the number of bits to use for the generated keys.", - Default: 0, - }, - "ttl": { - Type: framework.TypeDurationSecond, - Description: `The requested Time To Live for the SSH certificate; -sets the expiration date. If not specified -the role default, backend default, or system -default TTL is used, in that order. Cannot -be later than the role max TTL.`, - }, - "valid_principals": { - Type: framework.TypeString, - Description: `Valid principals, either usernames or hostnames, that the certificate should be signed for.`, - }, - "cert_type": { - Type: framework.TypeString, - Description: `Type of certificate to be created; either "user" or "host".`, - Default: "user", - }, - "key_id": { - Type: framework.TypeString, - Description: `Key id that the created certificate should have. If not specified, the display name of the token will be used.`, - }, - "critical_options": { - Type: framework.TypeMap, - Description: `Critical options that the certificate should be signed for.`, - }, - "extensions": { - Type: framework.TypeMap, - Description: `Extensions that the certificate should be signed for.`, - }, - }, - HelpSynopsis: pathIssueHelpSyn, - HelpDescription: pathIssueHelpDesc, - } -} - -func (b *backend) pathIssue(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) { - // Get the role - roleName := data.Get("role").(string) - role, err := b.getRole(ctx, req.Storage, roleName) - if err != nil { - return nil, err - } - if role == nil { - return logical.ErrorResponse(fmt.Sprintf("unknown role: %s", roleName)), nil - } - - if role.KeyType != "ca" { - return logical.ErrorResponse("role key type '%s' not allowed to issue key pairs", role.KeyType), nil - } - - // Validate and extract key specifications - keySpecs, err := extractKeySpecs(role, data) - if err != nil { - return logical.ErrorResponse(err.Error()), nil - } - - // Issue certificate - return b.pathIssueCertificate(ctx, req, data, role, keySpecs) -} - -func (b *backend) pathIssueCertificate(ctx context.Context, req *logical.Request, data *framework.FieldData, role *sshRole, keySpecs *keySpecs) (*logical.Response, error) { - publicKey, privateKey, err := generateSSHKeyPair(rand.Reader, keySpecs.Type, keySpecs.Bits) - if err != nil { - return nil, err - } - - // Sign key - userPublicKey, err := parsePublicSSHKey(publicKey) - if err != nil { - return logical.ErrorResponse(fmt.Sprintf("failed to parse public_key as SSH key: %s", err)), nil - } - - response, err := b.pathSignIssueCertificateHelper(ctx, req, data, role, userPublicKey) - if err != nil { - return nil, err - } - if response.IsError() { - return response, nil - } - - // Additional to sign response - response.Data["private_key"] = privateKey - response.Data["private_key_type"] = keySpecs.Type - - return response, nil -} - -func extractKeySpecs(role *sshRole, data *framework.FieldData) (*keySpecs, error) { - keyType := data.Get("key_type").(string) - keyBits := data.Get("key_bits").(int) - keySpecs := keySpecs{ - Type: keyType, - Bits: keyBits, - } - - keyTypeToMapKey := createKeyTypeToMapKey(keyType, keyBits) - - if len(role.AllowedUserKeyTypesLengths) != 0 { - var keyAllowed bool - var bitsAllowed bool - - keyTypeAliasesLoop: - for _, keyTypeAlias := range keyTypeToMapKey[keyType] { - allowedValues, allowed := role.AllowedUserKeyTypesLengths[keyTypeAlias] - if !allowed { - continue - } - keyAllowed = true - - for _, value := range allowedValues { - if value == keyBits { - bitsAllowed = true - break keyTypeAliasesLoop - } - } - } - - if !keyAllowed { - return nil, errors.New("provided key_type value not in allowed_user_key_types") - } - - if !bitsAllowed { - return nil, errors.New("provided key_bits value not in list of role's allowed_user_key_types") - } - } - - return &keySpecs, nil -} - -const pathIssueHelpSyn = ` -Request a certificate using a certain role with the provided details. -` - -const pathIssueHelpDesc = ` -This path allows requesting a certificate to be issued according to the -policy of the given role. The certificate will only be issued if the -requested details are allowed by the role policy. - -This path returns a certificate and a private key. If you want a workflow -that does not expose a private key, generate a CSR locally and use the -sign path instead. -` diff --git a/builtin/logical/ssh/path_issue_sign.go b/builtin/logical/ssh/path_issue_sign.go deleted file mode 100644 index d98b8100941de..0000000000000 --- a/builtin/logical/ssh/path_issue_sign.go +++ /dev/null @@ -1,554 +0,0 @@ -package ssh - -import ( - "context" - "crypto/dsa" - "crypto/ecdsa" - "crypto/ed25519" - "crypto/rand" - "crypto/rsa" - "crypto/sha256" - "errors" - "fmt" - "io" - "regexp" - "strconv" - "strings" - "time" - - "github.com/hashicorp/go-secure-stdlib/parseutil" - "github.com/hashicorp/vault/sdk/framework" - "github.com/hashicorp/vault/sdk/helper/certutil" - "github.com/hashicorp/vault/sdk/helper/strutil" - "github.com/hashicorp/vault/sdk/logical" - "golang.org/x/crypto/ssh" -) - -var containsTemplateRegex = regexp.MustCompile(`{{.+?}}`) - -var ecCurveBitsToAlgoName = map[int]string{ - 256: ssh.KeyAlgoECDSA256, - 384: ssh.KeyAlgoECDSA384, - 521: ssh.KeyAlgoECDSA521, -} - -// If the algorithm is not found, it could be that we have a curve -// that we haven't added a constant for yet. But they could allow it -// (assuming x/crypto/ssh can parse it) via setting a ec: -// mapping rather than using a named SSH key type, so erring out here -// isn't advisable. - -type creationBundle struct { - KeyID string - ValidPrincipals []string - PublicKey ssh.PublicKey - CertificateType uint32 - TTL time.Duration - Signer ssh.Signer - Role *sshRole - CriticalOptions map[string]string - Extensions map[string]string -} - -func (b *backend) pathSignIssueCertificateHelper(ctx context.Context, req *logical.Request, data *framework.FieldData, role *sshRole, publicKey ssh.PublicKey) (*logical.Response, error) { - // Note that these various functions always return "user errors" so we pass - // them as 4xx values - keyID, err := b.calculateKeyID(data, req, role, publicKey) - if err != nil { - return logical.ErrorResponse(err.Error()), nil - } - - certificateType, err := b.calculateCertificateType(data, role) - if err != nil { - return logical.ErrorResponse(err.Error()), nil - } - - var parsedPrincipals []string - if certificateType == ssh.HostCert { - parsedPrincipals, err = b.calculateValidPrincipals(data, req, role, "", role.AllowedDomains, validateValidPrincipalForHosts(role)) - if err != nil { - return logical.ErrorResponse(err.Error()), nil - } - } else { - defaultPrincipal := role.DefaultUser - if role.DefaultUserTemplate { - defaultPrincipal, err = b.renderPrincipal(role.DefaultUser, req) - if err != nil { - return nil, err - } - } - parsedPrincipals, err = b.calculateValidPrincipals(data, req, role, defaultPrincipal, role.AllowedUsers, strutil.StrListContains) - if err != nil { - return logical.ErrorResponse(err.Error()), nil - } - } - - ttl, err := b.calculateTTL(data, role) - if err != nil { - return logical.ErrorResponse(err.Error()), nil - } - - criticalOptions, err := b.calculateCriticalOptions(data, role) - if err != nil { - return logical.ErrorResponse(err.Error()), nil - } - - extensions, err := b.calculateExtensions(data, req, role) - if err != nil { - return logical.ErrorResponse(err.Error()), nil - } - - privateKeyEntry, err := caKey(ctx, req.Storage, caPrivateKey) - if err != nil { - return nil, fmt.Errorf("failed to read CA private key: %w", err) - } - if privateKeyEntry == nil || privateKeyEntry.Key == "" { - return nil, errors.New("failed to read CA private key") - } - - signer, err := ssh.ParsePrivateKey([]byte(privateKeyEntry.Key)) - if err != nil { - return nil, fmt.Errorf("failed to parse stored CA private key: %w", err) - } - - cBundle := creationBundle{ - KeyID: keyID, - PublicKey: publicKey, - Signer: signer, - ValidPrincipals: parsedPrincipals, - TTL: ttl, - CertificateType: certificateType, - Role: role, - CriticalOptions: criticalOptions, - Extensions: extensions, - } - - certificate, err := cBundle.sign() - if err != nil { - return nil, err - } - - signedSSHCertificate := ssh.MarshalAuthorizedKey(certificate) - if len(signedSSHCertificate) == 0 { - return nil, errors.New("error marshaling signed certificate") - } - - response := &logical.Response{ - Data: map[string]interface{}{ - "serial_number": strconv.FormatUint(certificate.Serial, 16), - "signed_key": string(signedSSHCertificate), - }, - } - - return response, nil -} - -func (b *backend) renderPrincipal(principal string, req *logical.Request) (string, error) { - // Look for templating markers {{ .* }} - matched := containsTemplateRegex.MatchString(principal) - if matched { - if req.EntityID != "" { - // Retrieve principal based on template + entityID from request. - renderedPrincipal, err := framework.PopulateIdentityTemplate(principal, req.EntityID, b.System()) - if err != nil { - return "", fmt.Errorf("template '%s' could not be rendered -> %s", principal, err) - } - return renderedPrincipal, nil - } - } - // Static principal - return principal, nil -} - -func (b *backend) calculateValidPrincipals(data *framework.FieldData, req *logical.Request, role *sshRole, defaultPrincipal, principalsAllowedByRole string, validatePrincipal func([]string, string) bool) ([]string, error) { - validPrincipals := "" - validPrincipalsRaw, ok := data.GetOk("valid_principals") - if ok { - validPrincipals = validPrincipalsRaw.(string) - } else { - validPrincipals = defaultPrincipal - } - - parsedPrincipals := strutil.RemoveDuplicates(strutil.ParseStringSlice(validPrincipals, ","), false) - // Build list of allowed Principals from template and static principalsAllowedByRole - var allowedPrincipals []string - for _, principal := range strutil.RemoveDuplicates(strutil.ParseStringSlice(principalsAllowedByRole, ","), false) { - if role.AllowedUsersTemplate { - rendered, err := b.renderPrincipal(principal, req) - if err != nil { - return nil, err - } - // Template returned a principal - allowedPrincipals = append(allowedPrincipals, rendered) - } else { - // Static principal - allowedPrincipals = append(allowedPrincipals, principal) - } - } - - switch { - case len(parsedPrincipals) == 0: - // There is nothing to process - return nil, nil - case len(allowedPrincipals) == 0: - // User has requested principals to be set, but role is not configured - // with any principals - return nil, fmt.Errorf("role is not configured to allow any principals") - default: - // Role was explicitly configured to allow any principal. - if principalsAllowedByRole == "*" { - return parsedPrincipals, nil - } - - for _, principal := range parsedPrincipals { - if !validatePrincipal(strutil.RemoveDuplicates(allowedPrincipals, false), principal) { - return nil, fmt.Errorf("%v is not a valid value for valid_principals", principal) - } - } - return parsedPrincipals, nil - } -} - -func validateValidPrincipalForHosts(role *sshRole) func([]string, string) bool { - return func(allowedPrincipals []string, validPrincipal string) bool { - for _, allowedPrincipal := range allowedPrincipals { - if allowedPrincipal == validPrincipal && role.AllowBareDomains { - return true - } - if role.AllowSubdomains && strings.HasSuffix(validPrincipal, "."+allowedPrincipal) { - return true - } - } - - return false - } -} - -func (b *backend) calculateCertificateType(data *framework.FieldData, role *sshRole) (uint32, error) { - requestedCertificateType := data.Get("cert_type").(string) - - var certificateType uint32 - switch requestedCertificateType { - case "user": - if !role.AllowUserCertificates { - return 0, errors.New("cert_type 'user' is not allowed by role") - } - certificateType = ssh.UserCert - case "host": - if !role.AllowHostCertificates { - return 0, errors.New("cert_type 'host' is not allowed by role") - } - certificateType = ssh.HostCert - default: - return 0, errors.New("cert_type must be either 'user' or 'host'") - } - - return certificateType, nil -} - -func (b *backend) calculateKeyID(data *framework.FieldData, req *logical.Request, role *sshRole, pubKey ssh.PublicKey) (string, error) { - reqID := data.Get("key_id").(string) - - if reqID != "" { - if !role.AllowUserKeyIDs { - return "", fmt.Errorf("setting key_id is not allowed by role") - } - return reqID, nil - } - - keyIDFormat := "vault-{{token_display_name}}-{{public_key_hash}}" - if req.DisplayName == "" { - keyIDFormat = "vault-{{public_key_hash}}" - } - - if role.KeyIDFormat != "" { - keyIDFormat = role.KeyIDFormat - } - - keyID := substQuery(keyIDFormat, map[string]string{ - "token_display_name": req.DisplayName, - "role_name": data.Get("role").(string), - "public_key_hash": fmt.Sprintf("%x", sha256.Sum256(pubKey.Marshal())), - }) - - return keyID, nil -} - -func (b *backend) calculateCriticalOptions(data *framework.FieldData, role *sshRole) (map[string]string, error) { - unparsedCriticalOptions := data.Get("critical_options").(map[string]interface{}) - if len(unparsedCriticalOptions) == 0 { - return role.DefaultCriticalOptions, nil - } - - criticalOptions := convertMapToStringValue(unparsedCriticalOptions) - - if role.AllowedCriticalOptions != "" { - notAllowedOptions := []string{} - allowedCriticalOptions := strings.Split(role.AllowedCriticalOptions, ",") - - for option := range criticalOptions { - if !strutil.StrListContains(allowedCriticalOptions, option) { - notAllowedOptions = append(notAllowedOptions, option) - } - } - - if len(notAllowedOptions) != 0 { - return nil, fmt.Errorf("critical options not on allowed list: %v", notAllowedOptions) - } - } - - return criticalOptions, nil -} - -func (b *backend) calculateExtensions(data *framework.FieldData, req *logical.Request, role *sshRole) (map[string]string, error) { - unparsedExtensions := data.Get("extensions").(map[string]interface{}) - extensions := make(map[string]string) - - if len(unparsedExtensions) > 0 { - extensions := convertMapToStringValue(unparsedExtensions) - if role.AllowedExtensions == "*" { - // Allowed extensions was configured to allow all - return extensions, nil - } - - notAllowed := []string{} - allowedExtensions := strings.Split(role.AllowedExtensions, ",") - for extensionKey := range extensions { - if !strutil.StrListContains(allowedExtensions, extensionKey) { - notAllowed = append(notAllowed, extensionKey) - } - } - - if len(notAllowed) != 0 { - return nil, fmt.Errorf("extensions %v are not on allowed list", notAllowed) - } - return extensions, nil - } - - if role.DefaultExtensionsTemplate { - for extensionKey, extensionValue := range role.DefaultExtensions { - // Look for templating markers {{ .* }} - matched := containsTemplateRegex.MatchString(extensionValue) - if matched { - if req.EntityID != "" { - // Retrieve extension value based on template + entityID from request. - templateExtensionValue, err := framework.PopulateIdentityTemplate(extensionValue, req.EntityID, b.System()) - if err == nil { - // Template returned an extension value that we can use - extensions[extensionKey] = templateExtensionValue - } else { - return nil, fmt.Errorf("template '%s' could not be rendered -> %s", extensionValue, err) - } - } - } else { - // Static extension value or err template - extensions[extensionKey] = extensionValue - } - } - } else { - extensions = role.DefaultExtensions - } - - return extensions, nil -} - -func (b *backend) calculateTTL(data *framework.FieldData, role *sshRole) (time.Duration, error) { - var ttl, maxTTL time.Duration - var err error - - ttlRaw, specifiedTTL := data.GetOk("ttl") - if specifiedTTL { - ttl = time.Duration(ttlRaw.(int)) * time.Second - } else { - ttl, err = parseutil.ParseDurationSecond(role.TTL) - if err != nil { - return 0, err - } - } - if ttl == 0 { - ttl = b.System().DefaultLeaseTTL() - } - - maxTTL, err = parseutil.ParseDurationSecond(role.MaxTTL) - if err != nil { - return 0, err - } - if maxTTL == 0 { - maxTTL = b.System().MaxLeaseTTL() - } - - if ttl > maxTTL { - // Don't error if they were using system defaults, only error if - // they specifically chose a bad TTL - if !specifiedTTL { - ttl = maxTTL - } else { - return 0, fmt.Errorf("ttl is larger than maximum allowed %d", maxTTL/time.Second) - } - } - - return ttl, nil -} - -func (b *backend) validateSignedKeyRequirements(publickey ssh.PublicKey, role *sshRole) error { - if len(role.AllowedUserKeyTypesLengths) != 0 { - var keyType string - var keyBits int - - switch k := publickey.(type) { - case ssh.CryptoPublicKey: - ff := k.CryptoPublicKey() - switch k := ff.(type) { - case *rsa.PublicKey: - keyType = "rsa" - keyBits = k.N.BitLen() - case *dsa.PublicKey: - keyType = "dsa" - keyBits = k.Parameters.P.BitLen() - case *ecdsa.PublicKey: - keyType = "ecdsa" - keyBits = k.Curve.Params().BitSize - case ed25519.PublicKey: - keyType = "ed25519" - default: - return fmt.Errorf("public key type of %s is not allowed", keyType) - } - default: - return fmt.Errorf("pubkey not suitable for crypto (expected ssh.CryptoPublicKey but found %T)", k) - } - - keyTypeToMapKey := createKeyTypeToMapKey(keyType, keyBits) - - var present bool - var pass bool - for _, kstr := range keyTypeToMapKey[keyType] { - allowed_values, ok := role.AllowedUserKeyTypesLengths[kstr] - if !ok { - continue - } - - present = true - - for _, value := range allowed_values { - if keyType == "rsa" || keyType == "dsa" { - // Regardless of map naming, we always need to validate the - // bit length of RSA and DSA keys. Use the keyType flag to - if keyBits == value { - pass = true - } - } else if kstr == "ec" || kstr == "ecdsa" { - // If the map string is "ecdsa", we have to validate the keyBits - // are a match for an allowed value, meaning that our curve - // is allowed. This isn't necessary when a named curve (e.g. - // ssh.KeyAlgoECDSA256) is allowed (and hence kstr is that), - // because keyBits is already specified in the kstr. Thus, - // we have conditioned around kstr and not keyType (like with - // rsa or dsa). - if keyBits == value { - pass = true - } - } else { - // We get here in two cases: we have a algo-named EC key - // matching a format specifier in the key map (e.g., a P-256 - // key with a KeyAlgoECDSA256 entry in the map) or we have a - // ed25519 key (which is always allowed). - pass = true - } - } - } - - if !present { - return fmt.Errorf("key of type %s is not allowed", keyType) - } - - if !pass { - return fmt.Errorf("key is of an invalid size: %v", keyBits) - } - } - return nil -} - -func (b *creationBundle) sign() (retCert *ssh.Certificate, retErr error) { - defer func() { - if r := recover(); r != nil { - errMsg, ok := r.(string) - if ok { - retCert = nil - retErr = errors.New(errMsg) - } - } - }() - - serialNumber, err := certutil.GenerateSerialNumber() - if err != nil { - return nil, err - } - - now := time.Now() - - sshAlgorithmSigner, ok := b.Signer.(ssh.AlgorithmSigner) - if !ok { - return nil, fmt.Errorf("failed to generate signed SSH key: signer is not an AlgorithmSigner") - } - - // prepare certificate for signing - nonce := make([]byte, 32) - if _, err := io.ReadFull(rand.Reader, nonce); err != nil { - return nil, fmt.Errorf("failed to generate signed SSH key: error generating random nonce") - } - certificate := &ssh.Certificate{ - Serial: serialNumber.Uint64(), - Key: b.PublicKey, - KeyId: b.KeyID, - ValidPrincipals: b.ValidPrincipals, - ValidAfter: uint64(now.Add(-b.Role.NotBeforeDuration).In(time.UTC).Unix()), - ValidBefore: uint64(now.Add(b.TTL).In(time.UTC).Unix()), - CertType: b.CertificateType, - Permissions: ssh.Permissions{ - CriticalOptions: b.CriticalOptions, - Extensions: b.Extensions, - }, - Nonce: nonce, - SignatureKey: sshAlgorithmSigner.PublicKey(), - } - - // get bytes to sign; this is based on Certificate.bytesForSigning() from the go ssh lib - out := certificate.Marshal() - // Drop trailing signature length. - certificateBytes := out[:len(out)-4] - - algo := b.Role.AlgorithmSigner - - // Handle the new default algorithm selection process correctly. - if algo == DefaultAlgorithmSigner && sshAlgorithmSigner.PublicKey().Type() == ssh.KeyAlgoRSA { - algo = ssh.SigAlgoRSASHA2256 - } else if algo == DefaultAlgorithmSigner { - algo = "" - } - - sig, err := sshAlgorithmSigner.SignWithAlgorithm(rand.Reader, certificateBytes, algo) - if err != nil { - return nil, fmt.Errorf("failed to generate signed SSH key: sign error: %w", err) - } - - certificate.Signature = sig - - return certificate, nil -} - -func createKeyTypeToMapKey(keyType string, keyBits int) map[string][]string { - keyTypeToMapKey := map[string][]string{ - "rsa": {"rsa", ssh.KeyAlgoRSA}, - "dsa": {"dsa", ssh.KeyAlgoDSA}, - "ecdsa": {"ecdsa", "ec"}, - "ed25519": {"ed25519", ssh.KeyAlgoED25519}, - } - - if keyType == "ecdsa" { - if algo, ok := ecCurveBitsToAlgoName[keyBits]; ok { - keyTypeToMapKey[keyType] = append(keyTypeToMapKey[keyType], algo) - } - } - - return keyTypeToMapKey -} diff --git a/builtin/logical/ssh/path_roles.go b/builtin/logical/ssh/path_roles.go index 123696b7a9c60..3264b000c2b4c 100644 --- a/builtin/logical/ssh/path_roles.go +++ b/builtin/logical/ssh/path_roles.go @@ -40,7 +40,6 @@ type sshRole struct { KeyBits int `mapstructure:"key_bits" json:"key_bits"` AdminUser string `mapstructure:"admin_user" json:"admin_user"` DefaultUser string `mapstructure:"default_user" json:"default_user"` - DefaultUserTemplate bool `mapstructure:"default_user_template" json:"default_user_template"` CIDRList string `mapstructure:"cidr_list" json:"cidr_list"` ExcludeCIDRList string `mapstructure:"exclude_cidr_list" json:"exclude_cidr_list"` Port int `mapstructure:"port" json:"port"` @@ -123,15 +122,6 @@ func pathRoles(b *backend) *framework.Path { Name: "Default Username", }, }, - "default_user_template": { - Type: framework.TypeBool, - Description: ` - [Not applicable for Dynamic type] [Not applicable for OTP type] [Optional for CA type] - If set, Default user can be specified using identity template policies. - Non-templated users are also permitted. - `, - Default: false, - }, "cidr_list": { Type: framework.TypeString, Description: ` @@ -568,7 +558,6 @@ func (b *backend) createCARole(allowedUsers, defaultUser, signer string, data *f AllowedUsersTemplate: data.Get("allowed_users_template").(bool), AllowedDomains: data.Get("allowed_domains").(string), DefaultUser: defaultUser, - DefaultUserTemplate: data.Get("default_user_template").(bool), AllowBareDomains: data.Get("allow_bare_domains").(bool), AllowSubdomains: data.Get("allow_subdomains").(bool), AllowUserKeyIDs: data.Get("allow_user_key_ids").(bool), @@ -751,7 +740,6 @@ func (b *backend) parseRole(role *sshRole) (map[string]interface{}, error) { "allowed_users_template": role.AllowedUsersTemplate, "allowed_domains": role.AllowedDomains, "default_user": role.DefaultUser, - "default_user_template": role.DefaultUserTemplate, "ttl": int64(ttl.Seconds()), "max_ttl": int64(maxTTL.Seconds()), "allowed_critical_options": role.AllowedCriticalOptions, diff --git a/builtin/logical/ssh/path_sign.go b/builtin/logical/ssh/path_sign.go index 19196013e6d50..8e21ad1e7e7f7 100644 --- a/builtin/logical/ssh/path_sign.go +++ b/builtin/logical/ssh/path_sign.go @@ -2,12 +2,42 @@ package ssh import ( "context" + "crypto/dsa" + "crypto/ecdsa" + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "errors" "fmt" + "io" + "regexp" + "strconv" + "strings" + "time" + "github.com/hashicorp/go-secure-stdlib/parseutil" + "github.com/hashicorp/go-secure-stdlib/strutil" "github.com/hashicorp/vault/sdk/framework" + "github.com/hashicorp/vault/sdk/helper/certutil" "github.com/hashicorp/vault/sdk/logical" + "golang.org/x/crypto/ed25519" + "golang.org/x/crypto/ssh" ) +type creationBundle struct { + KeyID string + ValidPrincipals []string + PublicKey ssh.PublicKey + CertificateType uint32 + TTL time.Duration + Signer ssh.Signer + Role *sshRole + CriticalOptions map[string]string + Extensions map[string]string +} + +var containsTemplateRegex = regexp.MustCompile(`{{.+?}}`) + func pathSign(b *backend) *framework.Path { return &framework.Path{ Pattern: "sign/" + framework.GenericNameWithAtRegex("role"), @@ -92,5 +122,497 @@ func (b *backend) pathSignCertificate(ctx context.Context, req *logical.Request, return logical.ErrorResponse(fmt.Sprintf("public_key failed to meet the key requirements: %s", err)), nil } - return b.pathSignIssueCertificateHelper(ctx, req, data, role, userPublicKey) + // Note that these various functions always return "user errors" so we pass + // them as 4xx values + keyID, err := b.calculateKeyID(data, req, role, userPublicKey) + if err != nil { + return logical.ErrorResponse(err.Error()), nil + } + + certificateType, err := b.calculateCertificateType(data, role) + if err != nil { + return logical.ErrorResponse(err.Error()), nil + } + + var parsedPrincipals []string + if certificateType == ssh.HostCert { + parsedPrincipals, err = b.calculateValidPrincipals(data, req, role, "", role.AllowedDomains, validateValidPrincipalForHosts(role)) + if err != nil { + return logical.ErrorResponse(err.Error()), nil + } + } else { + parsedPrincipals, err = b.calculateValidPrincipals(data, req, role, role.DefaultUser, role.AllowedUsers, strutil.StrListContains) + if err != nil { + return logical.ErrorResponse(err.Error()), nil + } + } + + ttl, err := b.calculateTTL(data, role) + if err != nil { + return logical.ErrorResponse(err.Error()), nil + } + + criticalOptions, err := b.calculateCriticalOptions(data, role) + if err != nil { + return logical.ErrorResponse(err.Error()), nil + } + + extensions, err := b.calculateExtensions(data, req, role) + if err != nil { + return logical.ErrorResponse(err.Error()), nil + } + + privateKeyEntry, err := caKey(ctx, req.Storage, caPrivateKey) + if err != nil { + return nil, fmt.Errorf("failed to read CA private key: %w", err) + } + if privateKeyEntry == nil || privateKeyEntry.Key == "" { + return nil, fmt.Errorf("failed to read CA private key") + } + + signer, err := ssh.ParsePrivateKey([]byte(privateKeyEntry.Key)) + if err != nil { + return nil, fmt.Errorf("failed to parse stored CA private key: %w", err) + } + + cBundle := creationBundle{ + KeyID: keyID, + PublicKey: userPublicKey, + Signer: signer, + ValidPrincipals: parsedPrincipals, + TTL: ttl, + CertificateType: certificateType, + Role: role, + CriticalOptions: criticalOptions, + Extensions: extensions, + } + + certificate, err := cBundle.sign() + if err != nil { + return nil, err + } + + signedSSHCertificate := ssh.MarshalAuthorizedKey(certificate) + if len(signedSSHCertificate) == 0 { + return nil, fmt.Errorf("error marshaling signed certificate") + } + + response := &logical.Response{ + Data: map[string]interface{}{ + "serial_number": strconv.FormatUint(certificate.Serial, 16), + "signed_key": string(signedSSHCertificate), + }, + } + + return response, nil +} + +func (b *backend) calculateValidPrincipals(data *framework.FieldData, req *logical.Request, role *sshRole, defaultPrincipal, principalsAllowedByRole string, validatePrincipal func([]string, string) bool) ([]string, error) { + validPrincipals := "" + validPrincipalsRaw, ok := data.GetOk("valid_principals") + if ok { + validPrincipals = validPrincipalsRaw.(string) + } else { + validPrincipals = defaultPrincipal + } + + parsedPrincipals := strutil.RemoveDuplicates(strutil.ParseStringSlice(validPrincipals, ","), false) + // Build list of allowed Principals from template and static principalsAllowedByRole + var allowedPrincipals []string + for _, principal := range strutil.RemoveDuplicates(strutil.ParseStringSlice(principalsAllowedByRole, ","), false) { + if role.AllowedUsersTemplate { + // Look for templating markers {{ .* }} + matched := containsTemplateRegex.MatchString(principal) + if matched { + if req.EntityID != "" { + // Retrieve principal based on template + entityID from request. + templatePrincipal, err := framework.PopulateIdentityTemplate(principal, req.EntityID, b.System()) + if err == nil { + // Template returned a principal + allowedPrincipals = append(allowedPrincipals, templatePrincipal) + } else { + return nil, fmt.Errorf("template '%s' could not be rendered -> %s", principal, err) + } + } + } else { + // Static principal or err template + allowedPrincipals = append(allowedPrincipals, principal) + } + } else { + // Static principal + allowedPrincipals = append(allowedPrincipals, principal) + } + } + + switch { + case len(parsedPrincipals) == 0: + // There is nothing to process + return nil, nil + case len(allowedPrincipals) == 0: + // User has requested principals to be set, but role is not configured + // with any principals + return nil, fmt.Errorf("role is not configured to allow any principals") + default: + // Role was explicitly configured to allow any principal. + if principalsAllowedByRole == "*" { + return parsedPrincipals, nil + } + + for _, principal := range parsedPrincipals { + if !validatePrincipal(strutil.RemoveDuplicates(allowedPrincipals, false), principal) { + return nil, fmt.Errorf("%v is not a valid value for valid_principals", principal) + } + } + return parsedPrincipals, nil + } +} + +func validateValidPrincipalForHosts(role *sshRole) func([]string, string) bool { + return func(allowedPrincipals []string, validPrincipal string) bool { + for _, allowedPrincipal := range allowedPrincipals { + if allowedPrincipal == validPrincipal && role.AllowBareDomains { + return true + } + if role.AllowSubdomains && strings.HasSuffix(validPrincipal, "."+allowedPrincipal) { + return true + } + } + + return false + } +} + +func (b *backend) calculateCertificateType(data *framework.FieldData, role *sshRole) (uint32, error) { + requestedCertificateType := data.Get("cert_type").(string) + + var certificateType uint32 + switch requestedCertificateType { + case "user": + if !role.AllowUserCertificates { + return 0, errors.New("cert_type 'user' is not allowed by role") + } + certificateType = ssh.UserCert + case "host": + if !role.AllowHostCertificates { + return 0, errors.New("cert_type 'host' is not allowed by role") + } + certificateType = ssh.HostCert + default: + return 0, errors.New("cert_type must be either 'user' or 'host'") + } + + return certificateType, nil +} + +func (b *backend) calculateKeyID(data *framework.FieldData, req *logical.Request, role *sshRole, pubKey ssh.PublicKey) (string, error) { + reqID := data.Get("key_id").(string) + + if reqID != "" { + if !role.AllowUserKeyIDs { + return "", fmt.Errorf("setting key_id is not allowed by role") + } + return reqID, nil + } + + keyIDFormat := "vault-{{token_display_name}}-{{public_key_hash}}" + if req.DisplayName == "" { + keyIDFormat = "vault-{{public_key_hash}}" + } + + if role.KeyIDFormat != "" { + keyIDFormat = role.KeyIDFormat + } + + keyID := substQuery(keyIDFormat, map[string]string{ + "token_display_name": req.DisplayName, + "role_name": data.Get("role").(string), + "public_key_hash": fmt.Sprintf("%x", sha256.Sum256(pubKey.Marshal())), + }) + + return keyID, nil +} + +func (b *backend) calculateCriticalOptions(data *framework.FieldData, role *sshRole) (map[string]string, error) { + unparsedCriticalOptions := data.Get("critical_options").(map[string]interface{}) + if len(unparsedCriticalOptions) == 0 { + return role.DefaultCriticalOptions, nil + } + + criticalOptions := convertMapToStringValue(unparsedCriticalOptions) + + if role.AllowedCriticalOptions != "" { + notAllowedOptions := []string{} + allowedCriticalOptions := strings.Split(role.AllowedCriticalOptions, ",") + + for option := range criticalOptions { + if !strutil.StrListContains(allowedCriticalOptions, option) { + notAllowedOptions = append(notAllowedOptions, option) + } + } + + if len(notAllowedOptions) != 0 { + return nil, fmt.Errorf("critical options not on allowed list: %v", notAllowedOptions) + } + } + + return criticalOptions, nil +} + +func (b *backend) calculateExtensions(data *framework.FieldData, req *logical.Request, role *sshRole) (map[string]string, error) { + unparsedExtensions := data.Get("extensions").(map[string]interface{}) + extensions := make(map[string]string) + + if len(unparsedExtensions) > 0 { + extensions := convertMapToStringValue(unparsedExtensions) + if role.AllowedExtensions == "*" { + // Allowed extensions was configured to allow all + return extensions, nil + } + + notAllowed := []string{} + allowedExtensions := strings.Split(role.AllowedExtensions, ",") + for extensionKey := range extensions { + if !strutil.StrListContains(allowedExtensions, extensionKey) { + notAllowed = append(notAllowed, extensionKey) + } + } + + if len(notAllowed) != 0 { + return nil, fmt.Errorf("extensions %v are not on allowed list", notAllowed) + } + return extensions, nil + } + + if role.DefaultExtensionsTemplate { + for extensionKey, extensionValue := range role.DefaultExtensions { + // Look for templating markers {{ .* }} + matched := containsTemplateRegex.MatchString(extensionValue) + if matched { + if req.EntityID != "" { + // Retrieve extension value based on template + entityID from request. + templateExtensionValue, err := framework.PopulateIdentityTemplate(extensionValue, req.EntityID, b.System()) + if err == nil { + // Template returned an extension value that we can use + extensions[extensionKey] = templateExtensionValue + } else { + return nil, fmt.Errorf("template '%s' could not be rendered -> %s", extensionValue, err) + } + } + } else { + // Static extension value or err template + extensions[extensionKey] = extensionValue + } + } + } else { + extensions = role.DefaultExtensions + } + + return extensions, nil +} + +func (b *backend) calculateTTL(data *framework.FieldData, role *sshRole) (time.Duration, error) { + var ttl, maxTTL time.Duration + var err error + + ttlRaw, specifiedTTL := data.GetOk("ttl") + if specifiedTTL { + ttl = time.Duration(ttlRaw.(int)) * time.Second + } else { + ttl, err = parseutil.ParseDurationSecond(role.TTL) + if err != nil { + return 0, err + } + } + if ttl == 0 { + ttl = b.System().DefaultLeaseTTL() + } + + maxTTL, err = parseutil.ParseDurationSecond(role.MaxTTL) + if err != nil { + return 0, err + } + if maxTTL == 0 { + maxTTL = b.System().MaxLeaseTTL() + } + + if ttl > maxTTL { + // Don't error if they were using system defaults, only error if + // they specifically chose a bad TTL + if !specifiedTTL { + ttl = maxTTL + } else { + return 0, fmt.Errorf("ttl is larger than maximum allowed %d", maxTTL/time.Second) + } + } + + return ttl, nil +} + +func (b *backend) validateSignedKeyRequirements(publickey ssh.PublicKey, role *sshRole) error { + if len(role.AllowedUserKeyTypesLengths) != 0 { + var keyType string + var keyBits int + + switch k := publickey.(type) { + case ssh.CryptoPublicKey: + ff := k.CryptoPublicKey() + switch k := ff.(type) { + case *rsa.PublicKey: + keyType = "rsa" + keyBits = k.N.BitLen() + case *dsa.PublicKey: + keyType = "dsa" + keyBits = k.Parameters.P.BitLen() + case *ecdsa.PublicKey: + keyType = "ecdsa" + keyBits = k.Curve.Params().BitSize + case ed25519.PublicKey: + keyType = "ed25519" + default: + return fmt.Errorf("public key type of %s is not allowed", keyType) + } + default: + return fmt.Errorf("pubkey not suitable for crypto (expected ssh.CryptoPublicKey but found %T)", k) + } + + keyTypeToMapKey := map[string][]string{ + "rsa": {"rsa", ssh.KeyAlgoRSA}, + "dsa": {"dsa", ssh.KeyAlgoDSA}, + "ecdsa": {"ecdsa", "ec"}, + "ed25519": {"ed25519", ssh.KeyAlgoED25519}, + } + + if keyType == "ecdsa" { + ecCurveBitsToAlgoName := map[int]string{ + 256: ssh.KeyAlgoECDSA256, + 384: ssh.KeyAlgoECDSA384, + 521: ssh.KeyAlgoECDSA521, + } + + if algo, ok := ecCurveBitsToAlgoName[keyBits]; ok { + keyTypeToMapKey[keyType] = append(keyTypeToMapKey[keyType], algo) + } + + // If the algorithm is not found, it could be that we have a curve + // that we haven't added a constant for yet. But they could allow it + // (assuming x/crypto/ssh can parse it) via setting a ec: + // mapping rather than using a named SSH key type, so erring out here + // isn't advisable. + } + + var present bool + var pass bool + for _, kstr := range keyTypeToMapKey[keyType] { + allowed_values, ok := role.AllowedUserKeyTypesLengths[kstr] + if !ok { + continue + } + + present = true + + for _, value := range allowed_values { + if keyType == "rsa" || keyType == "dsa" { + // Regardless of map naming, we always need to validate the + // bit length of RSA and DSA keys. Use the keyType flag to + if keyBits == value { + pass = true + } + } else if kstr == "ec" || kstr == "ecdsa" { + // If the map string is "ecdsa", we have to validate the keyBits + // are a match for an allowed value, meaning that our curve + // is allowed. This isn't necessary when a named curve (e.g. + // ssh.KeyAlgoECDSA256) is allowed (and hence kstr is that), + // because keyBits is already specified in the kstr. Thus, + // we have conditioned around kstr and not keyType (like with + // rsa or dsa). + if keyBits == value { + pass = true + } + } else { + // We get here in two cases: we have a algo-named EC key + // matching a format specifier in the key map (e.g., a P-256 + // key with a KeyAlgoECDSA256 entry in the map) or we have a + // ed25519 key (which is always allowed). + pass = true + } + } + } + + if !present { + return fmt.Errorf("key of type %s is not allowed", keyType) + } + + if !pass { + return fmt.Errorf("key is of an invalid size: %v", keyBits) + } + } + return nil +} + +func (b *creationBundle) sign() (retCert *ssh.Certificate, retErr error) { + defer func() { + if r := recover(); r != nil { + errMsg, ok := r.(string) + if ok { + retCert = nil + retErr = errors.New(errMsg) + } + } + }() + + serialNumber, err := certutil.GenerateSerialNumber() + if err != nil { + return nil, err + } + + now := time.Now() + + sshAlgorithmSigner, ok := b.Signer.(ssh.AlgorithmSigner) + if !ok { + return nil, fmt.Errorf("failed to generate signed SSH key: signer is not an AlgorithmSigner") + } + + // prepare certificate for signing + nonce := make([]byte, 32) + if _, err := io.ReadFull(rand.Reader, nonce); err != nil { + return nil, fmt.Errorf("failed to generate signed SSH key: error generating random nonce") + } + certificate := &ssh.Certificate{ + Serial: serialNumber.Uint64(), + Key: b.PublicKey, + KeyId: b.KeyID, + ValidPrincipals: b.ValidPrincipals, + ValidAfter: uint64(now.Add(-b.Role.NotBeforeDuration).In(time.UTC).Unix()), + ValidBefore: uint64(now.Add(b.TTL).In(time.UTC).Unix()), + CertType: b.CertificateType, + Permissions: ssh.Permissions{ + CriticalOptions: b.CriticalOptions, + Extensions: b.Extensions, + }, + Nonce: nonce, + SignatureKey: sshAlgorithmSigner.PublicKey(), + } + + // get bytes to sign; this is based on Certificate.bytesForSigning() from the go ssh lib + out := certificate.Marshal() + // Drop trailing signature length. + certificateBytes := out[:len(out)-4] + + algo := b.Role.AlgorithmSigner + + // Handle the new default algorithm selection process correctly. + if algo == DefaultAlgorithmSigner && sshAlgorithmSigner.PublicKey().Type() == ssh.KeyAlgoRSA { + algo = ssh.SigAlgoRSASHA2256 + } else if algo == DefaultAlgorithmSigner { + algo = "" + } + + sig, err := sshAlgorithmSigner.SignWithAlgorithm(rand.Reader, certificateBytes, algo) + if err != nil { + return nil, fmt.Errorf("failed to generate signed SSH key: sign error: %w", err) + } + + certificate.Signature = sig + + return certificate, nil } diff --git a/builtin/logical/ssh/util.go b/builtin/logical/ssh/util.go index 1923caa346b3d..5658232763a2a 100644 --- a/builtin/logical/ssh/util.go +++ b/builtin/logical/ssh/util.go @@ -238,7 +238,7 @@ func convertMapToIntSlice(initial map[string]interface{}) (map[string][]int, err // Serve a template processor for custom format inputs func substQuery(tpl string, data map[string]string) string { for k, v := range data { - tpl = strings.ReplaceAll(tpl, fmt.Sprintf("{{%s}}", k), v) + tpl = strings.Replace(tpl, fmt.Sprintf("{{%s}}", k), v, -1) } return tpl diff --git a/builtin/logical/transit/backend_test.go b/builtin/logical/transit/backend_test.go index 09e51c57d06ec..abe14b51c745a 100644 --- a/builtin/logical/transit/backend_test.go +++ b/builtin/logical/transit/backend_test.go @@ -744,7 +744,7 @@ func testAccStepRewrap( verString := splitStrings[1][1:] ver, err := strconv.Atoi(verString) if err != nil { - return fmt.Errorf("error pulling out version from verString %q, ciphertext was %s", verString, d.Ciphertext) + return fmt.Errorf("error pulling out version from verString '%s', ciphertext was %s", verString, d.Ciphertext) } if ver != expectedVer { return fmt.Errorf("did not get expected version") @@ -856,7 +856,7 @@ func testAccStepWriteDatakey(t *testing.T, name string, dataKeyInfo["plaintext"] = d.Plaintext plainBytes, err := base64.StdEncoding.DecodeString(d.Plaintext) if err != nil { - return fmt.Errorf("could not base64 decode plaintext string %q", d.Plaintext) + return fmt.Errorf("could not base64 decode plaintext string '%s'", d.Plaintext) } if len(plainBytes)*8 != bits { return fmt.Errorf("returned key does not have correct bit length") @@ -883,7 +883,7 @@ func testAccStepDecryptDatakey(t *testing.T, name string, } if d.Plaintext != dataKeyInfo["plaintext"].(string) { - return fmt.Errorf("plaintext mismatch: got %q, expected %q, decryptData was %#v", d.Plaintext, dataKeyInfo["plaintext"].(string), resp.Data) + return fmt.Errorf("plaintext mismatch: got '%s', expected '%s', decryptData was %#v", d.Plaintext, dataKeyInfo["plaintext"].(string), resp.Data) } return nil }, diff --git a/builtin/logical/transit/path_hmac_test.go b/builtin/logical/transit/path_hmac_test.go index c60b6ef46c177..108d6218bfd79 100644 --- a/builtin/logical/transit/path_hmac_test.go +++ b/builtin/logical/transit/path_hmac_test.go @@ -76,7 +76,7 @@ func TestTransit_HMAC(t *testing.T) { } // Now verify - req.Path = strings.ReplaceAll(req.Path, "hmac", "verify") + req.Path = strings.Replace(req.Path, "hmac", "verify", -1) req.Data["hmac"] = value.(string) resp, err = b.HandleRequest(context.Background(), req) if err != nil { @@ -268,7 +268,7 @@ func TestTransit_batchHMAC(t *testing.T) { t.Fatalf("Expected HMAC %s got %s in result %d", expected[i].HMAC, m.HMAC, i) } if expected[i].Error != "" && expected[i].Error != m.Error { - t.Fatalf("Expected Error %q got %q in result %d", expected[i].Error, m.Error, i) + t.Fatalf("Expected Error '%s' got '%s' in result %d", expected[i].Error, m.Error, i) } } diff --git a/builtin/logical/transit/path_import_test.go b/builtin/logical/transit/path_import_test.go index a532dfdbeb800..6e2748833db46 100644 --- a/builtin/logical/transit/path_import_test.go +++ b/builtin/logical/transit/path_import_test.go @@ -45,8 +45,6 @@ var ( keys = map[string]interface{}{} ) -const nssFormattedEd25519Key = "MGcCAQAwFAYHKoZIzj0CAQYJKwYBBAHaRw8BBEwwSgIBAQQgfJm5R+LK4FMwGzOpemTBXksimEVOVCE8QeC+XBBfNU+hIwMhADaif7IhYx46IHcRTy1z8LeyhABep+UB8Da6olMZGx0i" - func generateKeys(t *testing.T) { t.Helper() @@ -80,39 +78,6 @@ func getKey(t *testing.T, keyType string) interface{} { return key } -func TestTransit_ImportNSSEd25519Key(t *testing.T) { - generateKeys(t) - b, s := createBackendWithStorage(t) - - wrappingKey, err := b.getWrappingKey(context.Background(), s) - if err != nil || wrappingKey == nil { - t.Fatalf("failed to retrieve public wrapping key: %s", err) - } - privWrappingKey := wrappingKey.Keys[strconv.Itoa(wrappingKey.LatestVersion)].RSAKey - pubWrappingKey := &privWrappingKey.PublicKey - - rawPKCS8, err := base64.StdEncoding.DecodeString(nssFormattedEd25519Key) - if err != nil { - t.Fatalf("failed to parse nss base64: %v", err) - } - - blob := wrapTargetPKCS8ForImport(t, pubWrappingKey, rawPKCS8, "SHA256") - req := &logical.Request{ - Storage: s, - Operation: logical.UpdateOperation, - Path: "keys/nss-ed25519/import", - Data: map[string]interface{}{ - "ciphertext": blob, - "type": "ed25519", - }, - } - - _, err = b.HandleRequest(context.Background(), req) - if err != nil { - t.Fatalf("failed to import NSS-formatted Ed25519 key: %v", err) - } -} - func TestTransit_Import(t *testing.T) { generateKeys(t) b, s := createBackendWithStorage(t) @@ -538,29 +503,6 @@ func TestTransit_ImportVersion(t *testing.T) { func wrapTargetKeyForImport(t *testing.T, wrappingKey *rsa.PublicKey, targetKey interface{}, targetKeyType string, hashFnName string) string { t.Helper() - // Format target key for wrapping - var preppedTargetKey []byte - var ok bool - var err error - switch targetKeyType { - case "aes128-gcm96", "aes256-gcm96", "chacha20-poly1305": - preppedTargetKey, ok = targetKey.([]byte) - if !ok { - t.Fatal("failed to wrap target key for import: symmetric key not provided in byte format") - } - default: - preppedTargetKey, err = x509.MarshalPKCS8PrivateKey(targetKey) - if err != nil { - t.Fatalf("failed to wrap target key for import: %s", err) - } - } - - return wrapTargetPKCS8ForImport(t, wrappingKey, preppedTargetKey, hashFnName) -} - -func wrapTargetPKCS8ForImport(t *testing.T, wrappingKey *rsa.PublicKey, preppedTargetKey []byte, hashFnName string) string { - t.Helper() - // Generate an ephemeral AES-256 key ephKey, err := uuid.GenerateRandomBytes(32) if err != nil { @@ -585,6 +527,22 @@ func wrapTargetPKCS8ForImport(t *testing.T, wrappingKey *rsa.PublicKey, preppedT t.Fatalf("failed to wrap target key for import: %s", err) } + // Format target key for wrapping + var preppedTargetKey []byte + var ok bool + switch targetKeyType { + case "aes128-gcm96", "aes256-gcm96", "chacha20-poly1305": + preppedTargetKey, ok = targetKey.([]byte) + if !ok { + t.Fatal("failed to wrap target key for import: symmetric key not provided in byte format") + } + default: + preppedTargetKey, err = x509.MarshalPKCS8PrivateKey(targetKey) + if err != nil { + t.Fatalf("failed to wrap target key for import: %s", err) + } + } + // Wrap target key with KWP targetKeyWrapped, err := kwp.Wrap(preppedTargetKey) if err != nil { diff --git a/builtin/logical/transit/path_restore_test.go b/builtin/logical/transit/path_restore_test.go index 6e13b985ee65d..031679f9942f9 100644 --- a/builtin/logical/transit/path_restore_test.go +++ b/builtin/logical/transit/path_restore_test.go @@ -83,7 +83,7 @@ func TestTransit_Restore(t *testing.T) { return &b } - keyExitsError := fmt.Errorf("key %q already exists", keyName) + keyExitsError := fmt.Errorf("key \"%s\" already exists", keyName) testCases := []struct { Name string diff --git a/builtin/plugin/backend.go b/builtin/plugin/backend.go index 751588905870f..d33fe9c1a8eb8 100644 --- a/builtin/plugin/backend.go +++ b/builtin/plugin/backend.go @@ -7,8 +7,6 @@ import ( "reflect" "sync" - log "github.com/hashicorp/go-hclog" - uuid "github.com/hashicorp/go-uuid" "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/helper/consts" @@ -40,7 +38,7 @@ func Factory(ctx context.Context, conf *logical.BackendConfig) (logical.Backend, // Backend returns an instance of the backend, either as a plugin if external // or as a concrete implementation if builtin, casted as logical.Backend. -func Backend(ctx context.Context, conf *logical.BackendConfig) (*PluginBackend, error) { +func Backend(ctx context.Context, conf *logical.BackendConfig) (logical.Backend, error) { var b PluginBackend name := conf.Config["plugin_name"] @@ -82,7 +80,7 @@ func Backend(ctx context.Context, conf *logical.BackendConfig) (*PluginBackend, // PluginBackend is a thin wrapper around plugin.BackendPluginClient type PluginBackend struct { - Backend logical.Backend + logical.Backend sync.RWMutex config *logical.BackendConfig @@ -120,12 +118,12 @@ func (b *PluginBackend) startBackend(ctx context.Context, storage logical.Storag if !b.loaded { if b.Backend.Type() != nb.Type() { nb.Cleanup(ctx) - b.Backend.Logger().Warn("failed to start plugin process", "plugin", b.config.Config["plugin_name"], "error", ErrMismatchType) + b.Logger().Warn("failed to start plugin process", "plugin", b.config.Config["plugin_name"], "error", ErrMismatchType) return ErrMismatchType } if !reflect.DeepEqual(b.Backend.SpecialPaths(), nb.SpecialPaths()) { nb.Cleanup(ctx) - b.Backend.Logger().Warn("failed to start plugin process", "plugin", b.config.Config["plugin_name"], "error", ErrMismatchPaths) + b.Logger().Warn("failed to start plugin process", "plugin", b.config.Config["plugin_name"], "error", ErrMismatchPaths) return ErrMismatchPaths } } @@ -171,7 +169,7 @@ func (b *PluginBackend) lazyLoadBackend(ctx context.Context, storage logical.Sto // Reload plugin if it's an rpc.ErrShutdown b.Lock() if b.canary == canary { - b.Backend.Logger().Debug("reloading plugin backend", "plugin", b.config.Config["plugin_name"]) + b.Logger().Debug("reloading plugin backend", "plugin", b.config.Config["plugin_name"]) err := b.startBackend(ctx, storage) if err != nil { b.Unlock() @@ -222,52 +220,3 @@ func (b *PluginBackend) HandleExistenceCheck(ctx context.Context, req *logical.R func (b *PluginBackend) Initialize(ctx context.Context, req *logical.InitializationRequest) error { return nil } - -// SpecialPaths is a thin wrapper used to ensure we grab the lock for race purposes -func (b *PluginBackend) SpecialPaths() *logical.Paths { - b.RLock() - defer b.RUnlock() - return b.Backend.SpecialPaths() -} - -// System is a thin wrapper used to ensure we grab the lock for race purposes -func (b *PluginBackend) System() logical.SystemView { - b.RLock() - defer b.RUnlock() - return b.Backend.System() -} - -// Logger is a thin wrapper used to ensure we grab the lock for race purposes -func (b *PluginBackend) Logger() log.Logger { - b.RLock() - defer b.RUnlock() - return b.Backend.Logger() -} - -// Cleanup is a thin wrapper used to ensure we grab the lock for race purposes -func (b *PluginBackend) Cleanup(ctx context.Context) { - b.RLock() - defer b.RUnlock() - b.Backend.Cleanup(ctx) -} - -// InvalidateKey is a thin wrapper used to ensure we grab the lock for race purposes -func (b *PluginBackend) InvalidateKey(ctx context.Context, key string) { - b.RLock() - defer b.RUnlock() - b.Backend.InvalidateKey(ctx, key) -} - -// Setup is a thin wrapper used to ensure we grab the lock for race purposes -func (b *PluginBackend) Setup(ctx context.Context, config *logical.BackendConfig) error { - b.RLock() - defer b.RUnlock() - return b.Backend.Setup(ctx, config) -} - -// Type is a thin wrapper used to ensure we grab the lock for race purposes -func (b *PluginBackend) Type() logical.BackendType { - b.RLock() - defer b.RUnlock() - return b.Backend.Type() -} diff --git a/changelog/11904.txt b/changelog/11904.txt deleted file mode 100644 index 584aeae8d3b33..0000000000000 --- a/changelog/11904.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:bug -api: properly handle switching to/from unix domain socket when changing client address -``` diff --git a/changelog/11969.txt b/changelog/11969.txt deleted file mode 100644 index 668093565d33c..0000000000000 --- a/changelog/11969.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -agent: JWT auto auth now supports a `remove_jwt_after_reading` config option which defaults to true. -``` \ No newline at end of file diff --git a/changelog/14399.txt b/changelog/14399.txt deleted file mode 100644 index 5d5c6b179c9f3..0000000000000 --- a/changelog/14399.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:bug -debug: Fix panic when capturing debug bundle on Windows -``` \ No newline at end of file diff --git a/changelog/15552.txt b/changelog/15552.txt deleted file mode 100644 index 22d854bc54b45..0000000000000 --- a/changelog/15552.txt +++ /dev/null @@ -1,6 +0,0 @@ -```release-note:bug -openapi: Fixed issue where information about /auth/token endpoints was not present with explicit policy permissions -``` -```release-note:bug -api: Fixed issue with internal/ui/mounts and internal/ui/mounts/(?P.+) endpoints where it was not properly handling /auth/ -``` \ No newline at end of file diff --git a/changelog/15561.txt b/changelog/15561.txt deleted file mode 100644 index 95787b654e184..0000000000000 --- a/changelog/15561.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -ssh: Addition of an endpoint `ssh/issue/:role` to allow the creation of signed key pairs -``` diff --git a/changelog/15583.txt b/changelog/15583.txt deleted file mode 100644 index b6cda31682745..0000000000000 --- a/changelog/15583.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:bug -core (enterprise): Fix bug where wrapping token lookup does not work within namespaces. -``` diff --git a/changelog/15638.txt b/changelog/15638.txt deleted file mode 100644 index 94179552f754c..0000000000000 --- a/changelog/15638.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:bug -vault: Fix a bug where duplicate policies could be added to an identity group. -``` \ No newline at end of file diff --git a/changelog/15681.txt b/changelog/15681.txt deleted file mode 100644 index 2054411503d8f..0000000000000 --- a/changelog/15681.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:bug -ui: Fixed bug where red spellcheck underline appears in sensitive/secret kv values when it should not appear -``` \ No newline at end of file diff --git a/changelog/15735.txt b/changelog/15735.txt deleted file mode 100644 index 3dd6600e3c9b8..0000000000000 --- a/changelog/15735.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:bug -quotas/lease-count: Fix lease-count quotas on mounts not properly being enforced when the lease generating request is a read -``` diff --git a/changelog/15742.txt b/changelog/15742.txt deleted file mode 100644 index c7f69b6f70b90..0000000000000 --- a/changelog/15742.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -secret/transit: Allow importing Ed25519 keys from PKCS#8 with inner RFC 5915 ECPrivateKey blobs (NSS-wrapped keys). -``` diff --git a/changelog/15809.txt b/changelog/15809.txt deleted file mode 100644 index 87e42c82e679a..0000000000000 --- a/changelog/15809.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -secret/nomad: allow reading CA and client auth certificate from /nomad/config/access -``` diff --git a/changelog/15835.txt b/changelog/15835.txt deleted file mode 100644 index d689c2a38ca65..0000000000000 --- a/changelog/15835.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:bug -api/sys/internal/specs/openapi: support a new "dynamic" query parameter to generate generic mountpaths -``` diff --git a/changelog/15852.txt b/changelog/15852.txt deleted file mode 100644 index 8ed97dcc30298..0000000000000 --- a/changelog/15852.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -ui: Changed the tokenBoundCidrs tooltip content to clarify that comma separated values are not accepted in this field. -``` \ No newline at end of file diff --git a/changelog/15866.txt b/changelog/15866.txt deleted file mode 100644 index 384762e11af5b..0000000000000 --- a/changelog/15866.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -physical/postgresql: pass context to queries to propagate timeouts and cancellations on requests. -``` \ No newline at end of file diff --git a/changelog/15898.txt b/changelog/15898.txt deleted file mode 100644 index 02e380d2fcf03..0000000000000 --- a/changelog/15898.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -ui: Removed deprecated version of core-js 2.6.11 -``` \ No newline at end of file diff --git a/changelog/15900.txt b/changelog/15900.txt deleted file mode 100644 index ec1e8b66ce97b..0000000000000 --- a/changelog/15900.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:bug -core: Fixes parsing boolean values for ha_storage backends in config -``` \ No newline at end of file diff --git a/changelog/15912.txt b/changelog/15912.txt deleted file mode 100644 index 391d7353b6280..0000000000000 --- a/changelog/15912.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:change -identity: a request to `/identity/group` that includes `member_group_ids` that contains a cycle will now be responded to with a 400 rather than 500 -``` diff --git a/changelog/15989.txt b/changelog/15989.txt deleted file mode 100644 index 68ad2789f1b00..0000000000000 --- a/changelog/15989.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -core/quotas: Added ability to add path suffixes for rate-limit resource quotas -``` \ No newline at end of file diff --git a/changelog/15996.txt b/changelog/15996.txt deleted file mode 100644 index b29f1da19fae1..0000000000000 --- a/changelog/15996.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -secret/pki: Allow issuing certificates with non-domain, non-email Common Names from roles, sign-verbatim, and as issuers (`cn_validations`). -``` diff --git a/changelog/15998.txt b/changelog/15998.txt deleted file mode 100644 index 69274f6c3ff4b..0000000000000 --- a/changelog/15998.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:feature -ui: UI support for Okta Number Challenge. -``` diff --git a/changelog/16000.txt b/changelog/16000.txt deleted file mode 100644 index fde39b9598823..0000000000000 --- a/changelog/16000.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -core: Limit activity log client count usage by namespaces -``` \ No newline at end of file diff --git a/changelog/16063.txt b/changelog/16063.txt deleted file mode 100644 index aa90becd6170e..0000000000000 --- a/changelog/16063.txt +++ /dev/null @@ -1,4 +0,0 @@ -```release-note:improvement -website/docs: Update replication docs to mention Integrated Storage -``` - diff --git a/changelog/16115.txt b/changelog/16115.txt deleted file mode 100644 index 82998b6568493..0000000000000 --- a/changelog/16115.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -core/quotas: Added ability to add role information for rate-limit resource quotas, to limit login requests on auth mounts made using that role -``` \ No newline at end of file diff --git a/changelog/16124.txt b/changelog/16124.txt deleted file mode 100644 index 38eca2af9e402..0000000000000 --- a/changelog/16124.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -secret/pki: Add signature_bits to sign-intermediate, sign-verbatim endpoints -``` diff --git a/changelog/16140.txt b/changelog/16140.txt deleted file mode 100644 index 1fffd7ef82e39..0000000000000 --- a/changelog/16140.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -secrets/ad: set config default length only if password_policy is missing -``` diff --git a/changelog/16146.txt b/changelog/16146.txt deleted file mode 100644 index 39086b3b044f4..0000000000000 --- a/changelog/16146.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -core/activity: generate hyperloglogs containing clientIds for each month during precomputation -``` \ No newline at end of file diff --git a/changelog/16162.txt b/changelog/16162.txt deleted file mode 100644 index 5e3c348eae462..0000000000000 --- a/changelog/16162.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -core/activity: refactor activity log api to reuse partial api functions in activity endpoint when current month is specified -``` \ No newline at end of file diff --git a/changelog/16181.txt b/changelog/16181.txt deleted file mode 100644 index 1e97d1e15c25d..0000000000000 --- a/changelog/16181.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -identity/oidc: allows filtering the list providers response by an allowed_client_id -``` diff --git a/changelog/16184.txt b/changelog/16184.txt deleted file mode 100644 index e7a8b065e3980..0000000000000 --- a/changelog/16184.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -core/activity: use monthly hyperloglogs to calculate new clients approximation for current month -``` \ No newline at end of file diff --git a/changelog/16240.txt b/changelog/16240.txt deleted file mode 100644 index b04d9c0516f77..0000000000000 --- a/changelog/16240.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -secrets/kubernetes: Add allowed_kubernetes_namespace_selector to allow selecting Kubernetes namespaces with a label selector when configuring roles. -``` diff --git a/changelog/16274.txt b/changelog/16274.txt deleted file mode 100644 index 75374ed95d89b..0000000000000 --- a/changelog/16274.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -auth/oidc: Adds support for group membership parsing when using SecureAuth as an OIDC provider. -``` diff --git a/changelog/16351.txt b/changelog/16351.txt deleted file mode 100644 index 879c7f65be827..0000000000000 --- a/changelog/16351.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -secrets/ssh: Allow the use of Identity templates in the `default_user` field -``` diff --git a/changelog/16353.txt b/changelog/16353.txt deleted file mode 100644 index be247cc9f0394..0000000000000 --- a/changelog/16353.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -core: remove gox -``` \ No newline at end of file diff --git a/changelog/16379.txt b/changelog/16379.txt deleted file mode 100644 index 99ed7e5ece740..0000000000000 --- a/changelog/16379.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:change -core: Validate input parameters for vault operator init command. Vault 1.12 CLI version is needed to run operator init now. -``` \ No newline at end of file diff --git a/changelog/16386.txt b/changelog/16386.txt deleted file mode 100644 index 4fa6a6ca6649b..0000000000000 --- a/changelog/16386.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:bug -core/quotas: Added globbing functionality on the end of path suffix quota paths -``` diff --git a/changelog/16409.txt b/changelog/16409.txt deleted file mode 100644 index d8f83b029d026..0000000000000 --- a/changelog/16409.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -command/audit: Improve missing type error message -``` diff --git a/changelog/16421.txt b/changelog/16421.txt deleted file mode 100644 index 281d2e8717346..0000000000000 --- a/changelog/16421.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -command/server: add `-dev-tls` and `-dev-tls-cert-dir` subcommands to create a Vault dev server with generated certificates and private key. -``` diff --git a/changelog/16435.txt b/changelog/16435.txt deleted file mode 100644 index a7246e31eedcd..0000000000000 --- a/changelog/16435.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -auth/gcp: Add support for GCE regional instance groups -``` \ No newline at end of file diff --git a/changelog/16441.txt b/changelog/16441.txt deleted file mode 100644 index f265483d86ea2..0000000000000 --- a/changelog/16441.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -cli: CLI commands will print a warning if flags will be ignored because they are passed after positional arguments. -``` diff --git a/changelog/16447.txt b/changelog/16447.txt deleted file mode 100644 index 47102deca2719..0000000000000 --- a/changelog/16447.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:bug -activity: Add timestamp to current month calculation and remove deduplication for current month -``` diff --git a/changelog/16455.txt b/changelog/16455.txt deleted file mode 100644 index 660dbc10588b3..0000000000000 --- a/changelog/16455.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -auth/aws: PKCS7 signatures will now use SHA256 by default in prep for Go 1.18 -``` diff --git a/changelog/16487.txt b/changelog/16487.txt deleted file mode 100644 index cbf2a2a586fef..0000000000000 --- a/changelog/16487.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -identity: Prevent possibility of data races on entity creation. -``` diff --git a/changelog/16489.txt b/changelog/16489.txt deleted file mode 100644 index 17c66ca9f795f..0000000000000 --- a/changelog/16489.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -ui: Renamed labels under Tools for wrap, lookup, rewrap and unwrap with description. -``` diff --git a/changelog/16494.txt b/changelog/16494.txt deleted file mode 100644 index 40cf3643ad0c0..0000000000000 --- a/changelog/16494.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -secret/pki: Allow specifying SKID for cross-signed issuance from older Vault versions. -``` diff --git a/changelog/16519.txt b/changelog/16519.txt deleted file mode 100644 index 1325202e62648..0000000000000 --- a/changelog/16519.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -secret/pki: Add RSA PSS signature support for issuing certificates, signing CRLs -``` diff --git a/changelog/16523.txt b/changelog/16523.txt new file mode 100644 index 0000000000000..0e7350a09f679 --- /dev/null +++ b/changelog/16523.txt @@ -0,0 +1,3 @@ +```release-note:bug +auth/gcp: Fixes the ability to reset the configuration's credentials to use application default credentials. +``` diff --git a/changelog/16525.txt b/changelog/16525.txt deleted file mode 100644 index 2f611afc5c86c..0000000000000 --- a/changelog/16525.txt +++ /dev/null @@ -1,6 +0,0 @@ -```release-note:improvement -auth/jwt: Improves detection of Windows Subsystem for Linux (WSL) for CLI-based logins. -``` -```release-note:improvement -auth/jwt: Adds support for Microsoft US Gov L4 to the Azure provider for groups fetching. -``` diff --git a/changelog/16526.txt b/changelog/16526.txt new file mode 100644 index 0000000000000..50051731e914a --- /dev/null +++ b/changelog/16526.txt @@ -0,0 +1,3 @@ +```release-note:bug +database/elasticsearch: Fixes a bug in boolean parsing for initialize +``` diff --git a/changelog/16539.txt b/changelog/16539.txt deleted file mode 100644 index 9927329b5728a..0000000000000 --- a/changelog/16539.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:change -core/entities: Fixed stranding of aliases upon entity merge, and require explicit selection of which aliases should be kept when some must be deleted -``` diff --git a/changelog/16567.txt b/changelog/16567.txt deleted file mode 100644 index 78492e304549c..0000000000000 --- a/changelog/16567.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -identity/oidc: Adds support for detailed listing of clients and providers. -``` diff --git a/changelog/16609.txt b/changelog/16609.txt deleted file mode 100644 index 13ecb7bbcdb56..0000000000000 --- a/changelog/16609.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -core: Upgrade github.com/hashicorp/raft -``` \ No newline at end of file diff --git a/changelog/16631.txt b/changelog/16631.txt deleted file mode 100644 index 73c46f65569a3..0000000000000 --- a/changelog/16631.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:feature -secrets/database/hana: Add ability to customize dynamic usernames -``` \ No newline at end of file diff --git a/changelog/16721.txt b/changelog/16721.txt new file mode 100644 index 0000000000000..84e0ffa92ab67 --- /dev/null +++ b/changelog/16721.txt @@ -0,0 +1,3 @@ +```release-note:bug +secrets/pki: Ignore EC PARAMETER PEM blocks during issuer import (/config/ca, /issuers/import/*, and /intermediate/set-signed) +``` diff --git a/changelog/README.md b/changelog/README.md index cbf841f6c77b7..cf49db4264d08 100644 --- a/changelog/README.md +++ b/changelog/README.md @@ -1,56 +1,3 @@ # changelog -This folder holds changelog updates from commit 3bc7d15 onwards. - -Release notes are text files with three lines: - - 1. An opening code block with the `release-note:` type annotation. - - For example: - - ```release-note:bug - - Valid modes are: - - - `bug` - Any sort of non-security defect fix. - - `change` - A change in the product that may require action or - review by the operator. Examples would be any kind of API change - (as opposed to backwards compatible addition), a notable behavior - change, or anything that might require attention before updating. Go - version changes are also listed here since they can potentially have - large, sometimes unknown impacts. (Go updates are a special case, and - dep updates in general aren't a `change`). Discussion of any potential - `change` items in the pull request to see what other communication - might be warranted. - - `deprecation` - Announcement of a planned future removal of a - feature. Only use this if a deprecation notice also exists [in the - docs](https://www.vaultproject.io/docs/deprecation). - - `feature` - Large topical additions for a major release. These are - rarely in minor releases. Formatting for `feature` entries differs - from normal changelog formatting - see the [new features - instructions](#new-and-major-features). - - `improvement` - Most updates to the product that aren’t `bug`s, but - aren't big enough to be a `feature`, will be an `improvement`. - - 2. A component (for example, `secret/pki` or `sdk/framework` or), a colon and a space, and then a one-line description of the change. - - 3. An ending code block. - -This should be in a file named after the pull request number (e.g., `12345.txt`). - -There are many examples in this folder; check one out if you're stuck! - -See [hashicorp/go-changelog](https://github.com/hashicorp/go-changelog) for full documentation on the supported entries. - -## New and Major Features - -For features we are introducing in a new major release, we prefer a single -changelog entry representing that feature. This way, it is clear to readers -what feature is being introduced. You do not need to reference a specific PR, -and the formatting is slightly different - your changelog file should look -like: - - changelog/.txt: - ```release-note:feature - **Feature Name**: Description of feature - for example "Custom password policies are now supported for all database engines." - ``` +This folder holds changelog updates from commit 3bc7d15 onwards. See [hashicorp/go-changelog](https://github.com/hashicorp/go-changelog) for full documentation on the supported entries. diff --git a/changelog/_go-ver-1111.txt b/changelog/_go-ver-1111.txt new file mode 100644 index 0000000000000..c9e146855741c --- /dev/null +++ b/changelog/_go-ver-1111.txt @@ -0,0 +1,3 @@ +```release-note:change +core: Bump Go version to 1.17.12. +``` diff --git a/changelog/_go-ver-1120.txt b/changelog/_go-ver-1120.txt deleted file mode 100644 index 911ed775fb0d8..0000000000000 --- a/changelog/_go-ver-1120.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:change -core: Bump Go version to 1.18.4. -``` diff --git a/changelog/go-ver-1110.txt b/changelog/go-ver-1110.txt index 7f43e9fd544e8..5a5112885f087 100644 --- a/changelog/go-ver-1110.txt +++ b/changelog/go-ver-1110.txt @@ -1,3 +1,3 @@ ```release-note:change -core: Bump Go version to 1.17.9. +core: Bump Go version to 1.17.11. ``` diff --git a/command/agent.go b/command/agent.go index cd6daaf009411..898c9a641ef26 100644 --- a/command/agent.go +++ b/command/agent.go @@ -962,7 +962,7 @@ func verifyRequestHeader(handler http.Handler) http.Handler { if val, ok := r.Header[consts.RequestHeaderName]; !ok || len(val) != 1 || val[0] != "true" { logical.RespondError(w, http.StatusPreconditionFailed, - fmt.Errorf("missing %q header", consts.RequestHeaderName)) + fmt.Errorf("missing '%s' header", consts.RequestHeaderName)) return } diff --git a/command/agent/alicloud_end_to_end_test.go b/command/agent/alicloud_end_to_end_test.go index 948f9fa5accf4..1684ecae4ad71 100644 --- a/command/agent/alicloud_end_to_end_test.go +++ b/command/agent/alicloud_end_to_end_test.go @@ -190,7 +190,7 @@ func setAliCloudEnvCreds() error { } assumeRoleReq := sts.CreateAssumeRoleRequest() assumeRoleReq.RoleArn = os.Getenv(envVarAlicloudRoleArn) - assumeRoleReq.RoleSessionName = strings.ReplaceAll(roleSessionName, "-", "") + assumeRoleReq.RoleSessionName = strings.Replace(roleSessionName, "-", "", -1) assumeRoleResp, err := client.AssumeRole(assumeRoleReq) if err != nil { return err diff --git a/command/agent/auth/jwt/jwt.go b/command/agent/auth/jwt/jwt.go index 8f088eb199e5e..0c97bee905ec3 100644 --- a/command/agent/auth/jwt/jwt.go +++ b/command/agent/auth/jwt/jwt.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io/fs" + "io/ioutil" "net/http" "os" "sync" @@ -14,23 +15,21 @@ import ( hclog "github.com/hashicorp/go-hclog" "github.com/hashicorp/vault/api" "github.com/hashicorp/vault/command/agent/auth" - "github.com/hashicorp/vault/sdk/helper/parseutil" ) type jwtMethod struct { - logger hclog.Logger - path string - mountPath string - role string - removeJWTAfterReading bool - credsFound chan struct{} - watchCh chan string - stopCh chan struct{} - doneCh chan struct{} - credSuccessGate chan struct{} - ticker *time.Ticker - once *sync.Once - latestToken *atomic.Value + logger hclog.Logger + path string + mountPath string + role string + credsFound chan struct{} + watchCh chan string + stopCh chan struct{} + doneCh chan struct{} + credSuccessGate chan struct{} + ticker *time.Ticker + once *sync.Once + latestToken *atomic.Value } // NewJWTAuthMethod returns an implementation of Agent's auth.AuthMethod @@ -44,16 +43,15 @@ func NewJWTAuthMethod(conf *auth.AuthConfig) (auth.AuthMethod, error) { } j := &jwtMethod{ - logger: conf.Logger, - mountPath: conf.MountPath, - removeJWTAfterReading: true, - credsFound: make(chan struct{}), - watchCh: make(chan string), - stopCh: make(chan struct{}), - doneCh: make(chan struct{}), - credSuccessGate: make(chan struct{}), - once: new(sync.Once), - latestToken: new(atomic.Value), + logger: conf.Logger, + mountPath: conf.MountPath, + credsFound: make(chan struct{}), + watchCh: make(chan string), + stopCh: make(chan struct{}), + doneCh: make(chan struct{}), + credSuccessGate: make(chan struct{}), + once: new(sync.Once), + latestToken: new(atomic.Value), } j.latestToken.Store("") @@ -75,14 +73,6 @@ func NewJWTAuthMethod(conf *auth.AuthConfig) (auth.AuthMethod, error) { return nil, errors.New("could not convert 'role' config value to string") } - if removeJWTAfterReadingRaw, ok := conf.Config["remove_jwt_after_reading"]; ok { - removeJWTAfterReading, err := parseutil.ParseBool(removeJWTAfterReadingRaw) - if err != nil { - return nil, fmt.Errorf("error parsing 'remove_jwt_after_reading' value: %w", err) - } - j.removeJWTAfterReading = removeJWTAfterReading - } - switch { case j.path == "": return nil, errors.New("'path' value is empty") @@ -90,14 +80,7 @@ func NewJWTAuthMethod(conf *auth.AuthConfig) (auth.AuthMethod, error) { return nil, errors.New("'role' value is empty") } - // If we don't delete the JWT after reading, use a slower reload period, - // otherwise we would re-read the whole file every 500ms, instead of just - // doing a stat on the file every 500ms. - readPeriod := 1 * time.Minute - if j.removeJWTAfterReading { - readPeriod = 500 * time.Millisecond - } - j.ticker = time.NewTicker(readPeriod) + j.ticker = time.NewTicker(500 * time.Millisecond) go j.runWatcher() @@ -162,7 +145,6 @@ func (j *jwtMethod) runWatcher() { j.ingressToken() newToken := j.latestToken.Load().(string) if newToken != latestToken { - j.logger.Debug("new jwt file found") j.credsFound <- struct{}{} } } @@ -179,9 +161,11 @@ func (j *jwtMethod) ingressToken() { return } + j.logger.Debug("new jwt file found") + // Check that the path refers to a file. // If it's a symlink, it could still be a symlink to a directory, - // but os.ReadFile below will return a descriptive error. + // but ioutil.ReadFile below will return a descriptive error. switch mode := fi.Mode(); { case mode.IsRegular(): // regular file @@ -192,7 +176,7 @@ func (j *jwtMethod) ingressToken() { return } - token, err := os.ReadFile(j.path) + token, err := ioutil.ReadFile(j.path) if err != nil { j.logger.Error("failed to read jwt file", "error", err) return @@ -206,9 +190,7 @@ func (j *jwtMethod) ingressToken() { j.latestToken.Store(string(token)) } - if j.removeJWTAfterReading { - if err := os.Remove(j.path); err != nil { - j.logger.Error("error removing jwt file", "error", err) - } + if err := os.Remove(j.path); err != nil { + j.logger.Error("error removing jwt file", "error", err) } } diff --git a/command/agent/auth/jwt/jwt_test.go b/command/agent/auth/jwt/jwt_test.go index 8e9a2ae86c136..f912006b15130 100644 --- a/command/agent/auth/jwt/jwt_test.go +++ b/command/agent/auth/jwt/jwt_test.go @@ -2,6 +2,7 @@ package jwt import ( "bytes" + "io/ioutil" "os" "path" "strings" @@ -9,7 +10,6 @@ import ( "testing" "github.com/hashicorp/go-hclog" - "github.com/hashicorp/vault/command/agent/auth" ) func TestIngressToken(t *testing.T) { @@ -21,18 +21,18 @@ func TestIngressToken(t *testing.T) { symlinked = "symlinked" ) - rootDir, err := os.MkdirTemp("", "vault-agent-jwt-auth-test") + rootDir, err := ioutil.TempDir("", "vault-agent-jwt-auth-test") if err != nil { t.Fatalf("failed to create temp dir: %s", err) } defer os.RemoveAll(rootDir) setupTestDir := func() string { - testDir, err := os.MkdirTemp(rootDir, "") + testDir, err := ioutil.TempDir(rootDir, "") if err != nil { t.Fatal(err) } - err = os.WriteFile(path.Join(testDir, file), []byte("test"), 0o644) + err = ioutil.WriteFile(path.Join(testDir, file), []byte("test"), 0o644) if err != nil { t.Fatal(err) } @@ -106,62 +106,3 @@ func TestIngressToken(t *testing.T) { } } } - -func TestDeleteAfterReading(t *testing.T) { - for _, tc := range map[string]struct { - configValue string - shouldDelete bool - }{ - "default": { - "", - true, - }, - "explicit true": { - "true", - true, - }, - "false": { - "false", - false, - }, - } { - rootDir, err := os.MkdirTemp("", "vault-agent-jwt-auth-test") - if err != nil { - t.Fatalf("failed to create temp dir: %s", err) - } - defer os.RemoveAll(rootDir) - tokenPath := path.Join(rootDir, "token") - err = os.WriteFile(tokenPath, []byte("test"), 0o644) - if err != nil { - t.Fatal(err) - } - - config := &auth.AuthConfig{ - Config: map[string]interface{}{ - "path": tokenPath, - "role": "unusedrole", - }, - Logger: hclog.Default(), - } - if tc.configValue != "" { - config.Config["remove_jwt_after_reading"] = tc.configValue - } - - jwtAuth, err := NewJWTAuthMethod(config) - if err != nil { - t.Fatal(err) - } - - jwtAuth.(*jwtMethod).ingressToken() - - if _, err := os.Lstat(tokenPath); tc.shouldDelete { - if err == nil || !os.IsNotExist(err) { - t.Fatal(err) - } - } else { - if err != nil { - t.Fatal(err) - } - } - } -} diff --git a/command/agent/config/config_test.go b/command/agent/config/config_test.go index 3565e196f6a47..fa7e72394358c 100644 --- a/command/agent/config/config_test.go +++ b/command/agent/config/config_test.go @@ -372,9 +372,9 @@ func TestLoadConfigFile_Bad_AgentCache_InconsisentAutoAuth(t *testing.T) { } func TestLoadConfigFile_Bad_AgentCache_ForceAutoAuthNoMethod(t *testing.T) { - _, err := LoadConfig("./test-fixtures/bad-config-cache-force-auto_auth.hcl") + _, err := LoadConfig("./test-fixtures/bad-config-cache-inconsistent-auto_auth.hcl") if err == nil { - t.Fatal("LoadConfig should return an error when use_auto_auth_token=force and no auto_auth section present") + t.Fatal("LoadConfig should return an error when use_auto_auth_token=true and no auto_auth section present") } } diff --git a/command/agent_test.go b/command/agent_test.go index c5138144ef9c0..4b62020e1dfb0 100644 --- a/command/agent_test.go +++ b/command/agent_test.go @@ -909,7 +909,7 @@ auto_auth { continue } if string(c) != templateRendered(i)+suffix { - err = fmt.Errorf("expected=%q, got=%q", templateRendered(i)+suffix, string(c)) + err = fmt.Errorf("expected='%s', got='%s'", templateRendered(i)+suffix, string(c)) continue } } @@ -1462,7 +1462,7 @@ template_config { continue } if string(c) != templateRendered(0) { - err = fmt.Errorf("expected=%q, got=%q", templateRendered(0), string(c)) + err = fmt.Errorf("expected='%s', got='%s'", templateRendered(0), string(c)) continue } return nil @@ -1982,7 +1982,7 @@ vault { continue } if strings.TrimSpace(string(c)) != tc.expectTemplateRender { - err = fmt.Errorf("expected=%q, got=%q", tc.expectTemplateRender, strings.TrimSpace(string(c))) + err = fmt.Errorf("expected='%s', got='%s'", tc.expectTemplateRender, strings.TrimSpace(string(c))) continue } return nil diff --git a/command/audit_enable.go b/command/audit_enable.go index 9ed7d5d30694a..fae42394462d5 100644 --- a/command/audit_enable.go +++ b/command/audit_enable.go @@ -110,7 +110,7 @@ func (c *AuditEnableCommand) Run(args []string) int { args = f.Args() if len(args) < 1 { - c.UI.Error("Error enabling audit device: audit type missing. Valid types include 'file', 'socket' and 'syslog'.") + c.UI.Error("Missing TYPE!") return 1 } diff --git a/command/audit_enable_test.go b/command/audit_enable_test.go index 7d19f086ad586..1f55703c27bf1 100644 --- a/command/audit_enable_test.go +++ b/command/audit_enable_test.go @@ -32,7 +32,7 @@ func TestAuditEnableCommand_Run(t *testing.T) { { "empty", nil, - "Error enabling audit device: audit type missing. Valid types include 'file', 'socket' and 'syslog'.", + "Missing TYPE!", 1, }, { diff --git a/command/base.go b/command/base.go index bbad7beca2a2e..5f6a171dcee2c 100644 --- a/command/base.go +++ b/command/base.go @@ -549,7 +549,6 @@ type FlagSets struct { mainSet *flag.FlagSet hiddens map[string]struct{} completions complete.Flags - ui cli.Ui } // NewFlagSets creates a new flag sets. @@ -565,7 +564,6 @@ func NewFlagSets(ui cli.Ui) *FlagSets { mainSet: mainSet, hiddens: make(map[string]struct{}), completions: complete.Flags{}, - ui: ui, } } @@ -584,16 +582,8 @@ func (f *FlagSets) Completions() complete.Flags { } // Parse parses the given flags, returning any errors. -// Warnings, if any, regarding the arguments format are sent to stdout func (f *FlagSets) Parse(args []string) error { - err := f.mainSet.Parse(args) - - warnings := generateFlagWarnings(f.Args()) - if warnings != "" { - f.ui.Warn(warnings) - } - - return err + return f.mainSet.Parse(args) } // Parsed reports whether the command-line flags have been parsed. @@ -613,10 +603,10 @@ func (f *FlagSets) Visit(fn func(*flag.Flag)) { } // Help builds custom help for this command, grouping by flag set. -func (f *FlagSets) Help() string { +func (fs *FlagSets) Help() string { var out bytes.Buffer - for _, set := range f.flagSets { + for _, set := range fs.flagSets { printFlagTitle(&out, set.name+":") set.VisitAll(func(f *flag.Flag) { // Skip any hidden flags diff --git a/command/base_helpers.go b/command/base_helpers.go index 03e135a525a37..f20cfebf71025 100644 --- a/command/base_helpers.go +++ b/command/base_helpers.go @@ -292,19 +292,3 @@ func parseFlagFile(raw string) (string, error) { return raw, nil } - -func generateFlagWarnings(args []string) string { - var trailingFlags []string - for _, arg := range args { - if strings.HasPrefix(arg, "-") { - trailingFlags = append(trailingFlags, arg) - } - } - - if len(trailingFlags) > 0 { - return fmt.Sprintf("Flags must be provided before positional arguments. "+ - "The following arguments will not be parsed as flags: [%s]", strings.Join(trailingFlags, ",")) - } else { - return "" - } -} diff --git a/command/base_helpers_test.go b/command/base_helpers_test.go index 4703153df1b46..df764d36e4db7 100644 --- a/command/base_helpers_test.go +++ b/command/base_helpers_test.go @@ -5,7 +5,6 @@ import ( "io" "io/ioutil" "os" - "strings" "testing" "time" ) @@ -210,48 +209,3 @@ func TestParseFlagFile(t *testing.T) { }) } } - -func TestArgWarnings(t *testing.T) { - t.Parallel() - - cases := []struct { - args []string - expected string - }{ - { - []string{"a", "b", "c"}, - "", - }, - { - []string{"a", "-b"}, - "-b", - }, - { - []string{"a", "--b"}, - "--b", - }, - { - []string{"a-b", "-c"}, - "-c", - }, - { - []string{"a", "-b-c"}, - "-b-c", - }, - { - []string{"-a", "b"}, - "-a", - }, - } - - for _, tc := range cases { - tc := tc - - t.Run(tc.expected, func(t *testing.T) { - warnings := generateFlagWarnings(tc.args) - if !strings.Contains(warnings, tc.expected) { - t.Fatalf("expected %s to contain %s", warnings, tc.expected) - } - }) - } -} diff --git a/command/commands.go b/command/commands.go index f6aad476d1f39..6b9f5c89e7435 100644 --- a/command/commands.go +++ b/command/commands.go @@ -347,11 +347,6 @@ func initCommands(ui, serverCmdUi cli.Ui, runOpts *RunOptions) { BaseCommand: getBaseCommand(), }, nil }, - "namespace patch": func() (cli.Command, error) { - return &NamespacePatchCommand{ - BaseCommand: getBaseCommand(), - }, nil - }, "namespace delete": func() (cli.Command, error) { return &NamespaceDeleteCommand{ BaseCommand: getBaseCommand(), diff --git a/command/debug.go b/command/debug.go index 631ec9b418c63..0dd0fbf13a426 100644 --- a/command/debug.go +++ b/command/debug.go @@ -349,7 +349,7 @@ func (c *DebugCommand) generateIndex() error { dir, file := filepath.Split(relPath) if len(dir) != 0 { - dir = filepath.Clean(dir) + dir = strings.TrimSuffix(dir, "/") filesArr := outputLayout[dir].(map[string]interface{})["files"] outputLayout[dir].(map[string]interface{})["files"] = append(filesArr.([]string), file) } else { @@ -448,7 +448,7 @@ func (c *DebugCommand) preflight(rawArgs []string) (string, error) { } // Strip trailing slash before proceeding - c.flagOutput = filepath.Clean(c.flagOutput) + c.flagOutput = strings.TrimSuffix(c.flagOutput, "/") // If compression is enabled, trim the extension so that the files are // written to a directory even if compression somehow fails. We ensure the diff --git a/command/login.go b/command/login.go index 9beab755b8435..fc2a0f7e6a59b 100644 --- a/command/login.go +++ b/command/login.go @@ -55,8 +55,8 @@ Usage: vault login [options] [AUTH K=V...] $ vault login -method=userpass username=my-username For more information about the list of configuration parameters available for - a given auth method, use the "vault auth help TYPE" command. You can also use - "vault auth list" to see the list of enabled auth methods. + a given auth method, use the "vault auth help TYPE". You can also use "vault + auth list" to see the list of enabled auth methods. If an auth method is enabled at a non-standard path, the -method flag still refers to the canonical type, but the -path flag refers to the enabled path. diff --git a/command/namespace.go b/command/namespace.go index 702395753da8a..89cf2e0296855 100644 --- a/command/namespace.go +++ b/command/namespace.go @@ -36,10 +36,6 @@ Usage: vault namespace [options] [args] $ vault namespace create - Patch an existing namespace: - - $ vault namespace patch - Delete an existing namespace: $ vault namespace delete diff --git a/command/namespace_create.go b/command/namespace_create.go index 7d1f52fa8c9ba..80ce589f963d8 100644 --- a/command/namespace_create.go +++ b/command/namespace_create.go @@ -15,8 +15,6 @@ var ( type NamespaceCreateCommand struct { *BaseCommand - - flagCustomMetadata map[string]string } func (c *NamespaceCreateCommand) Synopsis() string { @@ -45,18 +43,7 @@ Usage: vault namespace create [options] PATH } func (c *NamespaceCreateCommand) Flags() *FlagSets { - set := c.flagSet(FlagSetHTTP | FlagSetOutputField | FlagSetOutputFormat) - - f := set.NewFlagSet("Command Options") - f.StringMapVar(&StringMapVar{ - Name: "custom-metadata", - Target: &c.flagCustomMetadata, - Default: map[string]string{}, - Usage: "Specifies arbitrary key=value metadata meant to describe a namespace." + - "This can be specified multiple times to add multiple pieces of metadata.", - }) - - return set + return c.flagSet(FlagSetHTTP | FlagSetOutputField | FlagSetOutputFormat) } func (c *NamespaceCreateCommand) AutocompleteArgs() complete.Predictor { @@ -93,11 +80,7 @@ func (c *NamespaceCreateCommand) Run(args []string) int { return 2 } - data := map[string]interface{}{ - "custom_metadata": c.flagCustomMetadata, - } - - secret, err := client.Logical().Write("sys/namespaces/"+namespacePath, data) + secret, err := client.Logical().Write("sys/namespaces/"+namespacePath, nil) if err != nil { c.UI.Error(fmt.Sprintf("Error creating namespace: %s", err)) return 2 diff --git a/command/namespace_patch.go b/command/namespace_patch.go deleted file mode 100644 index 6f5b8390f1e0d..0000000000000 --- a/command/namespace_patch.go +++ /dev/null @@ -1,137 +0,0 @@ -package command - -import ( - "context" - "fmt" - "strings" - - "github.com/posener/complete" - - "github.com/mitchellh/cli" -) - -var ( - _ cli.Command = (*NamespacePatchCommand)(nil) - _ cli.CommandAutocomplete = (*NamespacePatchCommand)(nil) -) - -type NamespacePatchCommand struct { - *BaseCommand - - flagCustomMetadata map[string]string - flagRemoveCustomMetadata []string -} - -func (c *NamespacePatchCommand) Synopsis() string { - return "Patch an existing namespace" -} - -func (c *NamespacePatchCommand) Help() string { - helpText := ` -Usage: vault namespace patch [options] PATH - - Patch an existing namespace. The namespace patched will be relative to the - namespace provided in either the VAULT_NAMESPACE environment variable or - -namespace CLI flag. - - Patch an existing child namespace by adding and removing custom-metadata (e.g. ns1/): - - $ vault namespace patch ns1 -custom-metadata=foo=abc -remove-custom-metadata=bar - - Patch an existing child namespace from a parent namespace (e.g. ns1/ns2/): - - $ vault namespace patch -namespace=ns1 ns2 -custom-metadata=foo=abc - -` + c.Flags().Help() - - return strings.TrimSpace(helpText) -} - -func (c *NamespacePatchCommand) Flags() *FlagSets { - set := c.flagSet(FlagSetHTTP | FlagSetOutputField | FlagSetOutputFormat) - - f := set.NewFlagSet("Command Options") - f.StringMapVar(&StringMapVar{ - Name: "custom-metadata", - Target: &c.flagCustomMetadata, - Default: map[string]string{}, - Usage: "Specifies arbitrary key=value metadata meant to describe a namespace." + - "This can be specified multiple times to add multiple pieces of metadata.", - }) - - f.StringSliceVar(&StringSliceVar{ - Name: "remove-custom-metadata", - Target: &c.flagRemoveCustomMetadata, - Default: []string{}, - Usage: "Key to remove from custom metadata. To specify multiple values, specify this flag multiple times.", - }) - - return set -} - -func (c *NamespacePatchCommand) AutocompleteArgs() complete.Predictor { - return complete.PredictNothing -} - -func (c *NamespacePatchCommand) AutocompleteFlags() complete.Flags { - return c.Flags().Completions() -} - -func (c *NamespacePatchCommand) Run(args []string) int { - f := c.Flags() - - if err := f.Parse(args); err != nil { - c.UI.Error(err.Error()) - return 1 - } - - args = f.Args() - switch { - case len(args) < 1: - c.UI.Error(fmt.Sprintf("Not enough arguments (expected 1, got %d)", len(args))) - return 1 - case len(args) > 1: - c.UI.Error(fmt.Sprintf("Too many arguments (expected 1, got %d)", len(args))) - return 1 - } - - namespacePath := strings.TrimSpace(args[0]) - - client, err := c.Client() - if err != nil { - c.UI.Error(err.Error()) - return 2 - } - - data := make(map[string]interface{}) - customMetadata := make(map[string]interface{}) - - for key, value := range c.flagCustomMetadata { - customMetadata[key] = value - } - - for _, key := range c.flagRemoveCustomMetadata { - // A null in a JSON merge patch payload will remove the associated key - customMetadata[key] = nil - } - - data["custom_metadata"] = customMetadata - - secret, err := client.Logical().JSONMergePatch(context.Background(), "sys/namespaces/"+namespacePath, data) - if err != nil { - c.UI.Error(fmt.Sprintf("Error patching namespace: %s", err)) - return 2 - } - - if secret == nil || secret.Data == nil { - c.UI.Error(fmt.Sprintf("No namespace found: %s", err)) - return 2 - } - - // Handle single field output - if c.flagField != "" { - return PrintRawField(c.UI, secret, c.flagField) - } - - return OutputSecret(c.UI, secret) -} diff --git a/command/operator_init.go b/command/operator_init.go index 6d67dcd9b6a45..a8b8e56010245 100644 --- a/command/operator_init.go +++ b/command/operator_init.go @@ -40,10 +40,8 @@ type OperatorInitCommand struct { } const ( - defKeyShares = 5 - defKeyThreshold = 3 - defRecoveryShares = 5 - defRecoveryThreshold = 3 + defKeyShares = 5 + defKeyThreshold = 3 ) func (c *OperatorInitCommand) Synopsis() string { @@ -105,6 +103,7 @@ func (c *OperatorInitCommand) Flags() *FlagSets { Name: "key-shares", Aliases: []string{"n"}, Target: &c.flagKeyShares, + Default: defKeyShares, Completion: complete.PredictAnything, Usage: "Number of key shares to split the generated root key into. " + "This is the number of \"unseal keys\" to generate.", @@ -114,6 +113,7 @@ func (c *OperatorInitCommand) Flags() *FlagSets { Name: "key-threshold", Aliases: []string{"t"}, Target: &c.flagKeyThreshold, + Default: defKeyThreshold, Completion: complete.PredictAnything, Usage: "Number of key shares required to reconstruct the root key. " + "This must be less than or equal to -key-shares.", @@ -182,6 +182,7 @@ func (c *OperatorInitCommand) Flags() *FlagSets { f.IntVar(&IntVar{ Name: "recovery-shares", Target: &c.flagRecoveryShares, + Default: 5, Completion: complete.PredictAnything, Usage: "Number of key shares to split the recovery key into. " + "This is only used in auto-unseal mode.", @@ -190,6 +191,7 @@ func (c *OperatorInitCommand) Flags() *FlagSets { f.IntVar(&IntVar{ Name: "recovery-threshold", Target: &c.flagRecoveryThreshold, + Default: 3, Completion: complete.PredictAnything, Usage: "Number of key shares required to reconstruct the recovery key. " + "This is only used in Auto Unseal mode.", @@ -231,35 +233,6 @@ func (c *OperatorInitCommand) Run(args []string) int { if c.flagStoredShares != -1 { c.UI.Warn("-stored-shares has no effect and will be removed in Vault 1.3.\n") } - client, err := c.Client() - if err != nil { - c.UI.Error(err.Error()) - return 2 - } - - // Set defaults based on use of auto unseal seal - sealInfo, err := client.Sys().SealStatus() - if err != nil { - c.UI.Error(err.Error()) - return 2 - } - - switch sealInfo.RecoverySeal { - case true: - if c.flagRecoveryShares == 0 { - c.flagRecoveryShares = defRecoveryShares - } - if c.flagRecoveryThreshold == 0 { - c.flagRecoveryThreshold = defRecoveryThreshold - } - default: - if c.flagKeyShares == 0 { - c.flagKeyShares = defKeyShares - } - if c.flagKeyThreshold == 0 { - c.flagKeyThreshold = defKeyThreshold - } - } // Build the initial init request initReq := &api.InitRequest{ @@ -273,6 +246,12 @@ func (c *OperatorInitCommand) Run(args []string) int { RecoveryPGPKeys: c.flagRecoveryPGPKeys, } + client, err := c.Client() + if err != nil { + c.UI.Error(err.Error()) + return 2 + } + // Check auto mode switch { case c.flagStatus: @@ -492,6 +471,14 @@ func (c *OperatorInitCommand) init(client *api.Client, req *api.InitRequest) int req.RecoveryThreshold))) } + if len(resp.RecoveryKeys) > 0 && (req.SecretShares != defKeyShares || req.SecretThreshold != defKeyThreshold) { + c.UI.Output("") + c.UI.Warn(wrapAtLength( + "WARNING! -key-shares and -key-threshold is ignored when " + + "Auto Unseal is used. Use -recovery-shares and -recovery-threshold instead.", + )) + } + return 0 } diff --git a/command/operator_init_test.go b/command/operator_init_test.go index ec02873587dfc..491d623a14732 100644 --- a/command/operator_init_test.go +++ b/command/operator_init_test.go @@ -355,7 +355,7 @@ func TestOperatorInitCommand_Run(t *testing.T) { t.Errorf("expected %d to be %d", code, exp) } - expected := "Error making API request" + expected := "Error initializing: " combined := ui.OutputWriter.String() + ui.ErrorWriter.String() if !strings.Contains(combined, expected) { t.Errorf("expected %q to contain %q", combined, expected) diff --git a/command/operator_migrate.go b/command/operator_migrate.go index a974f58d6cb61..5dcec8a56ed6d 100644 --- a/command/operator_migrate.go +++ b/command/operator_migrate.go @@ -332,11 +332,11 @@ func (c *OperatorMigrateCommand) loadMigratorConfig(path string) (*migratorConfi for _, stanza := range []string{"storage_source", "storage_destination"} { o := list.Filter(stanza) if len(o.Items) != 1 { - return nil, fmt.Errorf("exactly one %q block is required", stanza) + return nil, fmt.Errorf("exactly one '%s' block is required", stanza) } if err := parseStorage(&result, o, stanza); err != nil { - return nil, fmt.Errorf("error parsing %q: %w", stanza, err) + return nil, fmt.Errorf("error parsing '%s': %w", stanza, err) } } return &result, nil diff --git a/command/operator_raft_join.go b/command/operator_raft_join.go index 466ab84142b41..37bc77eedbafa 100644 --- a/command/operator_raft_join.go +++ b/command/operator_raft_join.go @@ -169,7 +169,7 @@ func (c *OperatorRaftJoinCommand) Run(args []string) int { } if c.flagAutoJoinScheme != "" && (c.flagAutoJoinScheme != "http" && c.flagAutoJoinScheme != "https") { - c.UI.Error(fmt.Sprintf("invalid scheme %q; must either be http or https", c.flagAutoJoinScheme)) + c.UI.Error(fmt.Sprintf("invalid scheme '%s'; must either be http or https", c.flagAutoJoinScheme)) return 1 } diff --git a/command/server.go b/command/server.go index 32b48325b2a47..d849b8d101a5e 100644 --- a/command/server.go +++ b/command/server.go @@ -42,7 +42,6 @@ import ( "github.com/hashicorp/vault/internalshared/listenerutil" "github.com/hashicorp/vault/sdk/helper/jsonutil" "github.com/hashicorp/vault/sdk/helper/logging" - "github.com/hashicorp/vault/sdk/helper/strutil" "github.com/hashicorp/vault/sdk/helper/useragent" "github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/sdk/physical" @@ -76,9 +75,8 @@ const ( // Even though there are more types than the ones below, the following consts // are declared internally for value comparison and reusability. - storageTypeRaft = "raft" - storageTypeConsul = "consul" - disableStorageTypeCheckEnv = "VAULT_DISABLE_SUPPORTED_STORAGE_CHECK" + storageTypeRaft = "raft" + storageTypeConsul = "consul" ) type ServerCommand struct { @@ -117,8 +115,6 @@ type ServerCommand struct { flagLogFormat string flagRecovery bool flagDev bool - flagDevTLS bool - flagDevTLSCertDir string flagDevRootTokenID string flagDevListenAddr string flagDevNoStoreToken bool @@ -247,23 +243,6 @@ func (c *ServerCommand) Flags() *FlagSets { "production.", }) - f.BoolVar(&BoolVar{ - Name: "dev-tls", - Target: &c.flagDevTLS, - Usage: "Enable TLS development mode. In this mode, Vault runs in-memory and " + - "starts unsealed, with a generated TLS CA, certificate and key. " + - "As the name implies, do not run \"dev-tls\" mode in " + - "production.", - }) - - f.StringVar(&StringVar{ - Name: "dev-tls-cert-dir", - Target: &c.flagDevTLSCertDir, - Default: "", - Usage: "Directory where generated TLS files are created if `-dev-tls` is " + - "specified. If left unset, files are generated in a temporary directory.", - }) - f.StringVar(&StringVar{ Name: "dev-root-token-id", Target: &c.flagDevRootTokenID, @@ -1045,7 +1024,7 @@ func (c *ServerCommand) Run(args []string) int { } // Automatically enable dev mode if other dev flags are provided. - if c.flagDevConsul || c.flagDevHA || c.flagDevTransactional || c.flagDevLeasedKV || c.flagDevThreeNode || c.flagDevFourCluster || c.flagDevAutoSeal || c.flagDevKVV1 || c.flagDevTLS { + if c.flagDevConsul || c.flagDevHA || c.flagDevTransactional || c.flagDevLeasedKV || c.flagDevThreeNode || c.flagDevFourCluster || c.flagDevAutoSeal || c.flagDevKVV1 { c.flagDev = true } @@ -1081,7 +1060,6 @@ func (c *ServerCommand) Run(args []string) int { // Load the configuration var config *server.Config var err error - var certDir string if c.flagDev { var devStorageType string switch { @@ -1096,59 +1074,11 @@ func (c *ServerCommand) Run(args []string) int { default: devStorageType = "inmem" } - - if c.flagDevTLS { - if c.flagDevTLSCertDir != "" { - _, err := os.Stat(c.flagDevTLSCertDir) - if err != nil { - c.UI.Error(err.Error()) - return 1 - } - - certDir = c.flagDevTLSCertDir - } else { - certDir, err = os.MkdirTemp("", "vault-tls") - if err != nil { - c.UI.Error(err.Error()) - return 1 - } - } - config, err = server.DevTLSConfig(devStorageType, certDir) - - defer func() { - err := os.Remove(fmt.Sprintf("%s/%s", certDir, server.VaultDevCAFilename)) - if err != nil { - c.UI.Error(err.Error()) - } - - err = os.Remove(fmt.Sprintf("%s/%s", certDir, server.VaultDevCertFilename)) - if err != nil { - c.UI.Error(err.Error()) - } - - err = os.Remove(fmt.Sprintf("%s/%s", certDir, server.VaultDevKeyFilename)) - if err != nil { - c.UI.Error(err.Error()) - } - - // Only delete temp directories we made. - if c.flagDevTLSCertDir == "" { - err = os.Remove(certDir) - if err != nil { - c.UI.Error(err.Error()) - } - } - }() - - } else { - config, err = server.DevConfig(devStorageType) - } - + config, err = server.DevConfig(devStorageType) if err != nil { c.UI.Error(err.Error()) return 1 } - if c.flagDevListenAddr != "" { config.Listeners[0].Address = c.flagDevListenAddr } @@ -1398,24 +1328,6 @@ func (c *ServerCommand) Run(args []string) int { // Apply any enterprise configuration onto the coreConfig. adjustCoreConfigForEnt(config, &coreConfig) - if !c.flagDev && os.Getenv(disableStorageTypeCheckEnv) == "" { - inMemStorageTypes := []string{ - "inmem", "inmem_ha", "inmem_transactional", "inmem_transactional_ha", - } - - if strutil.StrListContains(inMemStorageTypes, coreConfig.StorageType) { - c.UI.Warn("") - c.UI.Warn(wrapAtLength(fmt.Sprintf("WARNING: storage configured to use %q which should NOT be used in production", coreConfig.StorageType))) - c.UI.Warn("") - } else { - err = checkStorageTypeForEnt(&coreConfig) - if err != nil { - c.UI.Error(fmt.Sprintf("Invalid storage type: %s", err)) - return 1 - } - } - } - // Initialize the core core, newCoreError := vault.NewCore(&coreConfig) if newCoreError != nil { @@ -1563,7 +1475,7 @@ func (c *ServerCommand) Run(args []string) int { } // If we're in Dev mode, then initialize the core - err = initDevCore(c, &coreConfig, config, core, certDir) + err = initDevCore(c, &coreConfig, config, core) if err != nil { c.UI.Error(err.Error()) return 1 @@ -2153,8 +2065,7 @@ func (c *ServerCommand) addPlugin(path, token string, core *vault.Core) error { // detectRedirect is used to attempt redirect address detection func (c *ServerCommand) detectRedirect(detect physical.RedirectDetect, - config *server.Config, -) (string, error) { + config *server.Config) (string, error) { // Get the hostname host, err := detect.DetectHostAddr() if err != nil { @@ -2510,11 +2421,7 @@ func determineRedirectAddr(c *ServerCommand, coreConfig *vault.CoreConfig, confi } } if coreConfig.RedirectAddr == "" && c.flagDev { - protocol := "http" - if c.flagDevTLS { - protocol = "https" - } - coreConfig.RedirectAddr = fmt.Sprintf("%s://%s", protocol, config.Listeners[0].Address) + coreConfig.RedirectAddr = fmt.Sprintf("http://%s", config.Listeners[0].Address) } return retErr } @@ -2603,8 +2510,7 @@ func runUnseal(c *ServerCommand, core *vault.Core, ctx context.Context) { } func createCoreConfig(c *ServerCommand, config *server.Config, backend physical.Backend, configSR sr.ServiceRegistration, barrierSeal, unwrapSeal vault.Seal, - metricsHelper *metricsutil.MetricsHelper, metricSink *metricsutil.ClusterMetricSink, secureRandomReader io.Reader, -) vault.CoreConfig { + metricsHelper *metricsutil.MetricsHelper, metricSink *metricsutil.ClusterMetricSink, secureRandomReader io.Reader) vault.CoreConfig { coreConfig := &vault.CoreConfig{ RawConfig: config, Physical: backend, @@ -2676,7 +2582,7 @@ func runListeners(c *ServerCommand, coreConfig *vault.CoreConfig, config *server return nil } -func initDevCore(c *ServerCommand, coreConfig *vault.CoreConfig, config *server.Config, core *vault.Core, certDir string) error { +func initDevCore(c *ServerCommand, coreConfig *vault.CoreConfig, config *server.Config, core *vault.Core) error { if c.flagDev && !c.flagDevSkipInit { init, err := c.enableDev(core, coreConfig) @@ -2727,15 +2633,10 @@ func initDevCore(c *ServerCommand, coreConfig *vault.CoreConfig, config *server. "token is already authenticated to the CLI, so you can immediately " + "begin using Vault.")) c.UI.Warn("") - c.UI.Warn("You may need to set the following environment variables:") + c.UI.Warn("You may need to set the following environment variable:") c.UI.Warn("") - protocol := "http://" - if c.flagDevTLS { - protocol = "https://" - } - - endpointURL := protocol + config.Listeners[0].Address + endpointURL := "http://" + config.Listeners[0].Address if runtime.GOOS == "windows" { c.UI.Warn("PowerShell:") c.UI.Warn(fmt.Sprintf(" $env:VAULT_ADDR=\"%s\"", endpointURL)) @@ -2745,18 +2646,6 @@ func initDevCore(c *ServerCommand, coreConfig *vault.CoreConfig, config *server. c.UI.Warn(fmt.Sprintf(" $ export VAULT_ADDR='%s'", endpointURL)) } - if c.flagDevTLS { - if runtime.GOOS == "windows" { - c.UI.Warn("PowerShell:") - c.UI.Warn(fmt.Sprintf(" $env:VAULT_CACERT=\"%s/vault-ca.pem\"", certDir)) - c.UI.Warn("cmd.exe:") - c.UI.Warn(fmt.Sprintf(" set VAULT_CACERT=%s/vault-ca.pem", certDir)) - } else { - c.UI.Warn(fmt.Sprintf(" $ export VAULT_CACERT='%s/vault-ca.pem'", certDir)) - } - c.UI.Warn("") - } - // Unseal key is not returned if stored shares is supported if len(init.SecretShares) > 0 { c.UI.Warn("") diff --git a/command/server/config.go b/command/server/config.go index 5d985db69d08d..a3526e16e8f23 100644 --- a/command/server/config.go +++ b/command/server/config.go @@ -22,12 +22,6 @@ import ( "github.com/hashicorp/vault/sdk/helper/consts" ) -const ( - VaultDevCAFilename = "vault-ca.pem" - VaultDevCertFilename = "vault-cert.pem" - VaultDevKeyFilename = "vault-key.pem" -) - var entConfigValidate = func(_ *Config, _ string) []configutil.ConfigError { return nil } @@ -157,62 +151,6 @@ ui = true return parsed, nil } -// DevTLSConfig is a Config that is used for dev tls mode of Vault. -func DevTLSConfig(storageType, certDir string) (*Config, error) { - ca, err := GenerateCA() - if err != nil { - return nil, err - } - - cert, key, err := GenerateCert(ca.Template, ca.Signer) - if err != nil { - return nil, err - } - - if err := os.WriteFile(fmt.Sprintf("%s/%s", certDir, VaultDevCAFilename), []byte(ca.PEM), 0o444); err != nil { - return nil, err - } - - if err := os.WriteFile(fmt.Sprintf("%s/%s", certDir, VaultDevCertFilename), []byte(cert), 0o400); err != nil { - return nil, err - } - - if err := os.WriteFile(fmt.Sprintf("%s/%s", certDir, VaultDevKeyFilename), []byte(key), 0o400); err != nil { - return nil, err - } - - hclStr := ` -disable_mlock = true - -listener "tcp" { - address = "[::]:8200" - tls_cert_file = "%s/vault-cert.pem" - tls_key_file = "%s/vault-key.pem" - proxy_protocol_behavior = "allow_authorized" - proxy_protocol_authorized_addrs = "[::]:8200" -} - -telemetry { - prometheus_retention_time = "24h" - disable_hostname = true -} -enable_raw_endpoint = true - -storage "%s" { -} - -ui = true -` - - hclStr = fmt.Sprintf(hclStr, certDir, certDir, storageType) - parsed, err := ParseConfig(hclStr, "") - if err != nil { - return nil, err - } - - return parsed, nil -} - // Storage is the underlying storage configuration for the server. type Storage struct { Type string @@ -864,25 +802,11 @@ func parseHAStorage(result *Config, list *ast.ObjectList, name string) error { key = item.Keys[0].Token.Value().(string) } - var config map[string]interface{} - if err := hcl.DecodeObject(&config, item.Val); err != nil { + var m map[string]string + if err := hcl.DecodeObject(&m, item.Val); err != nil { return multierror.Prefix(err, fmt.Sprintf("%s.%s:", name, key)) } - m := make(map[string]string) - for key, val := range config { - valStr, ok := val.(string) - if ok { - m[key] = valStr - continue - } - valBytes, err := json.Marshal(val) - if err != nil { - return err - } - m[key] = string(valBytes) - } - // Pull out the redirect address since it's common to all backends var redirectAddr string if v, ok := m["redirect_addr"]; ok { diff --git a/command/server/config_test.go b/command/server/config_test.go index e8e80cc99b3d4..d246087032bd2 100644 --- a/command/server/config_test.go +++ b/command/server/config_test.go @@ -48,10 +48,6 @@ func TestParseSeals(t *testing.T) { testParseSeals(t) } -func TestParseStorage(t *testing.T) { - testParseStorageTemplate(t) -} - func TestUnknownFieldValidation(t *testing.T) { testUnknownFieldValidation(t) } diff --git a/command/server/config_test_helpers.go b/command/server/config_test_helpers.go index c459198263fae..4cde9b115668b 100644 --- a/command/server/config_test_helpers.go +++ b/command/server/config_test_helpers.go @@ -900,49 +900,6 @@ EOF } } -func testParseStorageTemplate(t *testing.T) { - config, err := ParseConfig(` -storage "consul" { - - disable_registration = false - path = "tmp/" - -} -ha_storage "consul" { - tls_skip_verify = true - scheme = "http" - max_parallel = 128 -} - -`, "") - if err != nil { - t.Fatal(err) - } - - expected := &Config{ - Storage: &Storage{ - Type: "consul", - Config: map[string]string{ - "disable_registration": "false", - "path": "tmp/", - }, - }, - HAStorage: &Storage{ - Type: "consul", - Config: map[string]string{ - "tls_skip_verify": "true", - "scheme": "http", - "max_parallel": "128", - }, - }, - SharedConfig: &configutil.SharedConfig{}, - } - config.Prune() - if diff := deep.Equal(config, expected); diff != nil { - t.Fatal(diff) - } -} - func testParseSeals(t *testing.T) { config, err := LoadConfigFile("./test-fixtures/config_seals.hcl") if err != nil { @@ -1056,7 +1013,6 @@ func testLoadConfigFileLeaseMetrics(t *testing.T) { Config: map[string]string{ "bar": "baz", }, - DisableClustering: true, }, diff --git a/command/server/tls_util.go b/command/server/tls_util.go deleted file mode 100644 index d327006332511..0000000000000 --- a/command/server/tls_util.go +++ /dev/null @@ -1,162 +0,0 @@ -package server - -import ( - "bytes" - "crypto" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/x509" - "crypto/x509/pkix" - "encoding/pem" - "fmt" - "math/big" - "net" - "os" - "time" - - "github.com/hashicorp/vault/sdk/helper/certutil" -) - -type CaCert struct { - PEM string - Template *x509.Certificate - Signer crypto.Signer -} - -// GenerateCert creates a new leaf cert from provided CA template and signer -func GenerateCert(caCertTemplate *x509.Certificate, caSigner crypto.Signer) (string, string, error) { - // Create the private key - signer, keyPEM, err := privateKey() - if err != nil { - return "", "", fmt.Errorf("error generating private key for server certificate: %v", err) - } - - // The serial number for the cert - sn, err := serialNumber() - if err != nil { - return "", "", fmt.Errorf("error generating serial number: %v", err) - } - - signerKeyId, err := certutil.GetSubjKeyID(signer) - if err != nil { - return "", "", fmt.Errorf("error getting subject key id from key: %v", err) - } - - hostname, err := os.Hostname() - if err != nil { - return "", "", fmt.Errorf("error getting hostname: %v", err) - } - - if hostname == "" { - hostname = "localhost" - } - - // Create the leaf cert - template := x509.Certificate{ - SerialNumber: sn, - Subject: pkix.Name{CommonName: hostname}, - KeyUsage: x509.KeyUsageDigitalSignature, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}, - NotAfter: time.Now().Add(365 * 24 * time.Hour), - NotBefore: time.Now().Add(-1 * time.Minute), - IPAddresses: []net.IP{net.ParseIP("127.0.0.1")}, - DNSNames: []string{"localhost", "localhost4", "localhost6", "localhost.localdomain"}, - AuthorityKeyId: caCertTemplate.AuthorityKeyId, - SubjectKeyId: signerKeyId, - } - - bs, err := x509.CreateCertificate( - rand.Reader, &template, caCertTemplate, signer.Public(), caSigner) - if err != nil { - return "", "", fmt.Errorf("error creating server certificate: %v", err) - } - var buf bytes.Buffer - err = pem.Encode(&buf, &pem.Block{Type: "CERTIFICATE", Bytes: bs}) - if err != nil { - return "", "", fmt.Errorf("error encoding server certificate: %v", err) - } - - return buf.String(), keyPEM, nil -} - -// GenerateCA generates a new self-signed CA cert and returns a -// CaCert struct containing the PEM encoded cert, -// X509 Certificate Template, and crypto.Signer -func GenerateCA() (*CaCert, error) { - // Create the private key we'll use for this CA cert. - signer, _, err := privateKey() - if err != nil { - return nil, fmt.Errorf("error generating private key for CA: %v", err) - } - - signerKeyId, err := certutil.GetSubjKeyID(signer) - if err != nil { - return nil, fmt.Errorf("error getting subject key id from key: %v", err) - } - - // The serial number for the cert - sn, err := serialNumber() - if err != nil { - return nil, fmt.Errorf("error generating serial number: %v", err) - } - - // Create the CA cert - template := x509.Certificate{ - SerialNumber: sn, - Subject: pkix.Name{CommonName: "Vault Dev CA"}, - BasicConstraintsValid: true, - KeyUsage: x509.KeyUsageCertSign, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}, - IsCA: true, - NotAfter: time.Now().Add(10 * 365 * 24 * time.Hour), - NotBefore: time.Now().Add(-1 * time.Minute), - AuthorityKeyId: signerKeyId, - SubjectKeyId: signerKeyId, - IPAddresses: []net.IP{net.ParseIP("127.0.0.1")}, - } - - bs, err := x509.CreateCertificate( - rand.Reader, &template, &template, signer.Public(), signer) - if err != nil { - return nil, fmt.Errorf("error creating CA certificate: %v", err) - } - - var buf bytes.Buffer - err = pem.Encode(&buf, &pem.Block{Type: "CERTIFICATE", Bytes: bs}) - if err != nil { - return nil, fmt.Errorf("error encoding CA certificate: %v", err) - } - return &CaCert{ - PEM: buf.String(), - Template: &template, - Signer: signer, - }, nil -} - -// privateKey returns a new ECDSA-based private key. Both a crypto.Signer -// and the key in PEM format are returned. -func privateKey() (crypto.Signer, string, error) { - pk, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - if err != nil { - return nil, "", err - } - - bs, err := x509.MarshalECPrivateKey(pk) - if err != nil { - return nil, "", err - } - - var buf bytes.Buffer - err = pem.Encode(&buf, &pem.Block{Type: "EC PRIVATE KEY", Bytes: bs}) - if err != nil { - return nil, "", err - } - - return pk, buf.String(), nil -} - -// serialNumber generates a new random serial number. -func serialNumber() (*big.Int, error) { - return rand.Int(rand.Reader, (&big.Int{}).Exp(big.NewInt(2), big.NewInt(159), nil)) -} diff --git a/command/server_test.go b/command/server_test.go index e19b499e255ff..d836b11047699 100644 --- a/command/server_test.go +++ b/command/server_test.go @@ -121,7 +121,7 @@ func TestServer_ReloadListener(t *testing.T) { inBytes, _ = ioutil.ReadFile(wd + "reload_foo.key") ioutil.WriteFile(td+"/reload_key.pem", inBytes, 0o777) - relhcl := strings.ReplaceAll(reloadHCL, "TMPDIR", td) + relhcl := strings.Replace(reloadHCL, "TMPDIR", td, -1) ioutil.WriteFile(td+"/reload.hcl", []byte(relhcl), 0o777) inBytes, _ = ioutil.ReadFile(wd + "reload_ca.pem") @@ -172,7 +172,7 @@ func TestServer_ReloadListener(t *testing.T) { t.Fatalf("certificate name didn't check out: %s", err) } - relhcl = strings.ReplaceAll(reloadHCL, "TMPDIR", td) + relhcl = strings.Replace(reloadHCL, "TMPDIR", td, -1) inBytes, _ = ioutil.ReadFile(wd + "reload_bar.pem") ioutil.WriteFile(td+"/reload_cert.pem", inBytes, 0o777) inBytes, _ = ioutil.ReadFile(wd + "reload_bar.key") diff --git a/command/server_util.go b/command/server_util.go index 1959f17662569..4054693be1e4d 100644 --- a/command/server_util.go +++ b/command/server_util.go @@ -5,10 +5,7 @@ import ( "github.com/hashicorp/vault/vault" ) -var ( - adjustCoreConfigForEnt = adjustCoreConfigForEntNoop - checkStorageTypeForEnt = checkStorageTypeForEntNoop -) +var adjustCoreConfigForEnt = adjustCoreConfigForEntNoop func adjustCoreConfigForEntNoop(config *server.Config, coreConfig *vault.CoreConfig) { } @@ -18,7 +15,3 @@ var getFIPSInfoKey = getFIPSInfoKeyNoop func getFIPSInfoKeyNoop() string { return "" } - -func checkStorageTypeForEntNoop(coreConfig *vault.CoreConfig) error { - return nil -} diff --git a/command/token/helper_external.go b/command/token/helper_external.go index 917d44573e1f0..102bc1cff4058 100644 --- a/command/token/helper_external.go +++ b/command/token/helper_external.go @@ -103,7 +103,7 @@ func (h *ExternalTokenHelper) Path() string { } func (h *ExternalTokenHelper) cmd(op string) (*exec.Cmd, error) { - script := strings.ReplaceAll(h.BinaryPath, "\\", "\\\\") + " " + op + script := strings.Replace(h.BinaryPath, "\\", "\\\\", -1) + " " + op cmd, err := ExecScript(script) if err != nil { return nil, err diff --git a/go.mod b/go.mod index aeca61c25dd3f..d92dd5e344135 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/hashicorp/vault -go 1.18 +go 1.17 replace github.com/hashicorp/vault/api => ./api @@ -15,7 +15,7 @@ replace github.com/hashicorp/vault/sdk => ./sdk replace go.etcd.io/etcd/client/pkg/v3 v3.5.0 => go.etcd.io/etcd/client/pkg/v3 v3.0.0-20210928084031-3df272774672 require ( - cloud.google.com/go/monitoring v1.2.0 + cloud.google.com/go v0.65.0 cloud.google.com/go/spanner v1.5.1 cloud.google.com/go/storage v1.10.0 github.com/Azure/azure-storage-blob-go v0.14.0 @@ -28,18 +28,17 @@ require ( github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190620160927-9418d7b0cd0f github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5 github.com/apple/foundationdb/bindings/go v0.0.0-20190411004307-cd5c9d91fad2 - github.com/armon/go-metrics v0.4.0 + github.com/armon/go-metrics v0.3.10 github.com/armon/go-radix v1.0.0 github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a - github.com/aws/aws-sdk-go v1.43.4 - github.com/axiomhq/hyperloglog v0.0.0-20220105174342-98591331716a + github.com/aws/aws-sdk-go v1.37.19 github.com/cenkalti/backoff/v3 v3.2.2 github.com/chrismalek/oktasdk-go v0.0.0-20181212195951-3430665dfaa0 github.com/client9/misspell v0.3.4 github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf github.com/denisenkom/go-mssqldb v0.12.0 - github.com/docker/docker v20.10.17+incompatible + github.com/docker/docker v20.10.10+incompatible github.com/docker/go-connections v0.4.0 github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74 github.com/dustin/go-humanize v1.0.0 @@ -49,32 +48,32 @@ require ( github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 github.com/go-errors/errors v1.4.1 github.com/go-ldap/ldap/v3 v3.4.1 - github.com/go-sql-driver/mysql v1.6.0 + github.com/go-sql-driver/mysql v1.5.0 github.com/go-test/deep v1.0.8 github.com/gocql/gocql v1.0.0 github.com/golang-jwt/jwt/v4 v4.3.0 github.com/golang/protobuf v1.5.2 - github.com/google/go-cmp v0.5.8 + github.com/google/go-cmp v0.5.6 github.com/google/go-github v17.0.0+incompatible github.com/google/go-metrics-stackdriver v0.2.0 - github.com/google/tink/go v1.6.1 - github.com/hashicorp/cap v0.2.1-0.20220727210936-60cd1534e220 + github.com/google/tink/go v1.4.0 + github.com/hashicorp/cap v0.2.1-0.20220502204956-9a9f4a9d6e61 github.com/hashicorp/consul-template v0.29.1 github.com/hashicorp/consul/api v1.12.0 github.com/hashicorp/errwrap v1.1.0 github.com/hashicorp/go-cleanhttp v0.5.2 github.com/hashicorp/go-discover v0.0.0-20210818145131-c573d69da192 - github.com/hashicorp/go-gcp-common v0.8.0 - github.com/hashicorp/go-hclog v1.2.0 + github.com/hashicorp/go-gcp-common v0.7.1-0.20220519220342-94aabf4c4c87 + github.com/hashicorp/go-hclog v1.1.0 github.com/hashicorp/go-kms-wrapping v0.7.0 - github.com/hashicorp/go-memdb v1.3.3 + github.com/hashicorp/go-memdb v1.3.2 github.com/hashicorp/go-msgpack v1.1.5 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-plugin v1.4.4 github.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a - github.com/hashicorp/go-retryablehttp v0.7.1 + github.com/hashicorp/go-retryablehttp v0.7.0 github.com/hashicorp/go-rootcerts v1.0.2 - github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 + github.com/hashicorp/go-secure-stdlib/awsutil v0.1.5 github.com/hashicorp/go-secure-stdlib/base62 v0.1.2 github.com/hashicorp/go-secure-stdlib/gatedwriter v0.1.1 github.com/hashicorp/go-secure-stdlib/kv-builder v0.1.2 @@ -86,34 +85,34 @@ require ( github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1 github.com/hashicorp/go-sockaddr v1.0.2 github.com/hashicorp/go-syslog v1.0.0 - github.com/hashicorp/go-uuid v1.0.3 - github.com/hashicorp/go-version v1.6.0 + github.com/hashicorp/go-uuid v1.0.2 + github.com/hashicorp/go-version v1.4.0 github.com/hashicorp/golang-lru v0.5.4 github.com/hashicorp/hcl v1.0.1-vault-3 github.com/hashicorp/nomad/api v0.0.0-20220407202126-2eba643965c4 - github.com/hashicorp/raft v1.3.10 - github.com/hashicorp/raft-autopilot v0.1.6 + github.com/hashicorp/raft v1.3.9 + github.com/hashicorp/raft-autopilot v0.1.3 github.com/hashicorp/raft-boltdb/v2 v2.0.0-20210421194847-a7e34179d62c github.com/hashicorp/raft-snapshot v1.0.4 github.com/hashicorp/vault-plugin-auth-alicloud v0.12.0 github.com/hashicorp/vault-plugin-auth-azure v0.11.0 github.com/hashicorp/vault-plugin-auth-centrify v0.12.0 github.com/hashicorp/vault-plugin-auth-cf v0.12.0 - github.com/hashicorp/vault-plugin-auth-gcp v0.13.2-0.20220722185016-9e4fddb995e5 - github.com/hashicorp/vault-plugin-auth-jwt v0.13.2-0.20220728183411-0edf6ecc0b37 + github.com/hashicorp/vault-plugin-auth-gcp v0.13.2 + github.com/hashicorp/vault-plugin-auth-jwt v0.13.0 github.com/hashicorp/vault-plugin-auth-kerberos v0.7.2 github.com/hashicorp/vault-plugin-auth-kubernetes v0.13.0 github.com/hashicorp/vault-plugin-auth-oci v0.11.0 github.com/hashicorp/vault-plugin-database-couchbase v0.7.0 - github.com/hashicorp/vault-plugin-database-elasticsearch v0.11.0 + github.com/hashicorp/vault-plugin-database-elasticsearch v0.11.1 github.com/hashicorp/vault-plugin-database-mongodbatlas v0.7.0 github.com/hashicorp/vault-plugin-database-snowflake v0.5.1 github.com/hashicorp/vault-plugin-mock v0.16.1 github.com/hashicorp/vault-plugin-secrets-ad v0.13.1 github.com/hashicorp/vault-plugin-secrets-alicloud v0.12.0 github.com/hashicorp/vault-plugin-secrets-azure v0.13.0 - github.com/hashicorp/vault-plugin-secrets-gcp v0.6.6-0.20220617175110-38223d8fabc9 - github.com/hashicorp/vault-plugin-secrets-gcpkms v0.5.7-0.20220617175201-b16d1500db6e + github.com/hashicorp/vault-plugin-secrets-gcp v0.13.1 + github.com/hashicorp/vault-plugin-secrets-gcpkms v0.12.0 github.com/hashicorp/vault-plugin-secrets-kubernetes v0.1.1 github.com/hashicorp/vault-plugin-secrets-kv v0.12.1 github.com/hashicorp/vault-plugin-secrets-mongodbatlas v0.7.0 @@ -123,7 +122,7 @@ require ( github.com/hashicorp/vault/api v1.7.2 github.com/hashicorp/vault/api/auth/approle v0.1.0 github.com/hashicorp/vault/api/auth/userpass v0.1.0 - github.com/hashicorp/vault/sdk v0.5.3 + github.com/hashicorp/vault/sdk v0.5.3-0.20220803145622-430daff0f040 github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab github.com/jackc/pgx/v4 v4.15.0 github.com/jcmturner/gokrb5/v8 v8.4.2 @@ -143,6 +142,7 @@ require ( github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/go-testing-interface v1.14.1 github.com/mitchellh/go-wordwrap v1.0.0 + github.com/mitchellh/gox v1.0.1 github.com/mitchellh/mapstructure v1.5.0 github.com/mitchellh/reflectwalk v1.0.2 github.com/natefinch/atomic v0.0.0-20150920032501-a62ce929ffcc @@ -165,8 +165,8 @@ require ( github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da github.com/sasha-s/go-deadlock v0.2.0 github.com/sethvargo/go-limiter v0.7.1 - github.com/shirou/gopsutil/v3 v3.22.6 - github.com/stretchr/testify v1.7.5 + github.com/shirou/gopsutil v3.21.5+incompatible + github.com/stretchr/testify v1.7.1 go.etcd.io/bbolt v1.3.6 go.etcd.io/etcd/client/pkg/v3 v3.5.0 go.etcd.io/etcd/client/v2 v2.305.0 @@ -179,15 +179,15 @@ require ( go.uber.org/atomic v1.9.0 go.uber.org/goleak v1.1.12 golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d - golang.org/x/net v0.0.0-20220607020251-c690dde0001d - golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401 - golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a + golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd + golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 + golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 golang.org/x/tools v0.1.5 - google.golang.org/api v0.83.0 - google.golang.org/grpc v1.47.0 + google.golang.org/api v0.30.0 + google.golang.org/grpc v1.44.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 - google.golang.org/protobuf v1.28.0 + google.golang.org/protobuf v1.27.1 gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce gopkg.in/ory-am/dockertest.v3 v3.3.4 gopkg.in/square/go-jose.v2 v2.6.0 @@ -197,10 +197,6 @@ require ( ) require ( - cloud.google.com/go v0.100.2 // indirect - cloud.google.com/go/compute v1.6.1 // indirect - cloud.google.com/go/iam v0.1.1 // indirect - cloud.google.com/go/kms v1.4.0 // indirect code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f // indirect github.com/Azure/azure-pipeline-go v0.2.3 // indirect github.com/Azure/azure-sdk-for-go v61.4.0+incompatible // indirect @@ -223,6 +219,7 @@ require ( github.com/Microsoft/go-winio v0.5.1 // indirect github.com/Microsoft/hcsshim v0.9.0 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect + github.com/StackExchange/wmi v1.2.1 // indirect github.com/andybalholm/brotli v1.0.4 // indirect github.com/apache/arrow/go/arrow v0.0.0-20210818145353-234c94e4ce64 // indirect github.com/aws/aws-sdk-go-v2 v1.8.0 // indirect @@ -243,8 +240,8 @@ require ( github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible // indirect github.com/circonus-labs/circonusllhist v0.1.3 // indirect github.com/cloudfoundry-community/go-cfclient v0.0.0-20210823134051-721f0e559306 // indirect - github.com/containerd/cgroups v1.0.3 // indirect - github.com/containerd/containerd v1.5.13 // indirect + github.com/containerd/cgroups v1.0.1 // indirect + github.com/containerd/containerd v1.5.7 // indirect github.com/containerd/continuity v0.2.1 // indirect github.com/coreos/go-oidc v2.2.1+incompatible // indirect github.com/coreos/go-oidc/v3 v3.1.0 // indirect @@ -252,9 +249,8 @@ require ( github.com/coreos/go-systemd/v22 v22.3.2 // indirect github.com/couchbase/gocb/v2 v2.3.3 // indirect github.com/couchbase/gocbcore/v10 v10.0.4 // indirect - github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba // indirect - github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc // indirect github.com/digitalocean/godo v1.7.5 // indirect github.com/dimchansky/utfbom v1.1.1 // indirect github.com/docker/cli v20.10.9+incompatible // indirect @@ -269,7 +265,7 @@ require ( github.com/go-asn1-ber/asn1-ber v1.5.1 // indirect github.com/go-ldap/ldif v0.0.0-20200320164324-fd88d9b715b3 // indirect github.com/go-logr/logr v1.2.0 // indirect - github.com/go-ole/go-ole v1.2.6 // indirect + github.com/go-ole/go-ole v1.2.5 // indirect github.com/go-stack/stack v1.8.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect @@ -282,7 +278,7 @@ require ( github.com/google/gofuzz v1.1.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect - github.com/googleapis/gax-go/v2 v2.4.0 // indirect + github.com/googleapis/gax-go/v2 v2.0.5 // indirect github.com/googleapis/gnostic v0.5.5 // indirect github.com/gophercloud/gophercloud v0.1.0 // indirect github.com/gorilla/websocket v1.4.2 // indirect @@ -318,16 +314,17 @@ require ( github.com/jeffchao/backoff v0.0.0-20140404060208-9d7fd7aa17f2 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/jstemmer/go-junit-report v0.9.1 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect github.com/klauspost/compress v1.13.6 // indirect github.com/klauspost/pgzip v1.2.5 // indirect - github.com/lib/pq v1.10.6 // indirect + github.com/lib/pq v1.10.2 // indirect github.com/linode/linodego v0.7.1 // indirect - github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/mattn/go-ieproxy v0.0.1 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/miekg/dns v1.1.41 // indirect github.com/mitchellh/hashstructure v1.0.0 // indirect + github.com/mitchellh/iochan v1.0.0 // indirect github.com/mitchellh/pointerstructure v1.2.0 // indirect github.com/moby/sys/mount v0.2.0 // indirect github.com/moby/sys/mountinfo v0.4.1 // indirect @@ -338,7 +335,7 @@ require ( github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 // indirect github.com/nwaples/rardecode v1.1.2 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.0.2 // indirect + github.com/opencontainers/image-spec v1.0.1 // indirect github.com/opencontainers/runc v1.0.2 // indirect github.com/openlyinc/pointy v1.1.2 // indirect github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c // indirect @@ -346,21 +343,20 @@ require ( github.com/pierrec/lz4 v2.6.1+incompatible // indirect github.com/pierrec/lz4/v4 v4.1.8 // indirect github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pquerna/cachecontrol v0.1.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/procfs v0.6.0 // indirect github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 // indirect - github.com/rogpeppe/go-internal v1.8.1 // indirect + github.com/rogpeppe/go-internal v1.6.2 // indirect github.com/sirupsen/logrus v1.8.1 // indirect github.com/snowflakedb/gosnowflake v1.6.3 // indirect github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/objx v0.4.0 // indirect + github.com/stretchr/objx v0.2.0 // indirect github.com/tencentcloud/tencentcloud-sdk-go v1.0.162 // indirect - github.com/tklauser/go-sysconf v0.3.10 // indirect - github.com/tklauser/numcpus v0.4.0 // indirect + github.com/tklauser/go-sysconf v0.3.9 // indirect + github.com/tklauser/numcpus v0.3.0 // indirect github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c // indirect github.com/ulikunitz/xz v0.5.10 // indirect github.com/vmware/govmomi v0.18.0 // indirect @@ -373,25 +369,25 @@ require ( github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9 // indirect - github.com/yusufpapurcu/wmi v1.2.2 // indirect go.etcd.io/etcd/api/v3 v3.5.0 // indirect go.opencensus.io v0.23.0 // indirect go.opentelemetry.io/otel/metric v0.20.0 // indirect - go.uber.org/multierr v1.7.0 // indirect + go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.19.1 // indirect + golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect golang.org/x/mod v0.4.2 // indirect - golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/text v0.3.7 // indirect - golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect - golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect + golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20220602131408-e326c6e8e9c8 // indirect + google.golang.org/genproto v0.0.0-20220207185906-7721543eae58 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.62.0 // indirect gopkg.in/jcmturner/goidentity.v3 v3.0.0 // indirect gopkg.in/resty.v1 v1.12.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect k8s.io/api v0.22.2 // indirect k8s.io/apimachinery v0.22.2 // indirect k8s.io/client-go v0.22.2 // indirect diff --git a/go.sum b/go.sum index 6b8268bc44bed..1fa8cdf75cc24 100644 --- a/go.sum +++ b/go.sum @@ -15,23 +15,8 @@ cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bP cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0 h1:Dg9iHVQfrhq82rUNu9ZxUDrJLaxFUe/HlCVaLyRruq8= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= -cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= -cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y= -cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -39,21 +24,8 @@ cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUM cloud.google.com/go/bigquery v1.6.0/go.mod h1:hyFDG0qSGdHNz8Q6nDN8rYIkld0q/+5uBZaelxiDLfE= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= -cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= -cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= -cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= -cloud.google.com/go/compute v1.6.1 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc= -cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= -cloud.google.com/go/iam v0.1.1 h1:4CapQyNFjiksks1/x7jsvsygFPhihslYk5GptIrlX68= -cloud.google.com/go/iam v0.1.1/go.mod h1:CKqrcnI/suGpybEHxZ7BMehL0oA4LpdyJdUlTl9jVMw= -cloud.google.com/go/kms v1.4.0 h1:iElbfoE61VeLhnZcGOltqL8HIly8Nhbe5t6JlH9GXjo= -cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= -cloud.google.com/go/monitoring v1.2.0 h1:fEvQITrhVcPM6vuDQcgPMbU5kZFeQFwZmE7v6+S8BPo= -cloud.google.com/go/monitoring v1.2.0/go.mod h1:tE8I08OzjWmXLhCopnPaUDpfGOEJOonfWXGR9E9SsFo= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -69,6 +41,7 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f h1:UrKzEwTgeiff9vxdrfdqxibzpWjxLnuXDI5m6z3GJAk= code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f/go.mod h1:sk5LnIjB/nIEU7yP5sDQExVm62wu0pBh3yrElngUisI= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +git.apache.org/thrift.git v0.12.0/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/Azure/azure-pipeline-go v0.2.3 h1:7U9HBg1JFK3jHl5qmo4CTZKFTVgMwdFHMVtCdfBE21U= github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k= github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= @@ -200,6 +173,10 @@ github.com/SAP/go-hdb v0.14.1/go.mod h1:7fdQLVC2lER3urZLjZCm0AuMQfApof92n3aylBPE github.com/Sectorbob/mlab-ns2 v0.0.0-20171030222938-d3aa0c295a8a h1:KFHLI4QGttB0i7M3qOkAo8Zn/GSsxwwCnInFqBaYtkM= github.com/Sectorbob/mlab-ns2 v0.0.0-20171030222938-d3aa0c295a8a/go.mod h1:D73UAuEPckrDorYZdtlCu2ySOLuPB5W4rhIkmmc/XbI= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= +github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af h1:DBNMBMuMiWYu0b+8KMJuWmfCkcxl09JwdlqwDZZ6U14= github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw= github.com/aerospike/aerospike-client-go/v5 v5.6.0 h1:tRxcUq0HY8fFPQEzF3EgrknF+w1xFO0YDfUb9Nm8yRI= @@ -210,6 +187,7 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= +github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190412020505-60e2075261b6/go.mod h1:T9M45xf79ahXVelWoOBmH0y4aC1t5kXO5BxwyakgIGA= github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190620160927-9418d7b0cd0f h1:oRD16bhpKNAanfcDDVU+J0NXqsgHIvGbbe/sy+r6Rs0= github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190620160927-9418d7b0cd0f/go.mod h1:myCDvQSzCW+wB1WAlocEru4wMGJxy+vlxHdhegi1CDQ= github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5 h1:nWDRPCyCltiTsANwC/n3QZH7Vww33Npq9MKqlwRzI/c= @@ -220,6 +198,7 @@ github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHG github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apache/arrow/go/arrow v0.0.0-20210818145353-234c94e4ce64 h1:ZsPrlYPY/v1PR7pGrmYD/rq5BFiSPalH8i9eEkSfnnI= github.com/apache/arrow/go/arrow v0.0.0-20210818145353-234c94e4ce64/go.mod h1:2qMFB56yOP3KzkB3PbYZ4AlUFg3a88F67TIx5lB/WwY= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apple/foundationdb/bindings/go v0.0.0-20190411004307-cd5c9d91fad2 h1:VoHKYIXEQU5LWoambPBOvYxyLqZYHuj+rj5DVnMUc3k= github.com/apple/foundationdb/bindings/go v0.0.0-20190411004307-cd5c9d91fad2/go.mod h1:OMVSB21p9+xQUIqlGizHPZfjK+SHws1ht+ZytVDoz9U= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -227,21 +206,21 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5 github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs= +github.com/armon/go-metrics v0.3.3/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-metrics v0.3.10 h1:FR+drcQStOe+32sYyJYyZ7FIdgoGGBnwLl+flodp8Uo= github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= -github.com/armon/go-metrics v0.4.0 h1:yCQqn7dwca4ITXb+CbubHmedzaQYHhNhrEXLYUeEe8Q= -github.com/armon/go-metrics v0.4.0/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +github.com/aws/aws-sdk-go v1.25.39/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.25.41/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= -github.com/aws/aws-sdk-go v1.36.29/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go v1.43.4 h1:EtsGbtOB+1548T6Nb62XCOofgXtMHwf+WZh5gQc3xTY= -github.com/aws/aws-sdk-go v1.43.4/go.mod h1:OGr6lGMAKGlG9CVrYnWYDKIyb829c6EVBRjxqjmPepc= +github.com/aws/aws-sdk-go v1.37.19 h1:/xKHoSsYfH9qe16pJAHIjqTVpMM2DRSsEt8Ok1bzYiw= +github.com/aws/aws-sdk-go v1.37.19/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go-v2 v1.8.0 h1:HcN6yDnHV9S7D69E7To0aUppJhiJNEzQSNcUxc7r3qo= github.com/aws/aws-sdk-go-v2 v1.8.0/go.mod h1:xEFuWz+3TYdlPRuo+CqATbeDWIWyaT5uAPwPaWtgse0= github.com/aws/aws-sdk-go-v2/config v1.6.0 h1:rtoCnNObhVm7me+v9sA2aY+NtHNZjjWWC3ifXVci+wE= @@ -268,8 +247,6 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.6.1 h1:1Pls85C5CFjhE3aH+h85/hyAk89kQ github.com/aws/aws-sdk-go-v2/service/sts v1.6.1/go.mod h1:hLZ/AnkIKHLuPGjEiyghNEdvJ2PP0MgOxcmv9EBJ4xs= github.com/aws/smithy-go v1.7.0 h1:+cLHMRrDZvQ4wk+KuQ9yH6eEg6KZEJ9RI2IkDqnygCg= github.com/aws/smithy-go v1.7.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= -github.com/axiomhq/hyperloglog v0.0.0-20220105174342-98591331716a h1:eqjiAL3qooftPm8b9C1GsSSRcmlw7iOva8vdBTmV2PY= -github.com/axiomhq/hyperloglog v0.0.0-20220105174342-98591331716a/go.mod h1:2stgcRjl6QmW+gU2h5E7BQXg4HU0gzxKWDuT5HviN9s= github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f h1:ZNv7On9kyUzm7fvRZumSyy/IUiSC7AzL0I1jKKtwooA= github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= @@ -303,11 +280,13 @@ github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QH github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/cenkalti/backoff/v3 v3.2.2 h1:cfUAAO3yvKMYKPrvhDuHSwQnhZNk/RMHKdZqKTxfm6M= github.com/cenkalti/backoff/v3 v3.2.2/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= +github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/centrify/cloud-golang-sdk v0.0.0-20210923165758-a8c48d049166 h1:jQ93fKqb/wRmK/KiHpa7Tk9rmHeKXhp4j+5Sg/tENiY= github.com/centrify/cloud-golang-sdk v0.0.0-20210923165758-a8c48d049166/go.mod h1:c/gmvyN8lq6lYtHvrqqoXrg2xyN65N0mBmbikxFWXNE= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -332,13 +311,11 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cloudfoundry-community/go-cfclient v0.0.0-20210823134051-721f0e559306 h1:k8q2Nsz7kNaUlysVCnWIFLMUSqiKXaGLdIf9P0GsX2Y= github.com/cloudfoundry-community/go-cfclient v0.0.0-20210823134051-721f0e559306/go.mod h1:0FdHblxw7g3M2PPICOw9i8YZOHP9dZTHbJUtoxL7Z/E= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= @@ -360,9 +337,8 @@ github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1 github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= +github.com/containerd/cgroups v1.0.1 h1:iJnMvco9XGvKUvNQkv88bE4uJXxRQH18efbKo9w5vHQ= github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU= -github.com/containerd/cgroups v1.0.3 h1:ADZftAkglvCiD44c77s5YmMqaP2pzVCFZvBmAlBdAP4= -github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8= github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= @@ -381,9 +357,8 @@ github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI= github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= +github.com/containerd/containerd v1.5.7 h1:rQyoYtj4KddB3bxG6SAqd4+08gePNyJjRqvOIfV3rkM= github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= -github.com/containerd/containerd v1.5.13 h1:XqvKw9i4P7/mFrC3TSM7yV5cwFZ9avXe6M3YANKnzEE= -github.com/containerd/containerd v1.5.13/go.mod h1:3AlCrzKROjIuP3JALsY14n8YtntaUDBu7vek+rPN5Vc= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= @@ -447,6 +422,7 @@ github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmeka github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk= github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-oidc/v3 v3.0.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo= github.com/coreos/go-oidc/v3 v3.1.0 h1:6avEvcdvTa1qYsOZ6I5PRkSYHzpTNWgKYmaJfaYbrRw= github.com/coreos/go-oidc/v3 v3.1.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -481,9 +457,8 @@ github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/denisenkom/go-mssqldb v0.12.0 h1:VtrkII767ttSPNRfFekePK3sctr+joXgO58stqQbtUA= github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU= github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= @@ -491,8 +466,6 @@ github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba h1:p6poVbjHDkK github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc h1:8WFBn63wegobsYAX0YjD+8suexZDga5CctH4CCTx2+8= -github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/digitalocean/godo v1.7.5 h1:JOQbAO6QT1GGjor0doT0mXefX2FgUDPOpYh2RaXA+ko= github.com/digitalocean/godo v1.7.5/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU= @@ -514,9 +487,8 @@ github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r github.com/docker/docker v1.4.2-0.20200319182547-c7ad2b866182/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.10+incompatible h1:GKkP0T7U4ks6X3lmmHKC2QDprnpRJor2Z5a8m62R9ZM= github.com/docker/docker v20.10.10+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.17+incompatible h1:JYCuMrWaVNophQTOrMMoSwudOVEfcegoZZrleKc1xwE= -github.com/docker/docker v20.10.17+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= @@ -524,6 +496,7 @@ github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6Uezg github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= @@ -537,27 +510,32 @@ github.com/duosecurity/duo_api_golang v0.0.0-20190308151101-6c680f768e74/go.mod github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v0.0.0-20190203023257-5858425f7550/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs= github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.5.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.11.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= @@ -618,8 +596,8 @@ github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab h1:xveKWz2iaueeTaUgdetzel+U7exyigDYBryyVfV/rZk= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= -github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= -github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= +github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= @@ -631,9 +609,8 @@ github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8 github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= -github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= @@ -677,6 +654,7 @@ github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= @@ -700,6 +678,7 @@ github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -707,7 +686,6 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -729,6 +707,7 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -751,10 +730,8 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= @@ -763,15 +740,14 @@ github.com/google/go-metrics-stackdriver v0.2.0/go.mod h1:KLcPyp3dWJAFD+yHisGlJS github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0 h1:pMen7vLs8nvgEYhywH3KDWJIJTeEr2ULsVWHWYHQyBs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -779,18 +755,11 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/google/tink/go v1.6.1 h1:t7JHqO8Ath2w2ig5vjwQYJzhGEZymedQc90lQXUBa4I= -github.com/google/tink/go v1.6.1/go.mod h1:IGW53kTgag+st5yPhKKwJ6u2l+SSp5/v9XF7spovjlY= +github.com/google/tink/go v1.4.0 h1:7Ihv6n6/0zPrm2GRAeeF408P9Y00HXC2J6tvUzgb2sg= +github.com/google/tink/go v1.4.0/go.mod h1:OdW+ACSIXwGiPOWJiRTdoKzStsnqo8ZOsTzchWLy2DY= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -798,13 +767,8 @@ github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= -github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= -github.com/googleapis/gax-go/v2 v2.4.0 h1:dS9eYAjhrE2RjmzYw2XAPvcXfmcQLtFEQWn0CR82awk= -github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= @@ -816,8 +780,11 @@ github.com/gophercloud/gophercloud v0.1.0 h1:P/nh25+rzXouhytV2pUHBb65fnds26Ghl8/ github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= @@ -833,18 +800,24 @@ github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:Fecb github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.6.2/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= -github.com/hashicorp/cap v0.2.1-0.20220727210936-60cd1534e220 h1:Vgv3jG0kicczshK+lOHWJ9OososZjnjSu1YslqofFYY= -github.com/hashicorp/cap v0.2.1-0.20220727210936-60cd1534e220/go.mod h1:zb3VvIFA0lM2lbmO69NjowV9dJzJnZS89TaM9blXPJA= +github.com/hashicorp/cap v0.0.0-20220502204956-9a9f4a9d6e61/go.mod h1:zb3VvIFA0lM2lbmO69NjowV9dJzJnZS89TaM9blXPJA= +github.com/hashicorp/cap v0.1.1/go.mod h1:VfBvK2ULRyqsuqAnjgZl7HJ7/CGMC7ro4H5eXiZuun8= +github.com/hashicorp/cap v0.2.1-0.20220502204956-9a9f4a9d6e61 h1:FIf15EEnoIOSXXy58zl89s88iz0jFhWEPMbIGyRoOvo= +github.com/hashicorp/cap v0.2.1-0.20220502204956-9a9f4a9d6e61/go.mod h1:zb3VvIFA0lM2lbmO69NjowV9dJzJnZS89TaM9blXPJA= github.com/hashicorp/consul-template v0.29.1 h1:icm/H7klHYlxpUoWqSmTIWaSLEfGqUJJBsZA/2JhTLU= github.com/hashicorp/consul-template v0.29.1/go.mod h1:QIohwBuXlKXtsmGGQdWrISlUy4E6LFg5tLZyrw4MyoU= +github.com/hashicorp/consul/api v1.4.0/go.mod h1:xc8u05kyMa3Wjr9eEAsIAo3dg8+LywT5E/Cl7cNS5nU= github.com/hashicorp/consul/api v1.12.0 h1:k3y1FYv6nuKyNTqj6w9gXOx5r5CfLj/k/euUeBXj1OY= github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.4.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM= +github.com/hashicorp/consul/sdk v0.4.1-0.20200910203702-bb2b5dd871ca/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPAvlcdx16zZ0fM= github.com/hashicorp/consul/sdk v0.8.0 h1:OJtKBtEjboEZvG6AOUdh4Z1Zbyu0WcxQ0qatRrZHTVU= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/cronexpr v1.1.1 h1:NJZDd87hGXjoZBdvyCF9mX4DCq5Wy7+A/w+A7q0wn6c= @@ -860,16 +833,20 @@ github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/S github.com/hashicorp/go-discover v0.0.0-20210818145131-c573d69da192 h1:eje2KOX8Sf7aYPiAsLnpWdAIrGRMcpFjN/Go/Exb7Zo= github.com/hashicorp/go-discover v0.0.0-20210818145131-c573d69da192/go.mod h1:3/4dzY4lR1Hzt9bBqMhBzG7lngZ0GKx/nL6G/ad62wE= github.com/hashicorp/go-gatedio v0.5.0 h1:Jm1X5yP4yCqqWj5L1TgW7iZwCVPGtVc+mro5r/XX7Tg= -github.com/hashicorp/go-gcp-common v0.8.0 h1:/2vGAbCU1v+BZ3YHXTCzTvxqma9WOJHYtADTfhZixLo= -github.com/hashicorp/go-gcp-common v0.8.0/go.mod h1:Q7zYRy9ue9SuaEN2s9YLIQs4SoKHdoRmKRcImY3SLgs= +github.com/hashicorp/go-gatedio v0.5.0/go.mod h1:Lr3t8L6IyxD3DAeaUxGcgl2JnRUpWMCsmBl4Omu/2t4= +github.com/hashicorp/go-gcp-common v0.5.0/go.mod h1:IDGUI2N/OS3PiU4qZcXJeWKPI6O/9Y8hOrbSiMcqyYw= +github.com/hashicorp/go-gcp-common v0.7.1-0.20220519220342-94aabf4c4c87 h1:ZFwYpI67zQ2G73zrij1LXhuubprduZORoClazMJ/cb8= +github.com/hashicorp/go-gcp-common v0.7.1-0.20220519220342-94aabf4c4c87/go.mod h1:RuZi18562/z30wxOzpjeRrGcmk9Ro/rBzixaSZDhIhY= +github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v0.16.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM= -github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v1.1.0 h1:QsGcniKx5/LuX2eYoeL+Np3UKYPNaN7YKpTh29h8rbw= +github.com/hashicorp/go-hclog v1.1.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -879,8 +856,8 @@ github.com/hashicorp/go-kms-wrapping v0.7.0 h1:UBagVJn4nSNOSjjtpkR370VOEBLnGMXfQ github.com/hashicorp/go-kms-wrapping v0.7.0/go.mod h1:rmGmNzO/DIBzUyisFjeocXvazOlxgO5K8vsFQkUn7Hk= github.com/hashicorp/go-kms-wrapping/entropy v0.1.0 h1:xuTi5ZwjimfpvpL09jDE71smCBRpnF5xfo871BSX4gs= github.com/hashicorp/go-kms-wrapping/entropy v0.1.0/go.mod h1:d1g9WGtAunDNpek8jUIEJnBlbgKS1N2Q61QkHiZyR1g= -github.com/hashicorp/go-memdb v1.3.3 h1:oGfEWrFuxtIUF3W2q/Jzt6G85TrMk9ey6XfYLvVe1Wo= -github.com/hashicorp/go-memdb v1.3.3/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg= +github.com/hashicorp/go-memdb v1.3.2 h1:RBKHOsnSszpU6vxq80LzC2BaQjuuvoyaQbkLTf7V7g8= +github.com/hashicorp/go-memdb v1.3.2/go.mod h1:Mluclgwib3R93Hk5fxEfiRhB+6Dar64wWh71LpNSe3g= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-msgpack v1.1.5 h1:9byZdVjKTe5mce63pRVNP1L7UAmdHOTEMGehn6KvJWs= @@ -890,6 +867,7 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= github.com/hashicorp/go-plugin v1.4.3/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ= github.com/hashicorp/go-plugin v1.4.4 h1:NVdrSdFRt3SkZtNckJ6tog7gbpRrcbOjQi/rgF7JYWQ= github.com/hashicorp/go-plugin v1.4.4/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= @@ -897,14 +875,14 @@ github.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a h1:Fmn github.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a/go.mod h1:xbXnmKqX9/+RhPkJ4zrEx4738HacP72aaUPlT2RZ4sU= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= +github.com/hashicorp/go-retryablehttp v0.6.7/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= +github.com/hashicorp/go-retryablehttp v0.7.0 h1:eu1EI/mbirUgP5C8hVsTNaGZreBDlYiwC1FZWkvQPQ4= github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= -github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1aJLQ4LJJbTQ= -github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-secure-stdlib/awsutil v0.1.2/go.mod h1:QRJZ7siKie+SZJB9jLbfKrs0Gd0yPWMtbneg0iU1PrY= -github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 h1:W9WN8p6moV1fjKLkeqEgkAMu5rauy9QeYDAmIaPuuiA= -github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6/go.mod h1:MpCPSPGLDILGb4JMm94/mMi3YysIqsXzGCzkEZjcjXg= +github.com/hashicorp/go-secure-stdlib/awsutil v0.1.5 h1:TkCWKqk1psjvUV7WktmZiRoZ1a9vw048AVnk/YbrzgY= +github.com/hashicorp/go-secure-stdlib/awsutil v0.1.5/go.mod h1:MpCPSPGLDILGb4JMm94/mMi3YysIqsXzGCzkEZjcjXg= github.com/hashicorp/go-secure-stdlib/base62 v0.1.1/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw= github.com/hashicorp/go-secure-stdlib/base62 v0.1.2 h1:ET4pqyjiGmY09R5y+rSd70J2w45CtbWDNvGqWp/R3Ng= github.com/hashicorp/go-secure-stdlib/base62 v0.1.2/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw= @@ -919,6 +897,7 @@ github.com/hashicorp/go-secure-stdlib/mlock v0.1.2 h1:p4AKXPPS24tO8Wc8i1gLvSKdmk github.com/hashicorp/go-secure-stdlib/mlock v0.1.2/go.mod h1:zq93CJChV6L9QTfGKtfBxKqD7BqqXx5O04A/ns2p5+I= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.2/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.4/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= github.com/hashicorp/go-secure-stdlib/password v0.1.1 h1:6JzmBqXprakgFEHwBgdchsjaA9x3GyjdI568bXKxa60= @@ -941,13 +920,14 @@ github.com/hashicorp/go-tfe v0.20.0 h1:XUAhKoCX8ZUQfwBebC8hz7nkSSnqgNkaablIfxnZ0 github.com/hashicorp/go-tfe v0.20.0/go.mod h1:gyXLXbpBVxA2F/6opah8XBsOkZJxHYQmghl0OWi8keI= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= -github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= -github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.4.0 h1:aAQzgqIrRKRa7w75CKpbBxYsmUoPjzVm1W59ca1L0J4= +github.com/hashicorp/go-version v1.4.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= @@ -960,9 +940,12 @@ github.com/hashicorp/jsonapi v0.0.0-20210826224640-ee7dae0fb22d h1:9ARUJJ1VVynB1 github.com/hashicorp/jsonapi v0.0.0-20210826224640-ee7dae0fb22d/go.mod h1:Yog5+CPEM3c99L1CL2CFCYoSzgWm5vTU58idbRUaLik= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= github.com/hashicorp/mdns v1.0.4 h1:sY0CMhFmjIPDMlTB+HfymFHCaYLhgifZ0QhjaYKD/UQ= github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/memberlist v0.3.0 h1:8+567mCcFDnS5ADl7lrpxPMWiFCElyUEeW0gtj34fMA= github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/nomad/api v0.0.0-20220407202126-2eba643965c4 h1:jwap3v+Yu5XvBXEX0r36km2rqAsXqEbGogTTwT5FgZM= @@ -971,15 +954,18 @@ github.com/hashicorp/raft v1.0.1/go.mod h1:DVSAWItjLjTOkVbSpWQ0j0kUADIvDaCtBxIcb github.com/hashicorp/raft v1.1.0/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM= github.com/hashicorp/raft v1.1.2-0.20191002163536-9c6bd3e3eb17/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= github.com/hashicorp/raft v1.2.0/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= -github.com/hashicorp/raft v1.3.10 h1:LR5QZX1VQd0DFWZfeCwWawyeKfpS/Tm1yjnJIY5X4Tw= -github.com/hashicorp/raft v1.3.10/go.mod h1:J8naEwc6XaaCfts7+28whSeRvCqTd6e20BlCU3LtEO4= -github.com/hashicorp/raft-autopilot v0.1.6 h1:C1q3RNF2FfXNZfHWbvVAu0QixaQK8K5pX4O5lh+9z4I= -github.com/hashicorp/raft-autopilot v0.1.6/go.mod h1:Af4jZBwaNOI+tXfIqIdbcAnh/UyyqIMj/pOISIfhArw= +github.com/hashicorp/raft v1.3.9 h1:9yuo1aR0bFTr1cw7pj3S2Bk6MhJCsnr2NAxvIBrP2x4= +github.com/hashicorp/raft v1.3.9/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM= +github.com/hashicorp/raft-autopilot v0.1.3 h1:Y+5jWKTFABJhCrpVwGpGjti2LzwQSzivoqd2wM6JWGw= +github.com/hashicorp/raft-autopilot v0.1.3/go.mod h1:Af4jZBwaNOI+tXfIqIdbcAnh/UyyqIMj/pOISIfhArw= +github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea h1:xykPFhrBAS2J0VBzVa5e80b5ZtYuNQtgXjN40qBZlD4= github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk= github.com/hashicorp/raft-boltdb/v2 v2.0.0-20210421194847-a7e34179d62c h1:oiKun9QlrOz5yQxMZJ3tf1kWtFYuKSJzxzEDxDPevj4= github.com/hashicorp/raft-boltdb/v2 v2.0.0-20210421194847-a7e34179d62c/go.mod h1:kiPs9g148eLShc2TYagUAyKDnD+dH9U+CQKsXzlY9xo= github.com/hashicorp/raft-snapshot v1.0.4 h1:EuDuayAJPdiDmVk1ygTDnG2zDzrs0/6/yBuma1IYSow= github.com/hashicorp/raft-snapshot v1.0.4/go.mod h1:5sL9eUn72lH5DzsFIJ9jaysITbHksSSszImWSOTC8Ic= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/serf v0.9.4/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hashicorp/serf v0.9.6 h1:uuEX1kLR6aoda1TBttmJQKDLZE1Ob7KN0NPdE7EtCDc= github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= github.com/hashicorp/vault-plugin-auth-alicloud v0.12.0 h1:Uv6V7tLPO09CPcHg2NfhxNkSQqtS3EpFwgC753hjC14= @@ -990,10 +976,10 @@ github.com/hashicorp/vault-plugin-auth-centrify v0.12.0 h1:d2dDZoUlSBNiw+jfi/2wx github.com/hashicorp/vault-plugin-auth-centrify v0.12.0/go.mod h1:3fDbIVdwA/hkOVhwktKHDX5lo4DqIUUVbBdwQNNvxHw= github.com/hashicorp/vault-plugin-auth-cf v0.12.0 h1:8X3Zlc6P/ih0MVhrPJ54iwiCyMVIcLwfBVpONuYddks= github.com/hashicorp/vault-plugin-auth-cf v0.12.0/go.mod h1:dr0cewrZ0SgpsPFkQ7Vf31J4xg+ylxM3Yv+dk1zWpEQ= -github.com/hashicorp/vault-plugin-auth-gcp v0.13.2-0.20220722185016-9e4fddb995e5 h1:uP0e9k8hIMfbWbeMKp6LxdRasxFBg4hTWaTmxDiwXZc= -github.com/hashicorp/vault-plugin-auth-gcp v0.13.2-0.20220722185016-9e4fddb995e5/go.mod h1:WNwaZN7NWy14xcy3otm1OXp5blcKgblUfvE16eYeUoQ= -github.com/hashicorp/vault-plugin-auth-jwt v0.13.2-0.20220728183411-0edf6ecc0b37 h1:gmJ49AHEJcrWNyo3GioyHvZVJCxSnKnTbLdm81A7XIU= -github.com/hashicorp/vault-plugin-auth-jwt v0.13.2-0.20220728183411-0edf6ecc0b37/go.mod h1:oWM7Naj8lo4J9vJ23S0kpNW9pmeiHRiG/9ghLlPu6N0= +github.com/hashicorp/vault-plugin-auth-gcp v0.13.2 h1:rv8gBKYzFz9BD9pFRyrmfi46BuOh3K2uSS3AjkVVEvg= +github.com/hashicorp/vault-plugin-auth-gcp v0.13.2/go.mod h1:tHtTF/qQmrRrY5DEOxWxoW/y5Wk9VoHsBOC339RO3d8= +github.com/hashicorp/vault-plugin-auth-jwt v0.13.0 h1:BeMC4ZnP8iwRgL8vInEvCICA6e+iiDtkmOdNYKg3aGQ= +github.com/hashicorp/vault-plugin-auth-jwt v0.13.0/go.mod h1:+WL5kaq/0L5OROsA31X15U8yTIX4GTEv1rTLA9d15eo= github.com/hashicorp/vault-plugin-auth-kerberos v0.7.2 h1:rtQ4aSr3vtAaQ8Al4p4ftZXgl47o+XyEbAR+mQNYaMs= github.com/hashicorp/vault-plugin-auth-kerberos v0.7.2/go.mod h1:eqjae8tMBpAWgJNk1NjV/vtJYXQRZnYudUkBFowz3bY= github.com/hashicorp/vault-plugin-auth-kubernetes v0.13.0 h1:pONFgWz9hbcS1wFxPtQJYj9Mt/nzPVX1kw1DGv+92Ww= @@ -1002,8 +988,8 @@ github.com/hashicorp/vault-plugin-auth-oci v0.11.0 h1:DrdccnGU8O28I1MIs21zmbYM2N github.com/hashicorp/vault-plugin-auth-oci v0.11.0/go.mod h1:Cn5cjR279Y+snw8LTaiLTko3KGrbigRbsQPOd2D5xDw= github.com/hashicorp/vault-plugin-database-couchbase v0.7.0 h1:p//NCrYPF7AlCFtwKsO6dT7RvINSq3/x1VN19nfPlK4= github.com/hashicorp/vault-plugin-database-couchbase v0.7.0/go.mod h1:Xw7uSxLWTzyWRHZhOBoc51cBC2nmNc7ekPgaaKK7UWI= -github.com/hashicorp/vault-plugin-database-elasticsearch v0.11.0 h1:3L3/KB7323cBkTzGDrRwVMcGtDMhU5VTWw9bYcVorEU= -github.com/hashicorp/vault-plugin-database-elasticsearch v0.11.0/go.mod h1:OMEQaNXsITksICGgkWW2y9/Nekv/cPKdqGOcMW5uUdI= +github.com/hashicorp/vault-plugin-database-elasticsearch v0.11.1 h1:XU2b1wrvHNeQafypbJ0Xs6Zec0kN5VzMZ0AJzWXlI+4= +github.com/hashicorp/vault-plugin-database-elasticsearch v0.11.1/go.mod h1:OMEQaNXsITksICGgkWW2y9/Nekv/cPKdqGOcMW5uUdI= github.com/hashicorp/vault-plugin-database-mongodbatlas v0.7.0 h1:TAyYn8/rWn+OeeiYAqlACV4q7A5YYDv3vVqucHTJgxE= github.com/hashicorp/vault-plugin-database-mongodbatlas v0.7.0/go.mod h1:e3HTaMD+aRWHBVctX/M39OaARQA8ux9TvdWDU0dJaoc= github.com/hashicorp/vault-plugin-database-snowflake v0.5.1 h1:/arASm4g8nyZrL2DxDSWhhQ7RjTrveXHURL3dRIfHM0= @@ -1016,10 +1002,10 @@ github.com/hashicorp/vault-plugin-secrets-alicloud v0.12.0 h1:4Ke3dtM7ARa9ga2jI2 github.com/hashicorp/vault-plugin-secrets-alicloud v0.12.0/go.mod h1:F4KWrlCQZbhP2dFXCkRvbHX2J6CTydlaY0cH+OrLHCE= github.com/hashicorp/vault-plugin-secrets-azure v0.13.0 h1:35JsvhKhvuATkP6vVQisA4prHd2gjzX4AT0CPvPXJ7I= github.com/hashicorp/vault-plugin-secrets-azure v0.13.0/go.mod h1:Xw8CQPkyZSJRK9BXKBruf6kOO8rLyXEf40o19ClK9kY= -github.com/hashicorp/vault-plugin-secrets-gcp v0.6.6-0.20220617175110-38223d8fabc9 h1:13NEYn/vLFiVfVpuHnu9ta7xDNiLp0IciSpiehiE4ug= -github.com/hashicorp/vault-plugin-secrets-gcp v0.6.6-0.20220617175110-38223d8fabc9/go.mod h1:kRgZfXRD9qUHoGclaR09tKXXwkwNrkY+D76ahetsaB8= -github.com/hashicorp/vault-plugin-secrets-gcpkms v0.5.7-0.20220617175201-b16d1500db6e h1:xjPKkxQOug4oo2KkV9N+qsEMlVW12OZNXMtIPw5ne0Y= -github.com/hashicorp/vault-plugin-secrets-gcpkms v0.5.7-0.20220617175201-b16d1500db6e/go.mod h1:n2VKlYDCuO8+OXN4S1Im8esIL53/ENRFa4gXrvhCVIM= +github.com/hashicorp/vault-plugin-secrets-gcp v0.13.1 h1:6aUi1Y9jGBoWm58wsJnq8xerxAsxXjdeFsgUle1eIqw= +github.com/hashicorp/vault-plugin-secrets-gcp v0.13.1/go.mod h1:ndpmRkIPHW5UYqv2nn2AJNVZsucJ8lY2bp5i5Ngvhuc= +github.com/hashicorp/vault-plugin-secrets-gcpkms v0.12.0 h1:MXqB1waq3L18eUhTZ7ng14MbjOiAlwANgZCVUwoLBXo= +github.com/hashicorp/vault-plugin-secrets-gcpkms v0.12.0/go.mod h1:6DPwGu8oGR1sZRpjwkcAnrQZWQuAJ/Ph+rQHfUo1Yf4= github.com/hashicorp/vault-plugin-secrets-kubernetes v0.1.1 h1:KiYpZpQv7X7Tm9wHUvboC2CyquwmjMhrPU2DvTcPC8o= github.com/hashicorp/vault-plugin-secrets-kubernetes v0.1.1/go.mod h1:aF9rgE2pGvWpyS/ijVrd817aA4Sf1I+dpLaKgshAPyQ= github.com/hashicorp/vault-plugin-secrets-kv v0.12.1 h1:Nef6kmnCQQRRdYzA52diUnx4r8HPwoh1oP9FCHB2hrg= @@ -1040,11 +1026,11 @@ github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKe github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I= github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4= github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huaweicloud/golangsdk v0.0.0-20200304081349-45ec0797f2a4/go.mod h1:WQBcHRNX9shz3928lWEvstQJtAtYI7ks6XlgtRT9Tcw= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= @@ -1053,10 +1039,10 @@ github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb v1.7.6/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab h1:HqW4xhhynfjrtEiiSGcQUd6vrK23iMam1FO8rI7mwig= github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= +github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -1079,6 +1065,7 @@ github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5W github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A= github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= @@ -1110,6 +1097,7 @@ github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dv github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jarcoal/httpmock v0.0.0-20180424175123-9c70cfe4a1da/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4= github.com/jarcoal/httpmock v1.0.7 h1:d1a2VFpSdm5gtjhCPWsQHSnx8+5V3ms5431YwvmkuNk= +github.com/jarcoal/httpmock v1.0.7/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= @@ -1146,6 +1134,7 @@ github.com/joyent/triton-go v0.0.0-20180628001255-830d2b111e62/go.mod h1:U+RSyWx github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f h1:ENpDacvnr8faw5ugQmEF1QYk+f/Y9lXFvuYmRxykago= github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f/go.mod h1:KDSfL7qe5ZfQqvlDMkVjCztbmcpp/c8M77vhQP8ZPvk= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -1156,6 +1145,7 @@ github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= @@ -1203,14 +1193,11 @@ github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs= -github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/linode/linodego v0.7.1 h1:4WZmMpSA2NRwlPZcc0+4Gyn7rr99Evk9bnr0B3gXRKE= github.com/linode/linodego v0.7.1/go.mod h1:ga11n3ivecUrPCHN0rANxKmfWBJVkOXfLMZinAbj2sY= github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= -github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -1225,6 +1212,7 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= @@ -1271,16 +1259,23 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.14.0/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/gox v1.0.1 h1:x0jD3dcHk9a9xPSDN6YEL4xL6Qz0dvNYm8yZqui5chI= +github.com/mitchellh/gox v1.0.1/go.mod h1:ED6BioOGXMswlXa2zxfh/xdd5QhwYliBFn9V18Ap4z4= github.com/mitchellh/hashstructure v1.0.0 h1:ZkRJX1CyOoTkar7p/mLS5TZU4nJ1Rn/F8u9dGS02Q3Y= github.com/mitchellh/hashstructure v1.0.0/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= +github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= @@ -1344,6 +1339,7 @@ github.com/olekukonko/tablewriter v0.0.0-20180130162743-b8a9be070da4/go.mod h1:v github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -1356,6 +1352,7 @@ github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v0.0.0-20190113212917-5533ce8a0da3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= @@ -1373,9 +1370,8 @@ github.com/opencontainers/go-digest v1.0.0-rc1.0.20180430190053-c9281466c8b2/go. github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= -github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= @@ -1395,6 +1391,8 @@ github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3 github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= github.com/openlyinc/pointy v1.1.2 h1:LywVV2BWC5Sp5v7FoP4bUD+2Yn5k0VNeRbU5vq9jUMY= github.com/openlyinc/pointy v1.1.2/go.mod h1:w2Sytx+0FVuMKn37xpXIAyBNhFNBIJGR/v2m7ik1WtM= +github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/oracle/oci-go-sdk v7.0.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= github.com/oracle/oci-go-sdk v13.1.0+incompatible h1:inwbT0b/mMbnTfzYoW2xcU1cCMIlU6Fz973at5phRXM= github.com/oracle/oci-go-sdk v13.1.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= @@ -1409,6 +1407,7 @@ github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c/go.mod h1:otz github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/patrickmn/go-cache v0.0.0-20180815053127-5633e0862627/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= @@ -1417,6 +1416,7 @@ github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrap github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.2.6+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= @@ -1430,21 +1430,16 @@ github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= -github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc= github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= @@ -1453,6 +1448,7 @@ github.com/pquerna/otp v1.2.1-0.20191009055518-468c2dd2b58d/go.mod h1:dkJfzwRKNi github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= @@ -1463,6 +1459,7 @@ github.com/prometheus/client_golang v1.11.1 h1:+4eQaD7vAZ6DsfsxB15hbE0odUjGI5ARs github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= @@ -1470,6 +1467,7 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= @@ -1480,6 +1478,7 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9 github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= @@ -1493,6 +1492,7 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rboyer/safeio v0.2.1 h1:05xhhdRNAdS3apYm7JRjOqngf4xruaW959jmRxGDuSU= github.com/rboyer/safeio v0.2.1/go.mod h1:Cq/cEPK+YXFn622lsQ0K4KsPZSPtaptHHEldsy7Fmig= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 h1:Wdi9nwnhFNAlseAOekn6B5G/+GMtks9UKbvRU/CMM/o= github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03/go.mod h1:gRAiPF5C5Nd0eyyRdqIu9qTiFSoZzpTq727b5B8fkkU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -1501,9 +1501,8 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.6.2 h1:aIihoIOHCiLZHxyoNQ+ABL4NKhFTgKLBdMLyEAh98m0= github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.4.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= @@ -1530,8 +1529,8 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/sethvargo/go-limiter v0.7.1 h1:wWNhTj0pxjyJ7wuJHpRJpYwJn+bUnjYfw2a85eu5w9U= github.com/sethvargo/go-limiter v0.7.1/go.mod h1:C0kbSFbiriE5k2FFOe18M1YZbAR2Fiwf72uGu0CXCcU= -github.com/shirou/gopsutil/v3 v3.22.6 h1:FnHOFOh+cYAM0C30P+zysPISzlknLC5Z1G4EAElznfQ= -github.com/shirou/gopsutil/v3 v3.22.6/go.mod h1:EdIubSnZhbAvBS1yJ7Xi+AShB/hxwLHOMz4MCYz7yMs= +github.com/shirou/gopsutil v3.21.5+incompatible h1:OloQyEerMi7JUrXiNzy8wQ5XN+baemxSl12QgIzt0jc= +github.com/shirou/gopsutil v3.21.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= @@ -1581,9 +1580,8 @@ github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1Sd github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -1591,9 +1589,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.5 h1:s5PTfem8p8EbKQOctVV53k6jCJt3UX4IEJzwh+C324Q= -github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= @@ -1602,10 +1599,10 @@ github.com/tencentcloud/tencentcloud-sdk-go v1.0.162 h1:8fDzz4GuVg4skjY2B0nMN7h6 github.com/tencentcloud/tencentcloud-sdk-go v1.0.162/go.mod h1:asUz5BPXxgoPGaRgZaVm1iGcUAuHyYUo1nXqKa83cvI= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= -github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk= -github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o= -github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ= +github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev3vTo= +github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs= +github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ= +github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= @@ -1662,8 +1659,6 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da/go.mod h1:E1AXubJBdNmFERAOucpDIxNzeGfLzg0mYh+UfMWdChA= github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9 h1:k/gmLsJDWwWqbLCur2yWnJzwQEKRcAHXo6seXGuSwWw= github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9/go.mod h1:E1AXubJBdNmFERAOucpDIxNzeGfLzg0mYh+UfMWdChA= -github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= -github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= @@ -1673,6 +1668,7 @@ go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489 h1:1JFLBqwIgdyHN1ZtgjTBwO+blA6gVOmZurpiMEsETKo= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= go.etcd.io/etcd/api/v3 v3.5.0 h1:GsV3S+OfZEOCNXdtNkBSR7kgLobAa/SO6tCxRa0GAYw= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= @@ -1688,12 +1684,13 @@ go.mongodb.org/atlas v0.15.0/go.mod h1:lQhRHIxc6jQHEK3/q9WLu/SdBkPj2fQYhjLGUF6Z3 go.mongodb.org/mongo-driver v1.7.3 h1:G4l/eYY9VrQAK/AUgkV0koQKzQnyddnWxrd/Etf0jIs= go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= +go.opencensus.io v0.19.1/go.mod h1:gug0GbSHa8Pafr0d2urOSgoXHZ6x/RUlaiT0d9pqb4A= +go.opencensus.io v0.19.2/go.mod h1:NO/8qkisMZLZ1FCsKNqtJPwc8/TaclWyY0B6wcYNg9M= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/otel v0.20.0 h1:eaP0Fqu7SXHwvjiqDq83zImeehOHX8doTvU9AwXON8g= @@ -1721,9 +1718,8 @@ go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec= -go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= @@ -1741,12 +1737,14 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -1766,6 +1764,9 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1780,7 +1781,9 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -1802,7 +1805,6 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1812,10 +1814,13 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190206173232-65e2d4e15006/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -1853,11 +1858,8 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= @@ -1865,6 +1867,7 @@ golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -1875,35 +1878,19 @@ golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220607020251-c690dde0001d h1:4SFsTMi4UahlKoloni7L4eYzhFRifURQLw+yv0QDCx8= -golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190130055435-99b60b757ec1/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190319182350-c85d3e98c914/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401 h1:zwrSfklXn0gxyLRX/aR+q6cgHbV/ItVyzbPlbA+dkAw= -golang.org/x/oauth2 v0.0.0-20220524215830-622c5d57e401/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1915,9 +1902,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1926,7 +1912,10 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181218192612-074acd46bca6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1998,7 +1987,6 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -2009,14 +1997,10 @@ golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -2031,27 +2015,19 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210818153620-00dd8d7831e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025112917-711f33c9992c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211031064116-611d5d643895/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 h1:xHms4gcpe1YE7A3yIllJXP16CMAGuqwO2lX1mTyyRRc= golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -2062,6 +2038,7 @@ golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fq golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -2076,12 +2053,15 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w= -golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44= +golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181219222714-6e267b5cc78e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -2142,19 +2122,13 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -2163,11 +2137,12 @@ golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.0.0-20181220000619-583d854617af/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.2.0/go.mod h1:IfRCZScioGtypHNTlz3gFk67J8uePVW7uDTBzXuIkhU= +google.golang.org/api v0.3.0/go.mod h1:IuvZyQh8jgscv8qWfQ4ABd8m7hEudgBFM/EdhA3BnXw= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -2185,35 +2160,13 @@ google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0 h1:yfrXXP61wVuLb0vBcG6qaOoIoqYEzOQS8jum51jkv2w= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.32.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= -google.golang.org/api v0.64.0/go.mod h1:931CdxA8Rm4t6zqTFGSsgwbAEZ2+GMYurbndwSimebM= -google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= -google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= -google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= -google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= -google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= -google.golang.org/api v0.83.0 h1:pMvST+6v+46Gabac4zlJlalxZjCeRcepwg2EdBU+nCc= -google.golang.org/api v0.83.0/go.mod h1:CNywQoj/AfhTw26ZWAa6LwOv+6WFxHmeLPZq2uncLZk= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= @@ -2222,11 +2175,13 @@ google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20181219182458-5a97ab628bfb/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190513181449-d00d292a067c/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= @@ -2258,58 +2213,20 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/genproto v0.0.0-20210630183607-d20f26d13c79/go.mod h1:yiaVoXHpRzHGyxV3o4DktVWY4mSUErTKaeEOq6C3t3U= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211223182754-3ac035c7e7cb/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220111164026-67b88f271998/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220602131408-e326c6e8e9c8 h1:qRu95HZ148xXw+XeZ3dvqe85PxH4X8+jIo0iRPKcEnM= -google.golang.org/genproto v0.0.0-20220602131408-e326c6e8e9c8/go.mod h1:yKyY4AMRwFiC8yMMNaMi+RkCnjZJt9LoWuvhXjMs+To= +google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207185906-7721543eae58 h1:i67FGOy2/zGfhE3YgHdrOrcFbOBhqdcRoBrsDqSQrOI= +google.golang.org/genproto v0.0.0-20220207185906-7721543eae58/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -2327,27 +2244,16 @@ google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= +google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8= -google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -2362,9 +2268,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= -google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -2380,6 +2285,7 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= @@ -2395,6 +2301,7 @@ gopkg.in/ory-am/dockertest.v3 v3.3.4/go.mod h1:s9mmoLkaGeAh97qygnNj4xWkiN7e1SKek gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.3.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= @@ -2413,14 +2320,15 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -2428,12 +2336,14 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +k8s.io/api v0.0.0-20190409092523-d687e77c8ae9/go.mod h1:FQEUn50aaytlU65qqBn/w+5ugllHwrBzKm7DzbnXdzE= k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78= k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= k8s.io/api v0.22.2 h1:M8ZzAD0V6725Fjg53fKeTJxGsJvRbk4TEm/fexHMtfw= k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8= +k8s.io/apimachinery v0.0.0-20190409092423-760d1845f48b/go.mod h1:FW86P8YXVLsbuplGMZeb20J3jYHscrDqw4jELaFJvRU= k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= @@ -2462,7 +2372,9 @@ k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8 k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.0.0-20190306015804-8e90cee79f82/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= @@ -2470,6 +2382,7 @@ k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.60.1 h1:VW25q3bZx9uE3vvdL6M8ezOX79vA2Aq1nEWLqNQclHc= k8s.io/klog/v2 v2.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= diff --git a/helper/forwarding/types.pb.go b/helper/forwarding/types.pb.go index dfc3aa7ce2b71..3a036f4726aaf 100644 --- a/helper/forwarding/types.pb.go +++ b/helper/forwarding/types.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.0 +// protoc-gen-go v1.27.1 // protoc v3.19.4 // source: helper/forwarding/types.proto diff --git a/helper/hostutil/hostinfo.go b/helper/hostutil/hostinfo.go index d35afb57d900a..ed8e648f6e628 100644 --- a/helper/hostutil/hostinfo.go +++ b/helper/hostutil/hostinfo.go @@ -8,10 +8,10 @@ import ( "time" "github.com/hashicorp/go-multierror" - "github.com/shirou/gopsutil/v3/cpu" - "github.com/shirou/gopsutil/v3/disk" - "github.com/shirou/gopsutil/v3/host" - "github.com/shirou/gopsutil/v3/mem" + "github.com/shirou/gopsutil/cpu" + "github.com/shirou/gopsutil/disk" + "github.com/shirou/gopsutil/host" + "github.com/shirou/gopsutil/mem" ) // HostInfo holds all the information that gets captured on the host. The @@ -28,10 +28,10 @@ type HostInfo struct { Disk []*disk.UsageStat `json:"disk"` // Host returns general host information such as hostname, platform, uptime, // kernel version, etc. - Host *HostInfoStat `json:"host"` + Host *host.InfoStat `json:"host"` // Memory contains statistics about the memory such as total, available, and // used memory in number of bytes. - Memory *VirtualMemoryStat `json:"memory"` + Memory *mem.VirtualMemoryStat `json:"memory"` } // CollectHostInfo returns information on the host, which includes general @@ -44,13 +44,13 @@ func CollectHostInfo(ctx context.Context) (*HostInfo, error) { var retErr *multierror.Error info := &HostInfo{Timestamp: time.Now().UTC()} - if h, err := CollectHostInfoStat(ctx); err != nil { + if h, err := host.InfoWithContext(ctx); err != nil { retErr = multierror.Append(retErr, &HostInfoError{"host", err}) } else { info.Host = h } - if v, err := CollectHostMemory(ctx); err != nil { + if v, err := mem.VirtualMemoryWithContext(ctx); err != nil { retErr = multierror.Append(retErr, &HostInfoError{"memory", err}) } else { info.Memory = v @@ -96,63 +96,9 @@ func CollectHostMemory(ctx context.Context) (*VirtualMemoryStat, error) { } return &VirtualMemoryStat{ - Total: m.Total, - Available: m.Available, - Used: m.Used, - UsedPercent: m.UsedPercent, - Free: m.Free, - Active: m.Active, - Inactive: m.Inactive, - Wired: m.Wired, - Laundry: m.Laundry, - Buffers: m.Buffers, - Cached: m.Cached, - Writeback: m.WriteBack, - Dirty: m.Dirty, - WritebackTmp: m.WriteBackTmp, - Shared: m.Shared, - Slab: m.Slab, - SReclaimable: m.Sreclaimable, - SUnreclaim: m.Sunreclaim, - PageTables: m.PageTables, - SwapCached: m.SwapCached, - CommitLimit: m.CommitLimit, - CommittedAS: m.CommittedAS, - HighTotal: m.HighTotal, - HighFree: m.HighFree, - LowTotal: m.LowTotal, - LowFree: m.LowFree, - SwapTotal: m.SwapTotal, - SwapFree: m.SwapFree, - Mapped: m.Mapped, - VMallocTotal: m.VmallocTotal, - VMallocUsed: m.VmallocUsed, - VMallocChunk: m.VmallocChunk, - HugePagesTotal: m.HugePagesTotal, - HugePagesFree: m.HugePagesFree, - HugePageSize: m.HugePageSize, - }, nil -} - -func CollectHostInfoStat(ctx context.Context) (*HostInfoStat, error) { - h, err := host.InfoWithContext(ctx) - if err != nil { - return nil, err - } - - return &HostInfoStat{ - Hostname: h.Hostname, - Uptime: h.Uptime, - BootTime: h.BootTime, - Procs: h.Procs, - OS: h.OS, - Platform: h.Platform, - PlatformFamily: h.PlatformFamily, - PlatformVersion: h.PlatformVersion, - KernelVersion: h.KernelVersion, - KernelArch: h.KernelArch, - VirtualizationSystem: h.VirtualizationSystem, - VirtualizationRole: h.VirtualizationRole, - HostID: h.HostID, + Total: m.Total, + Available: m.Available, + Used: m.Used, + UsedPercent: m.UsedPercent, }, nil } diff --git a/helper/hostutil/hostinfo_util.go b/helper/hostutil/hostinfo_util.go index 8811746fd8178..114f596f9abab 100644 --- a/helper/hostutil/hostinfo_util.go +++ b/helper/hostutil/hostinfo_util.go @@ -1,124 +1,24 @@ -// Copyright (c) 2014, WAKAYAMA Shirou -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, -// are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name of the gopsutil authors nor the names of its contributors -// may be used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Copied from https://github.com/shirou/gopsutil/blob/b49f37e9f30f49530cf2ad6038a4dac1b746c8f7/mem/mem.go#L15 -// Copied from https://github.com/shirou/gopsutil/blob/b49f37e9f30f49530cf2ad6038a4dac1b746c8f7/host/host.go#L17 - package hostutil -// VirtualMemoryStat holds commonly used memory measurements. We must have a +// VirutalMemoryStat holds commonly used memory measurements. We must have a // local type here in order to avoid building the gopsutil library on certain // arch types. -// -// This struct is copied to maintain backwards compatibility in the Vault host-info API. -// This is done because gopsutil changed JSON struct tags between its v2 and v3 releases. -// For details see https://github.com/shirou/gopsutil/tree/master/_tools/v3migration. type VirtualMemoryStat struct { // Total amount of RAM on this system - Total uint64 `json:"total"` + Total uint64 // RAM available for programs to allocate // // This value is computed from the kernel specific values. - Available uint64 `json:"available"` + Available uint64 // RAM used by programs // // This value is computed from the kernel specific values. - Used uint64 `json:"used"` + Used uint64 // Percentage of RAM used by programs // // This value is computed from the kernel specific values. - UsedPercent float64 `json:"usedPercent"` - - // This is the kernel's notion of free memory; RAM chips whose bits nobody - // cares about the value of right now. For a human consumable number, - // Available is what you really want. - Free uint64 `json:"free"` - - // OS X / BSD specific numbers: - // http://www.macyourself.com/2010/02/17/what-is-free-wired-active-and-inactive-system-memory-ram/ - Active uint64 `json:"active"` - Inactive uint64 `json:"inactive"` - Wired uint64 `json:"wired"` - - // FreeBSD specific numbers: - // https://reviews.freebsd.org/D8467 - Laundry uint64 `json:"laundry"` - - // Linux specific numbers - // https://www.centos.org/docs/5/html/5.1/Deployment_Guide/s2-proc-meminfo.html - // https://www.kernel.org/doc/Documentation/filesystems/proc.txt - // https://www.kernel.org/doc/Documentation/vm/overcommit-accounting - Buffers uint64 `json:"buffers"` - Cached uint64 `json:"cached"` - Writeback uint64 `json:"writeback"` - Dirty uint64 `json:"dirty"` - WritebackTmp uint64 `json:"writebacktmp"` - Shared uint64 `json:"shared"` - Slab uint64 `json:"slab"` - SReclaimable uint64 `json:"sreclaimable"` - SUnreclaim uint64 `json:"sunreclaim"` - PageTables uint64 `json:"pagetables"` - SwapCached uint64 `json:"swapcached"` - CommitLimit uint64 `json:"commitlimit"` - CommittedAS uint64 `json:"committedas"` - HighTotal uint64 `json:"hightotal"` - HighFree uint64 `json:"highfree"` - LowTotal uint64 `json:"lowtotal"` - LowFree uint64 `json:"lowfree"` - SwapTotal uint64 `json:"swaptotal"` - SwapFree uint64 `json:"swapfree"` - Mapped uint64 `json:"mapped"` - VMallocTotal uint64 `json:"vmalloctotal"` - VMallocUsed uint64 `json:"vmallocused"` - VMallocChunk uint64 `json:"vmallocchunk"` - HugePagesTotal uint64 `json:"hugepagestotal"` - HugePagesFree uint64 `json:"hugepagesfree"` - HugePageSize uint64 `json:"hugepagesize"` -} - -// HostInfoStat describes the host status. -// -// This struct is copied to maintain backwards compatibility in the Vault host-info API. -// This is done because gopsutil changed JSON struct tags between its v2 and v3 releases. -// For details see https://github.com/shirou/gopsutil/tree/master/_tools/v3migration. -type HostInfoStat struct { - Hostname string `json:"hostname"` - Uptime uint64 `json:"uptime"` - BootTime uint64 `json:"bootTime"` - Procs uint64 `json:"procs"` - OS string `json:"os"` - Platform string `json:"platform"` - PlatformFamily string `json:"platformFamily"` - PlatformVersion string `json:"platformVersion"` - KernelVersion string `json:"kernelVersion"` - KernelArch string `json:"kernelArch"` - VirtualizationSystem string `json:"virtualizationSystem"` - VirtualizationRole string `json:"virtualizationRole"` - HostID string `json:"hostid"` + UsedPercent float64 } diff --git a/helper/identity/mfa/types.pb.go b/helper/identity/mfa/types.pb.go index f306ad4048bef..789def20f0fe0 100644 --- a/helper/identity/mfa/types.pb.go +++ b/helper/identity/mfa/types.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.0 +// protoc-gen-go v1.27.1 // protoc v3.19.4 // source: helper/identity/mfa/types.proto diff --git a/helper/identity/types.pb.go b/helper/identity/types.pb.go index 278f361d772d1..a392d24bc313e 100644 --- a/helper/identity/types.pb.go +++ b/helper/identity/types.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.0 +// protoc-gen-go v1.27.1 // protoc v3.19.4 // source: helper/identity/types.proto diff --git a/helper/metricsutil/gauge_process.go b/helper/metricsutil/gauge_process.go index 0ad0e9d876cf9..fd327bc687f85 100644 --- a/helper/metricsutil/gauge_process.go +++ b/helper/metricsutil/gauge_process.go @@ -6,7 +6,6 @@ import ( "sort" "time" - "github.com/armon/go-metrics" log "github.com/hashicorp/go-hclog" ) @@ -61,7 +60,7 @@ type GaugeCollectionProcess struct { collector GaugeCollector // destination for metrics - sink Metrics + sink *ClusterMetricSink logger log.Logger // time between collections @@ -69,39 +68,10 @@ type GaugeCollectionProcess struct { currentInterval time.Duration ticker *time.Ticker - // used to help limit cardinality - maxGaugeCardinality int - // time source clock clock } -// NewGaugeCollectionProcess creates a new collection process for the callback -// function given as an argument, and starts it running. -// A label should be provided for metrics *about* this collection process. -// -// The Run() method must be called to start the process. -func NewGaugeCollectionProcess( - key []string, - id []Label, - collector GaugeCollector, - m metrics.MetricSink, - gaugeInterval time.Duration, - maxGaugeCardinality int, - logger log.Logger, -) (*GaugeCollectionProcess, error) { - return newGaugeCollectionProcessWithClock( - key, - id, - collector, - SinkWrapper{MetricSink: m}, - gaugeInterval, - maxGaugeCardinality, - logger, - defaultClock{}, - ) -} - // NewGaugeCollectionProcess creates a new collection process for the callback // function given as an argument, and starts it running. // A label should be provided for metrics *about* this collection process. @@ -113,48 +83,41 @@ func (m *ClusterMetricSink) NewGaugeCollectionProcess( collector GaugeCollector, logger log.Logger, ) (*GaugeCollectionProcess, error) { - return newGaugeCollectionProcessWithClock( + return m.newGaugeCollectionProcessWithClock( key, id, collector, - m, - m.GaugeInterval, - m.MaxGaugeCardinality, logger, defaultClock{}, ) } // test version allows an alternative clock implementation -func newGaugeCollectionProcessWithClock( +func (m *ClusterMetricSink) newGaugeCollectionProcessWithClock( key []string, id []Label, collector GaugeCollector, - sink Metrics, - gaugeInterval time.Duration, - maxGaugeCardinality int, logger log.Logger, clock clock, ) (*GaugeCollectionProcess, error) { process := &GaugeCollectionProcess{ - stop: make(chan struct{}, 1), - stopped: make(chan struct{}, 1), - key: key, - labels: id, - collector: collector, - sink: sink, - originalInterval: gaugeInterval, - currentInterval: gaugeInterval, - maxGaugeCardinality: maxGaugeCardinality, - logger: logger, - clock: clock, + stop: make(chan struct{}, 1), + stopped: make(chan struct{}, 1), + key: key, + labels: id, + collector: collector, + sink: m, + originalInterval: m.GaugeInterval, + currentInterval: m.GaugeInterval, + logger: logger, + clock: clock, } return process, nil } // delayStart randomly delays by up to one extra interval -// so that collection processes do not all run at the time. -// If we knew all the processes in advance, we could just schedule them +// so that collection processes do not all run at the time time. +// If we knew all the procsses in advance, we could just schedule them // evenly, but a new one could be added per secret engine. func (p *GaugeCollectionProcess) delayStart() bool { randomDelay := time.Duration(rand.Int63n(int64(p.currentInterval))) @@ -224,11 +187,11 @@ func (p *GaugeCollectionProcess) collectAndFilterGauges() { // Filter to top N. // This does not guarantee total cardinality is <= N, but it does slow things down // a little if the cardinality *is* too high and the gauge needs to be disabled. - if len(values) > p.maxGaugeCardinality { + if len(values) > p.sink.MaxGaugeCardinality { sort.Slice(values, func(a, b int) bool { return values[a].Value > values[b].Value }) - values = values[:p.maxGaugeCardinality] + values = values[:p.sink.MaxGaugeCardinality] } p.streamGaugesToSink(values) diff --git a/helper/metricsutil/gauge_process_test.go b/helper/metricsutil/gauge_process_test.go index 9971714e04e30..89ef813a850c6 100644 --- a/helper/metricsutil/gauge_process_test.go +++ b/helper/metricsutil/gauge_process_test.go @@ -147,13 +147,10 @@ func TestGauge_StartDelay(t *testing.T) { sink := BlackholeSink() sink.GaugeInterval = 2 * time.Hour - p, err := newGaugeCollectionProcessWithClock( + p, err := sink.newGaugeCollectionProcessWithClock( []string{"example", "count"}, []Label{{"gauge", "test"}}, c.EmptyCollectionFunction, - sink, - sink.GaugeInterval, - sink.MaxGaugeCardinality, log.Default(), s, ) @@ -212,13 +209,10 @@ func TestGauge_StoppedDuringInitialDelay(t *testing.T) { sink := BlackholeSink() sink.GaugeInterval = 2 * time.Hour - p, err := newGaugeCollectionProcessWithClock( + p, err := sink.newGaugeCollectionProcessWithClock( []string{"example", "count"}, []Label{{"gauge", "test"}}, c.EmptyCollectionFunction, - sink, - sink.GaugeInterval, - sink.MaxGaugeCardinality, log.Default(), s, ) @@ -241,13 +235,10 @@ func TestGauge_StoppedAfterInitialDelay(t *testing.T) { sink := BlackholeSink() sink.GaugeInterval = 2 * time.Hour - p, err := newGaugeCollectionProcessWithClock( + p, err := sink.newGaugeCollectionProcessWithClock( []string{"example", "count"}, []Label{{"gauge", "test"}}, c.EmptyCollectionFunction, - sink, - sink.GaugeInterval, - sink.MaxGaugeCardinality, log.Default(), s, ) @@ -283,13 +274,10 @@ func TestGauge_Backoff(t *testing.T) { return []GaugeLabelValues{}, nil } - p, err := newGaugeCollectionProcessWithClock( + p, err := sink.newGaugeCollectionProcessWithClock( []string{"example", "count"}, []Label{{"gauge", "test"}}, f, - sink, - sink.GaugeInterval, - sink.MaxGaugeCardinality, log.Default(), s, ) @@ -312,13 +300,10 @@ func TestGauge_RestartTimer(t *testing.T) { sink := BlackholeSink() sink.GaugeInterval = 2 * time.Hour - p, err := newGaugeCollectionProcessWithClock( + p, err := sink.newGaugeCollectionProcessWithClock( []string{"example", "count"}, []Label{{"gauge", "test"}}, c.EmptyCollectionFunction, - sink, - sink.GaugeInterval, - sink.MaxGaugeCardinality, log.Default(), s, ) @@ -385,13 +370,10 @@ func TestGauge_InterruptedStreaming(t *testing.T) { sink.MaxGaugeCardinality = 500 sink.GaugeInterval = 2 * time.Hour - p, err := newGaugeCollectionProcessWithClock( + p, err := sink.newGaugeCollectionProcessWithClock( []string{"example", "count"}, []Label{{"gauge", "test"}}, nil, // shouldn't be called - sink, - sink.GaugeInterval, - sink.MaxGaugeCardinality, log.Default(), s, ) @@ -463,13 +445,10 @@ func TestGauge_MaximumMeasurements(t *testing.T) { // Advance time by 0.5% of duration advance := time.Duration(int(0.005 * float32(sink.GaugeInterval))) - p, err := newGaugeCollectionProcessWithClock( + p, err := sink.newGaugeCollectionProcessWithClock( []string{"example", "count"}, []Label{{"gauge", "test"}}, c.makeFunctionForValues(values, s, advance), - sink, - sink.GaugeInterval, - sink.MaxGaugeCardinality, log.Default(), s, ) @@ -545,13 +524,10 @@ func TestGauge_MeasurementError(t *testing.T) { return values, errors.New("test error") } - p, err := newGaugeCollectionProcessWithClock( + p, err := sink.newGaugeCollectionProcessWithClock( []string{"example", "count"}, []Label{{"gauge", "test"}}, f, - sink, - sink.GaugeInterval, - sink.MaxGaugeCardinality, log.Default(), s, ) diff --git a/helper/metricsutil/metricsutil.go b/helper/metricsutil/metricsutil.go index de85c7e4628e9..0abb8148e3eb9 100644 --- a/helper/metricsutil/metricsutil.go +++ b/helper/metricsutil/metricsutil.go @@ -105,7 +105,7 @@ func (m *MetricsHelper) ResponseForFormat(format string) *logical.Response { return &logical.Response{ Data: map[string]interface{}{ logical.HTTPContentType: ErrorContentType, - logical.HTTPRawBody: fmt.Sprintf("metric response format %q unknown", format), + logical.HTTPRawBody: fmt.Sprintf("metric response format \"%s\" unknown", format), logical.HTTPStatusCode: http.StatusBadRequest, }, } diff --git a/helper/metricsutil/wrapped_metrics.go b/helper/metricsutil/wrapped_metrics.go index 67deb3bee1cd1..dcbd42aad3f27 100644 --- a/helper/metricsutil/wrapped_metrics.go +++ b/helper/metricsutil/wrapped_metrics.go @@ -5,7 +5,7 @@ import ( "sync/atomic" "time" - "github.com/armon/go-metrics" + metrics "github.com/armon/go-metrics" "github.com/hashicorp/vault/helper/namespace" ) @@ -49,25 +49,6 @@ type Metrics interface { var _ Metrics = &ClusterMetricSink{} -// SinkWrapper implements `metricsutil.Metrics` using an instance of -// armon/go-metrics `MetricSink` as the underlying implementation. -type SinkWrapper struct { - metrics.MetricSink -} - -func (s SinkWrapper) AddDurationWithLabels(key []string, d time.Duration, labels []Label) { - val := float32(d) / float32(time.Millisecond) - s.MetricSink.AddSampleWithLabels(key, val, labels) -} - -func (s SinkWrapper) MeasureSinceWithLabels(key []string, start time.Time, labels []Label) { - elapsed := time.Now().Sub(start) - val := float32(elapsed) / float32(time.Millisecond) - s.MetricSink.AddSampleWithLabels(key, val, labels) -} - -var _ Metrics = SinkWrapper{} - // Convenience alias type Label = metrics.Label diff --git a/helper/namespace/namespace.go b/helper/namespace/namespace.go index 93d68622dec57..90ddadefd62df 100644 --- a/helper/namespace/namespace.go +++ b/helper/namespace/namespace.go @@ -12,9 +12,8 @@ import ( type contextValues struct{} type Namespace struct { - ID string `json:"id" mapstructure:"id"` - Path string `json:"path" mapstructure:"path"` - CustomMetadata map[string]string `json:"custom_metadata" mapstructure:"custom_metadata"` + ID string `json:"id"` + Path string `json:"path"` } func (n *Namespace) String() string { @@ -29,9 +28,8 @@ var ( contextNamespace contextValues = struct{}{} ErrNoNamespace error = errors.New("no namespace") RootNamespace *Namespace = &Namespace{ - ID: RootNamespaceID, - Path: "", - CustomMetadata: make(map[string]string), + ID: RootNamespaceID, + Path: "", } ) diff --git a/helper/pgpkeys/flag_test.go b/helper/pgpkeys/flag_test.go index 86e04611f1cfe..214a1719b9ae6 100644 --- a/helper/pgpkeys/flag_test.go +++ b/helper/pgpkeys/flag_test.go @@ -68,7 +68,7 @@ func TestPubKeyFilesFlagSetBinary(t *testing.T) { t.Fatalf("err: should not have been able to set a second value") } - expected := []string{strings.ReplaceAll(pubKey1, "\n", ""), strings.ReplaceAll(pubKey2, "\n", "")} + expected := []string{strings.Replace(pubKey1, "\n", "", -1), strings.Replace(pubKey2, "\n", "", -1)} if !reflect.DeepEqual(pkf.String(), fmt.Sprint(expected)) { t.Fatalf("Bad: %#v", pkf) } diff --git a/helper/storagepacker/types.pb.go b/helper/storagepacker/types.pb.go index 235b5c011c9ca..bd7b780cd5a9a 100644 --- a/helper/storagepacker/types.pb.go +++ b/helper/storagepacker/types.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.0 +// protoc-gen-go v1.27.1 // protoc v3.19.4 // source: helper/storagepacker/types.proto diff --git a/helper/testhelpers/consul/consulhelper.go b/helper/testhelpers/consul/consulhelper.go index e88ead2bfad56..3facba58feb1b 100644 --- a/helper/testhelpers/consul/consulhelper.go +++ b/helper/testhelpers/consul/consulhelper.go @@ -27,7 +27,7 @@ func (c *Config) APIConfig() *consulapi.Config { // the Consul version used will be given by the environment variable // CONSUL_DOCKER_VERSION, or if that's empty, whatever we've hardcoded as the // the latest Consul version. -func PrepareTestContainer(t *testing.T, version string, isEnterprise bool, doBootstrapSetup bool) (func(), *Config) { +func PrepareTestContainer(t *testing.T, version string, isEnterprise bool, bootstrap bool) (func(), *Config) { t.Helper() if retAddress := os.Getenv("CONSUL_HTTP_ADDR"); retAddress != "" { @@ -119,7 +119,7 @@ func PrepareTestContainer(t *testing.T, version string, isEnterprise bool, doBoo // New default behavior var consulToken string - if doBootstrapSetup { + if bootstrap { aclbootstrap, _, err := consul.ACL().Bootstrap() if err != nil { return nil, err diff --git a/helper/testhelpers/logical/testing.go b/helper/testhelpers/logical/testing.go index 4740ff6be370a..ffc801b78d5d6 100644 --- a/helper/testhelpers/logical/testing.go +++ b/helper/testhelpers/logical/testing.go @@ -120,7 +120,7 @@ func Test(tt TestT, c TestCase) { // slow and generally require some outside configuration. if c.AcceptanceTest && os.Getenv(TestEnvVar) == "" { tt.Skip(fmt.Sprintf( - "Acceptance tests skipped unless env %q set", + "Acceptance tests skipped unless env '%s' set", TestEnvVar)) return } diff --git a/helper/testhelpers/teststorage/teststorage_reusable.go b/helper/testhelpers/teststorage/teststorage_reusable.go index 257a5a0184c5f..7806f03635118 100644 --- a/helper/testhelpers/teststorage/teststorage_reusable.go +++ b/helper/testhelpers/teststorage/teststorage_reusable.go @@ -18,6 +18,7 @@ import ( // seal migration, wherein a given physical backend must be re-used as several // test clusters are sequentially created, tested, and discarded. type ReusableStorage struct { + // IsRaft specifies whether the storage is using a raft backend. IsRaft bool diff --git a/http/logical.go b/http/logical.go index 34c60d18ee681..2de6c32954857 100644 --- a/http/logical.go +++ b/http/logical.go @@ -178,8 +178,6 @@ func buildLogicalRequestNoAuth(perfStandby bool, w http.ResponseWriter, r *http. path += "/" } - data = parseQuery(r.URL.Query()) - case "OPTIONS", "HEAD": default: return nil, nil, http.StatusMethodNotAllowed, nil diff --git a/http/logical_test.go b/http/logical_test.go index 9fccb063183f6..5580e13082f76 100644 --- a/http/logical_test.go +++ b/http/logical_test.go @@ -555,23 +555,10 @@ func TestLogical_AuditPort(t *testing.T) { }, } - // workaround kv-v2 initialization upgrade errors - numFailures := 0 - vault.RetryUntil(t, 10*time.Second, func() error { - resp, err := c.Logical().Write("kv/data/foo", writeData) - if err != nil { - if strings.Contains(err.Error(), "Upgrading from non-versioned to versioned data") { - t.Logf("Retrying fetch KV data due to upgrade error") - time.Sleep(100 * time.Millisecond) - numFailures += 1 - return err - } - - t.Fatalf("write request failed, err: %#v, resp: %#v\n", err, resp) - } - - return nil - }) + resp, err := c.Logical().Write("kv/data/foo", writeData) + if err != nil { + t.Fatalf("write request failed, err: %#v, resp: %#v\n", err, resp) + } decoder := json.NewDecoder(auditLogFile) @@ -592,7 +579,7 @@ func TestLogical_AuditPort(t *testing.T) { } if _, ok := auditRequest["remote_address"].(string); !ok { - t.Fatalf("remote_address should be a string, not %T", auditRequest["remote_address"]) + t.Fatalf("remote_port should be a number, not %T", auditRequest["remote_address"]) } if _, ok := auditRequest["remote_port"].(float64); !ok { @@ -600,12 +587,8 @@ func TestLogical_AuditPort(t *testing.T) { } } - // We expect the following items in the audit log: - // audit log header + an entry for updating sys/audit/file - // + request/response per failure (if any) + request/response for creating kv - numExpectedEntries := (numFailures * 2) + 4 - if count != numExpectedEntries { - t.Fatalf("wrong number of audit entries expected: %d got: %d", numExpectedEntries, count) + if count != 4 { + t.Fatalf("wrong number of audit entries: %d", count) } } diff --git a/http/sys_init.go b/http/sys_init.go index ae3059462bef4..b21e5363ea020 100644 --- a/http/sys_init.go +++ b/http/sys_init.go @@ -4,9 +4,7 @@ import ( "context" "encoding/base64" "encoding/hex" - "fmt" "net/http" - "strings" "github.com/hashicorp/vault/vault" ) @@ -46,12 +44,6 @@ func handleSysInitPut(core *vault.Core, w http.ResponseWriter, r *http.Request) return } - // Validate init request parameters - if err := validateInitParameters(core, req); err != nil { - respondError(w, http.StatusBadRequest, err) - return - } - // Initialize barrierConfig := &vault.SealConfig{ SecretShares: req.SecretShares, @@ -136,41 +128,3 @@ type InitResponse struct { type InitStatusResponse struct { Initialized bool `json:"initialized"` } - -// Validates if the right parameters are used based on AutoUnseal -func validateInitParameters(core *vault.Core, req InitRequest) error { - recoveryFlags := make([]string, 0) - barrierFlags := make([]string, 0) - - if req.SecretShares != 0 { - barrierFlags = append(barrierFlags, "secret_shares") - } - if req.SecretThreshold != 0 { - barrierFlags = append(barrierFlags, "secret_threshold") - } - if len(req.PGPKeys) != 0 { - barrierFlags = append(barrierFlags, "pgp_keys") - } - if req.RecoveryShares != 0 { - recoveryFlags = append(recoveryFlags, "recovery_shares") - } - if req.RecoveryThreshold != 0 { - recoveryFlags = append(recoveryFlags, "recovery_threshold") - } - if len(req.RecoveryPGPKeys) != 0 { - recoveryFlags = append(recoveryFlags, "recovery_pgp_keys") - } - - switch core.SealAccess().RecoveryKeySupported() { - case true: - if len(barrierFlags) > 0 { - return fmt.Errorf("parameters %s not applicable to seal type %s", strings.Join(barrierFlags, ","), core.SealAccess().BarrierType()) - } - default: - if len(recoveryFlags) > 0 { - return fmt.Errorf("parameters %s not applicable to seal type %s", strings.Join(recoveryFlags, ","), core.SealAccess().BarrierType()) - } - - } - return nil -} diff --git a/http/sys_init_test.go b/http/sys_init_test.go index 38a15f6ccc42e..f4be3413a9022 100644 --- a/http/sys_init_test.go +++ b/http/sys_init_test.go @@ -4,15 +4,9 @@ import ( "encoding/hex" "net/http" "reflect" - "strconv" "testing" - "github.com/hashicorp/go-hclog" - "github.com/hashicorp/vault/builtin/logical/transit" - "github.com/hashicorp/vault/sdk/helper/logging" - "github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/vault" - "github.com/hashicorp/vault/vault/seal" ) func TestSysInit_get(t *testing.T) { @@ -129,63 +123,3 @@ func TestSysInit_put(t *testing.T) { t.Fatal("should not be sealed") } } - -func TestSysInit_Put_ValidateParams(t *testing.T) { - core := vault.TestCore(t) - ln, addr := TestServer(t, core) - defer ln.Close() - - resp := testHttpPut(t, "", addr+"/v1/sys/init", map[string]interface{}{ - "secret_shares": 5, - "secret_threshold": 3, - "recovery_shares": 5, - "recovery_threshold": 3, - }) - testResponseStatus(t, resp, http.StatusBadRequest) - body := map[string][]string{} - testResponseBody(t, resp, &body) - if body["errors"][0] != "parameters recovery_shares,recovery_threshold not applicable to seal type shamir" { - t.Fatal(body) - } -} - -func TestSysInit_Put_ValidateParams_AutoUnseal(t *testing.T) { - testSeal := seal.NewTestSeal(nil) - autoSeal := vault.NewAutoSeal(testSeal) - autoSeal.SetType("transit") - - // Create the transit server. - conf := &vault.CoreConfig{ - LogicalBackends: map[string]logical.Factory{ - "transit": transit.Factory, - }, - Seal: autoSeal, - } - opts := &vault.TestClusterOptions{ - NumCores: 1, - HandlerFunc: Handler, - Logger: logging.NewVaultLogger(hclog.Trace).Named(t.Name()).Named("transit-seal" + strconv.Itoa(0)), - } - cluster := vault.NewTestCluster(t, conf, opts) - cluster.Start() - defer cluster.Cleanup() - - cores := cluster.Cores - core := cores[0].Core - - ln, addr := TestServer(t, core) - defer ln.Close() - - resp := testHttpPut(t, "", addr+"/v1/sys/init", map[string]interface{}{ - "secret_shares": 5, - "secret_threshold": 3, - "recovery_shares": 5, - "recovery_threshold": 3, - }) - testResponseStatus(t, resp, http.StatusBadRequest) - body := map[string][]string{} - testResponseBody(t, resp, &body) - if body["errors"][0] != "parameters secret_shares,secret_threshold not applicable to seal type transit" { - t.Fatal(body) - } -} diff --git a/http/sys_raft.go b/http/sys_raft.go index 428aad4f7da3a..5db1a80fb78f6 100644 --- a/http/sys_raft.go +++ b/http/sys_raft.go @@ -68,7 +68,7 @@ func handleSysRaftJoinPost(core *vault.Core, w http.ResponseWriter, r *http.Requ } if req.AutoJoinScheme != "" && (req.AutoJoinScheme != "http" && req.AutoJoinScheme != "https") { - respondError(w, http.StatusBadRequest, fmt.Errorf("invalid scheme %q; must either be http or https", req.AutoJoinScheme)) + respondError(w, http.StatusBadRequest, fmt.Errorf("invalid scheme '%s'; must either be http or https", req.AutoJoinScheme)) return } diff --git a/http/util.go b/http/util.go index b4c8923cc3eea..cbb364843c308 100644 --- a/http/util.go +++ b/http/util.go @@ -1,10 +1,7 @@ package http import ( - "bytes" - "errors" "fmt" - "io/ioutil" "net" "net/http" "strings" @@ -50,21 +47,11 @@ func rateLimitQuotaWrapping(handler http.Handler, core *vault.Core) http.Handler respondError(w, status, err) return } - mountPath := strings.TrimPrefix(core.MatchingMount(r.Context(), path), ns.Path) - - // Clone body, so we do not close the request body reader - bodyBytes, err := ioutil.ReadAll(r.Body) - if err != nil { - respondError(w, http.StatusInternalServerError, errors.New("failed to read request body")) - return - } - r.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes)) quotaResp, err := core.ApplyRateLimitQuota(r.Context(), "as.Request{ Type: quotas.TypeRateLimit, Path: path, - MountPath: mountPath, - Role: core.DetermineRoleFromLoginRequestFromBytes(mountPath, bodyBytes, r.Context()), + MountPath: strings.TrimPrefix(core.MatchingMount(r.Context(), path), ns.Path), NamespacePath: ns.Path, ClientAddress: parseRemoteIPAddress(r), }) diff --git a/make.bat b/make.bat index ca3238bc12e4c..d636b5b03b592 100644 --- a/make.bat +++ b/make.bat @@ -7,7 +7,7 @@ REM If no target is provided, default to test. if [%1]==[] goto test set _TARGETS=bin,bootstrap,dev,generate,test,testacc,testrace,vet -set _EXTERNAL_TOOLS=github.com/kardianos/govendor +set _EXTERNAL_TOOLS=github.com/mitchellh/gox,github.com/kardianos/govendor REM Run target. for %%a in (%_TARGETS%) do (if x%1==x%%a goto %%a) @@ -82,7 +82,7 @@ REM any common errors. go tool vet 2>nul if %ERRORLEVEL% equ 3 go get golang.org/x/tools/cmd/vet - + set _vetExitCode=0 set _VAULT_PKG_DIRS=%TEMP%\vault-pkg-dirs.txt diff --git a/physical/foundationdb/foundationdb.go b/physical/foundationdb/foundationdb.go index 56305b2fbf7df..e6fe596b081ae 100644 --- a/physical/foundationdb/foundationdb.go +++ b/physical/foundationdb/foundationdb.go @@ -122,8 +122,8 @@ func decoratePath(path string) ([]byte, error) { // Turn a decorated byte array back into a path string func undecoratePath(decoratedPath []byte) string { - ret := strings.ReplaceAll(string(decoratedPath), dirPathMarker, "/") - ret = strings.ReplaceAll(ret, dirEntryMarker, "/") + ret := strings.Replace(string(decoratedPath), dirPathMarker, "/", -1) + ret = strings.Replace(ret, dirEntryMarker, "/", -1) return strings.TrimLeft(ret, "/") } @@ -233,12 +233,12 @@ func NewFDBBackend(conf map[string]string, logger log.Logger) (physical.Backend, db, err := fdb.Open(fdbClusterFile, []byte("DB")) if err != nil { - return nil, fmt.Errorf("failed to open database with cluster file %q: %w", fdbClusterFile, err) + return nil, fmt.Errorf("failed to open database with cluster file '%s': %w", fdbClusterFile, err) } topDir, err := directory.CreateOrOpen(db, dirPath, nil) if err != nil { - return nil, fmt.Errorf("failed to create/open top-level directory %q: %w", path, err) + return nil, fmt.Errorf("failed to create/open top-level directory '%s': %w", path, err) } // Setup the backend diff --git a/physical/postgresql/postgresql.go b/physical/postgresql/postgresql.go index 7483999241d3d..b7b1d072baf77 100644 --- a/physical/postgresql/postgresql.go +++ b/physical/postgresql/postgresql.go @@ -244,7 +244,7 @@ func (m *PostgreSQLBackend) Put(ctx context.Context, entry *physical.Entry) erro parentPath, path, key := m.splitKey(entry.Key) - _, err := m.client.ExecContext(ctx, m.put_query, parentPath, path, key, entry.Value) + _, err := m.client.Exec(m.put_query, parentPath, path, key, entry.Value) if err != nil { return err } @@ -261,7 +261,7 @@ func (m *PostgreSQLBackend) Get(ctx context.Context, fullPath string) (*physical _, path, key := m.splitKey(fullPath) var result []byte - err := m.client.QueryRowContext(ctx, m.get_query, path, key).Scan(&result) + err := m.client.QueryRow(m.get_query, path, key).Scan(&result) if err == sql.ErrNoRows { return nil, nil } @@ -285,7 +285,7 @@ func (m *PostgreSQLBackend) Delete(ctx context.Context, fullPath string) error { _, path, key := m.splitKey(fullPath) - _, err := m.client.ExecContext(ctx, m.delete_query, path, key) + _, err := m.client.Exec(m.delete_query, path, key) if err != nil { return err } @@ -300,7 +300,7 @@ func (m *PostgreSQLBackend) List(ctx context.Context, prefix string) ([]string, m.permitPool.Acquire() defer m.permitPool.Release() - rows, err := m.client.QueryContext(ctx, m.list_query, "/"+prefix) + rows, err := m.client.Query(m.list_query, "/"+prefix) if err != nil { return nil, err } diff --git a/physical/postgresql/postgresql_test.go b/physical/postgresql/postgresql_test.go index 15d1ab35076d9..22476de55580c 100644 --- a/physical/postgresql/postgresql_test.go +++ b/physical/postgresql/postgresql_test.go @@ -106,7 +106,7 @@ func TestPostgreSQLBackendMaxIdleConnectionsParameter(t *testing.T) { } expectedErrStr := "failed parsing max_idle_connections parameter: strconv.Atoi: parsing \"bad param\": invalid syntax" if err.Error() != expectedErrStr { - t.Errorf("Expected: %q but found %q", expectedErrStr, err.Error()) + t.Errorf("Expected: \"%s\" but found \"%s\"", expectedErrStr, err.Error()) } } @@ -165,7 +165,7 @@ func TestConnectionURL(t *testing.T) { got := connectionURL(tt.input.conf) if got != tt.want { - t.Errorf("connectionURL(%s): want %q, got %q", tt.input, tt.want, got) + t.Errorf("connectionURL(%s): want '%s', got '%s'", tt.input, tt.want, got) } }) } diff --git a/physical/raft/bolt_linux.go b/physical/raft/bolt_linux.go index 4ea13e2a39860..03db74bc475c0 100644 --- a/physical/raft/bolt_linux.go +++ b/physical/raft/bolt_linux.go @@ -4,7 +4,7 @@ import ( "context" "os" - "github.com/shirou/gopsutil/v3/mem" + "github.com/shirou/gopsutil/mem" "golang.org/x/sys/unix" ) diff --git a/physical/raft/raft.go b/physical/raft/raft.go index 4114377134c63..21d6d93058494 100644 --- a/physical/raft/raft.go +++ b/physical/raft/raft.go @@ -250,7 +250,7 @@ func (b *RaftBackend) JoinConfig() ([]*LeaderJoinInfo, error) { } if info.AutoJoinScheme != "" && (info.AutoJoinScheme != "http" && info.AutoJoinScheme != "https") { - return nil, fmt.Errorf("invalid scheme %q; must either be http or https", info.AutoJoinScheme) + return nil, fmt.Errorf("invalid scheme '%s'; must either be http or https", info.AutoJoinScheme) } info.Retry = true diff --git a/physical/raft/types.pb.go b/physical/raft/types.pb.go index 470cabffcd610..5fca8f6c3e81d 100644 --- a/physical/raft/types.pb.go +++ b/physical/raft/types.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.0 +// protoc-gen-go v1.27.1 // protoc v3.19.4 // source: physical/raft/types.proto diff --git a/physical/spanner/spanner.go b/physical/spanner/spanner.go index 09634da53c8dd..8447ed9853a96 100644 --- a/physical/spanner/spanner.go +++ b/physical/spanner/spanner.go @@ -371,5 +371,5 @@ func sanitizeTable(s string) string { if end > -1 { s = s[:end] } - return strings.ReplaceAll(s, `"`, `""`) + return strings.Replace(s, `"`, `""`, -1) } diff --git a/physical/swift/swift_test.go b/physical/swift/swift_test.go index 0e569c5a9fae9..c385285437d17 100644 --- a/physical/swift/swift_test.go +++ b/physical/swift/swift_test.go @@ -50,7 +50,7 @@ func TestSwiftBackend(t *testing.T) { err = cleaner.ContainerCreate(container, nil) if nil != err { - t.Fatalf("Unable to create test container %q: %v", container, err) + t.Fatalf("Unable to create test container '%s': %v", container, err) } defer func() { newObjects, err := cleaner.ObjectNamesAll(container, nil) diff --git a/plugins/database/hana/hana.go b/plugins/database/hana/hana.go index bca437c369a69..7462a35063775 100644 --- a/plugins/database/hana/hana.go +++ b/plugins/database/hana/hana.go @@ -10,22 +10,19 @@ import ( "github.com/hashicorp/go-secure-stdlib/strutil" "github.com/hashicorp/vault/sdk/database/dbplugin/v5" "github.com/hashicorp/vault/sdk/database/helper/connutil" + "github.com/hashicorp/vault/sdk/database/helper/credsutil" "github.com/hashicorp/vault/sdk/database/helper/dbutil" "github.com/hashicorp/vault/sdk/helper/dbtxn" - "github.com/hashicorp/vault/sdk/helper/template" ) const ( - hanaTypeName = "hdb" - - defaultUserNameTemplate = `{{ printf "v_%s_%s_%s_%s" (.DisplayName | truncate 32) (.RoleName | truncate 20) (random 20) (unix_time) | truncate 127 | replace "-" "_" | uppercase }}` + hanaTypeName = "hdb" + maxIdentifierLength = 127 ) // HANA is an implementation of Database interface type HANA struct { *connutil.SQLConnectionProducer - - usernameProducer template.StringTemplate } var _ dbplugin.Database = (*HANA)(nil) @@ -60,25 +57,6 @@ func (h *HANA) Initialize(ctx context.Context, req dbplugin.InitializeRequest) ( return dbplugin.InitializeResponse{}, fmt.Errorf("error initializing db: %w", err) } - usernameTemplate, err := strutil.GetString(req.Config, "username_template") - if err != nil { - return dbplugin.InitializeResponse{}, fmt.Errorf("failed to retrieve username_template: %w", err) - } - if usernameTemplate == "" { - usernameTemplate = defaultUserNameTemplate - } - - up, err := template.NewTemplate(template.Template(usernameTemplate)) - if err != nil { - return dbplugin.InitializeResponse{}, fmt.Errorf("unable to initialize username template: %w", err) - } - h.usernameProducer = up - - _, err = h.usernameProducer.Generate(dbplugin.UsernameMetadata{}) - if err != nil { - return dbplugin.InitializeResponse{}, fmt.Errorf("invalid username template: %w", err) - } - return dbplugin.InitializeResponse{ Config: conf, }, nil @@ -116,13 +94,19 @@ func (h *HANA) NewUser(ctx context.Context, req dbplugin.NewUserRequest) (respon } // Generate username - username, err := h.usernameProducer.Generate(req.UsernameConfig) + username, err := credsutil.GenerateUsername( + credsutil.DisplayName(req.UsernameConfig.DisplayName, 32), + credsutil.RoleName(req.UsernameConfig.RoleName, 20), + credsutil.MaxLength(maxIdentifierLength), + credsutil.Separator("_"), + credsutil.ToUpper(), + ) if err != nil { return dbplugin.NewUserResponse{}, err } // HANA does not allow hyphens in usernames, and highly prefers capital letters - username = strings.ReplaceAll(username, "-", "_") + username = strings.Replace(username, "-", "_", -1) username = strings.ToUpper(username) // If expiration is in the role SQL, HANA will deactivate the user when time is up, diff --git a/plugins/database/hana/hana_test.go b/plugins/database/hana/hana_test.go index 67c1088834897..b38e93b459cb1 100644 --- a/plugins/database/hana/hana_test.go +++ b/plugins/database/hana/hana_test.go @@ -12,7 +12,6 @@ import ( "github.com/hashicorp/vault/sdk/database/dbplugin/v5" dbtesting "github.com/hashicorp/vault/sdk/database/dbplugin/v5/testing" - "github.com/stretchr/testify/require" ) func TestHANA_Initialize(t *testing.T) { @@ -179,7 +178,7 @@ func TestHANA_UpdateUser(t *testing.T) { if err == nil { t.Fatalf("Able to login with new creds when expecting an issue") } else if test.expectedErrMsg != "" && !strings.Contains(err.Error(), test.expectedErrMsg) { - t.Fatalf("Expected error message to contain %q, received: %s", test.expectedErrMsg, err) + t.Fatalf("Expected error message to contain \"%s\", received: %s", test.expectedErrMsg, err) } } if !test.expectErrOnLogin && err != nil { @@ -289,97 +288,6 @@ func copyConfig(config map[string]interface{}) map[string]interface{} { return newConfig } -func TestHANA_DefaultUsernameTemplate(t *testing.T) { - if os.Getenv("HANA_URL") == "" || os.Getenv("VAULT_ACC") != "1" { - t.SkipNow() - } - connURL := os.Getenv("HANA_URL") - - connectionDetails := map[string]interface{}{ - "connection_url": connURL, - } - - initReq := dbplugin.InitializeRequest{ - Config: connectionDetails, - VerifyConnection: true, - } - - db := new() - dbtesting.AssertInitialize(t, db, initReq) - - usernameConfig := dbplugin.UsernameMetadata{ - DisplayName: "test", - RoleName: "test", - } - - const password = "SuperSecurePa55w0rd!" - resp := dbtesting.AssertNewUser(t, db, dbplugin.NewUserRequest{ - UsernameConfig: usernameConfig, - Password: password, - Statements: dbplugin.Statements{ - Commands: []string{testHANARole}, - }, - Expiration: time.Now().Add(5 * time.Minute), - }) - username := resp.Username - - if resp.Username == "" { - t.Fatalf("Missing username") - } - - testCredsExist(t, connURL, username, password) - - require.Regexp(t, `^V_TEST_TEST_[A-Z0-9]{20}_[0-9]{10}$`, resp.Username) - - defer dbtesting.AssertClose(t, db) -} - -func TestHANA_CustomUsernameTemplate(t *testing.T) { - if os.Getenv("HANA_URL") == "" || os.Getenv("VAULT_ACC") != "1" { - t.SkipNow() - } - connURL := os.Getenv("HANA_URL") - - connectionDetails := map[string]interface{}{ - "connection_url": connURL, - "username_template": "{{.DisplayName}}_{{random 10}}", - } - - initReq := dbplugin.InitializeRequest{ - Config: connectionDetails, - VerifyConnection: true, - } - - db := new() - dbtesting.AssertInitialize(t, db, initReq) - - usernameConfig := dbplugin.UsernameMetadata{ - DisplayName: "test", - RoleName: "test", - } - - const password = "SuperSecurePa55w0rd!" - resp := dbtesting.AssertNewUser(t, db, dbplugin.NewUserRequest{ - UsernameConfig: usernameConfig, - Password: password, - Statements: dbplugin.Statements{ - Commands: []string{testHANARole}, - }, - Expiration: time.Now().Add(5 * time.Minute), - }) - username := resp.Username - - if resp.Username == "" { - t.Fatalf("Missing username") - } - - testCredsExist(t, connURL, username, password) - - require.Regexp(t, `^TEST_[A-Z0-9]{10}$`, resp.Username) - - defer dbtesting.AssertClose(t, db) -} - const testHANARole = ` CREATE USER {{name}} PASSWORD "{{password}}" NO FORCE_FIRST_PASSWORD_CHANGE VALID UNTIL '{{expiration}}';` diff --git a/plugins/database/mysql/mysql.go b/plugins/database/mysql/mysql.go index db47c71dd3108..1a992a30f1a55 100644 --- a/plugins/database/mysql/mysql.go +++ b/plugins/database/mysql/mysql.go @@ -16,7 +16,7 @@ import ( const ( defaultMysqlRevocationStmts = ` - REVOKE ALL PRIVILEGES, GRANT OPTION FROM '{{name}}'@'%'; + REVOKE ALL PRIVILEGES, GRANT OPTION FROM '{{name}}'@'%'; DROP USER '{{name}}'@'%' ` @@ -174,8 +174,8 @@ func (m *MySQL) DeleteUser(ctx context.Context, req dbplugin.DeleteUserRequest) // This is not a prepared statement because not all commands are supported // 1295: This command is not supported in the prepared statement protocol yet // Reference https://mariadb.com/kb/en/mariadb/prepare-statement/ - query = strings.ReplaceAll(query, "{{name}}", req.Username) - query = strings.ReplaceAll(query, "{{username}}", req.Username) + query = strings.Replace(query, "{{name}}", req.Username, -1) + query = strings.Replace(query, "{{username}}", req.Username, -1) _, err = tx.ExecContext(ctx, query) if err != nil { return dbplugin.DeleteUserResponse{}, err diff --git a/plugins/database/postgresql/postgresql.go b/plugins/database/postgresql/postgresql.go index b46813727be69..359e7ca886883 100644 --- a/plugins/database/postgresql/postgresql.go +++ b/plugins/database/postgresql/postgresql.go @@ -482,7 +482,7 @@ func containsMultilineStatement(stmt string) bool { } stmtWithoutLiterals := stmt for _, literal := range literals { - stmtWithoutLiterals = strings.ReplaceAll(stmt, literal, "") + stmtWithoutLiterals = strings.Replace(stmt, literal, "", -1) } // Now look for the word "END" specifically. This will miss any // representations of END that aren't surrounded by spaces, but diff --git a/scripts/build.sh b/scripts/build.sh index b2e1302cb4aec..14261537a52f7 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -23,6 +23,21 @@ GIT_DIRTY="$(test -n "`git status --porcelain`" && echo "+CHANGES" || true)" BUILD_DATE=$("$SOURCE_DIR"/build_date.sh) +# If its dev mode, only build for ourself +if [ "${VAULT_DEV_BUILD}x" != "x" ] && [ "${XC_OSARCH}x" == "x" ]; then + XC_OS=$(${GO_CMD} env GOOS) + XC_ARCH=$(${GO_CMD} env GOARCH) + XC_OSARCH=$(${GO_CMD} env GOOS)/$(${GO_CMD} env GOARCH) +elif [ "${XC_OSARCH}x" != "x" ]; then + IFS='/' read -ra SPLITXC <<< "${XC_OSARCH}" + DEV_PLATFORM="./pkg/${SPLITXC[0]}_${SPLITXC[1]}" +fi + +# Determine the arch/os combos we're building for +XC_ARCH=${XC_ARCH:-"386 amd64"} +XC_OS=${XC_OS:-linux darwin windows freebsd openbsd netbsd solaris} +XC_OSARCH=${XC_OSARCH:-"linux/386 linux/amd64 linux/arm linux/arm64 darwin/386 darwin/amd64 darwin/arm64 windows/386 windows/amd64 freebsd/386 freebsd/amd64 freebsd/arm openbsd/386 openbsd/amd64 openbsd/arm netbsd/386 netbsd/amd64 solaris/amd64"} + GOPATH=${GOPATH:-$(${GO_CMD} env GOPATH)} case $(uname) in CYGWIN*) @@ -37,12 +52,16 @@ rm -rf pkg/* mkdir -p bin/ # Build! +# If GOX_PARALLEL_BUILDS is set, it will be used to add a "-parallel=${GOX_PARALLEL_BUILDS}" gox parameter echo "==> Building..." -${GO_CMD} build \ +gox \ + -osarch="${XC_OSARCH}" \ -gcflags "${GCFLAGS}" \ - -ldflags "${LD_FLAGS} -X github.com/hashicorp/vault/sdk/version.GitCommit='${GIT_COMMIT}${GIT_DIRTY}' -X github.com/hashicorp/vault/sdk/version.BuildDate=${BUILD_DATE}" \ - -o "bin/vault" \ - -tags "${BUILD_TAGS}" \ + -ldflags "${LD_FLAGS}-X github.com/hashicorp/vault/sdk/version.GitCommit='${GIT_COMMIT}${GIT_DIRTY}' -X github.com/hashicorp/vault/sdk/version.BuildDate=${BUILD_DATE}" \ + -output "pkg/{{.OS}}_{{.Arch}}/vault" \ + ${GOX_PARALLEL_BUILDS+-parallel="${GOX_PARALLEL_BUILDS}"} \ + -tags="${BUILD_TAGS}" \ + -gocmd="${GO_CMD}" \ . # Move all the compiled things to the $GOPATH/bin @@ -50,8 +69,26 @@ OLDIFS=$IFS IFS=: MAIN_GOPATH=($GOPATH) IFS=$OLDIFS -rm -f ${MAIN_GOPATH}/bin/vault -cp bin/vault ${MAIN_GOPATH}/bin/ +# Copy our OS/Arch to the bin/ directory +DEV_PLATFORM=${DEV_PLATFORM:-"./pkg/$(${GO_CMD} env GOOS)_$(${GO_CMD} env GOARCH)"} +for F in $(find ${DEV_PLATFORM} -mindepth 1 -maxdepth 1 -type f); do + cp ${F} bin/ + rm -f ${MAIN_GOPATH}/bin/vault + cp ${F} ${MAIN_GOPATH}/bin/ +done + +if [ "${VAULT_DEV_BUILD}x" = "x" ]; then + # Zip and copy to the dist dir + echo "==> Packaging..." + for PLATFORM in $(find ./pkg -mindepth 1 -maxdepth 1 -type d); do + OSARCH=$(basename ${PLATFORM}) + echo "--> ${OSARCH}" + + pushd $PLATFORM >/dev/null 2>&1 + zip ../${OSARCH}.zip ./* + popd >/dev/null 2>&1 + done +fi # Done! echo diff --git a/scripts/cross/Dockerfile b/scripts/cross/Dockerfile index 504399c3ff386..220982a6f3976 100644 --- a/scripts/cross/Dockerfile +++ b/scripts/cross/Dockerfile @@ -31,6 +31,7 @@ ENV GOROOT /goroot ENV PATH $GOROOT/bin:$GOPATH/bin:$PATH RUN go get golang.org/x/tools/cmd/goimports +RUN go get github.com/mitchellh/gox RUN mkdir -p /gopath/src/github.com/hashicorp/vault WORKDIR /gopath/src/github.com/hashicorp/vault diff --git a/scripts/docker/Dockerfile b/scripts/docker/Dockerfile index 5a29c49314aed..e408df085093d 100644 --- a/scripts/docker/Dockerfile +++ b/scripts/docker/Dockerfile @@ -1,6 +1,7 @@ # Multi-stage builder to avoid polluting users environment with wrong -# architecture binaries. -ARG VERSION=1.18.4 +# architecture binaries. Since this binary is used in an alpine container, +# we're explicitly compiling for 'linux/amd64' +ARG VERSION=1.17.12 FROM golang:${VERSION} AS builder @@ -11,7 +12,7 @@ WORKDIR /go/src/github.com/hashicorp/vault COPY . . RUN make bootstrap \ - && CGO_ENABLED=$CGO_ENABLED BUILD_TAGS="${BUILD_TAGS}" VAULT_DEV_BUILD=1 sh -c "'./scripts/build.sh'" + && CGO_ENABLED=$CGO_ENABLED BUILD_TAGS="${BUILD_TAGS}" VAULT_DEV_BUILD=1 XC_OSARCH='linux/amd64' sh -c "'./scripts/build.sh'" # Docker Image @@ -26,7 +27,7 @@ RUN addgroup vault && \ RUN set -eux; \ apk add --no-cache ca-certificates libcap su-exec dumb-init tzdata -COPY --from=builder /go/src/github.com/hashicorp/vault/bin/vault /bin/vault +COPY --from=builder /go/bin/vault /bin/vault # /vault/logs is made available to use as a location to store audit logs, if # desired; /vault/file is made available to use as a location with the file diff --git a/scripts/docker/Dockerfile.ui b/scripts/docker/Dockerfile.ui index 595af6a3d5c2a..4163ffbbed61d 100644 --- a/scripts/docker/Dockerfile.ui +++ b/scripts/docker/Dockerfile.ui @@ -1,8 +1,9 @@ # Multi-stage builder to avoid polluting users environment with wrong -# architecture binaries. This file only currently works for linux/amd64. +# architecture binaries. Since this binary is used in an alpine container, +# we're explicitly compiling for 'linux/amd64' FROM debian:buster AS builder -ARG VERSION=1.18.4 +ARG VERSION=1.17.12 ARG CGO_ENABLED=0 ARG BUILD_TAGS ENV JOBS=2 @@ -37,7 +38,7 @@ ENV PATH $GOROOT/bin:$GOPATH/bin:$PATH WORKDIR /go/src/github.com/hashicorp/vault COPY . . RUN make bootstrap static-dist \ - && CGO_ENABLED=$CGO_ENABLED BUILD_TAGS="${BUILD_TAGS} ui" VAULT_DEV_BUILD=1 GOOS=linux GOARCH=amd64 sh -c "'./scripts/build.sh'" + && CGO_ENABLED=$CGO_ENABLED BUILD_TAGS="${BUILD_TAGS} ui" VAULT_DEV_BUILD=1 XC_OSARCH='linux/amd64' sh -c "'./scripts/build.sh'" # Docker Image @@ -52,7 +53,7 @@ RUN addgroup vault && \ RUN set -eux; \ apk add --no-cache ca-certificates libcap su-exec dumb-init tzdata -COPY --from=builder /go/src/github.com/hashicorp/vault/bin/vault /bin/vault +COPY --from=builder /go/bin/vault /bin/vault # /vault/logs is made available to use as a location to store audit logs, if # desired; /vault/file is made available to use as a location with the file diff --git a/scripts/windows/build.bat b/scripts/windows/build.bat index 1452911e514a7..3b4ee3a4c616b 100644 --- a/scripts/windows/build.bat +++ b/scripts/windows/build.bat @@ -62,9 +62,11 @@ del /f "%_GO_ENV_TMP_FILE%" 2>nul :build REM Build! echo ==^> Building... -go build^ +gox^ + -os="%_XC_OS%"^ + -arch="%_XC_ARCH%"^ -ldflags "-X github.com/hashicorp/vault/sdk/version.GitCommit=%_GIT_COMMIT%%_GIT_DIRTY% -X github.com/hashicorp/vault/sdk/version.BuildDate=%_BUILD_DATE%"^ - -o "bin/vault.exe"^ + -output "pkg/{{.OS}}_{{.Arch}}/vault"^ . if %ERRORLEVEL% equ 1 set %_EXITCODE%=1 @@ -85,6 +87,14 @@ go env GOOS >"%_GO_ENV_TMP_FILE%" set /p _GOOS=<"%_GO_ENV_TMP_FILE%" del /f "%_GO_ENV_TMP_FILE%" 2>nul +REM Copy our OS/Arch to the bin/ directory +set _DEV_PLATFORM=pkg\%_GOOS%_%_GOARCH% + +for /r %%f in (%_DEV_PLATFORM%) do ( + copy /b /y %%f bin\ >nul + copy /b /y %%f %_GOPATH%\bin\ >nul +) + REM TODO(ceh): package dist REM Done! diff --git a/sdk/database/dbplugin/database.pb.go b/sdk/database/dbplugin/database.pb.go index 524ddc05e0386..7c9e08a9b03eb 100644 --- a/sdk/database/dbplugin/database.pb.go +++ b/sdk/database/dbplugin/database.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.0 +// protoc-gen-go v1.27.1 // protoc v3.19.4 // source: sdk/database/dbplugin/database.proto diff --git a/sdk/database/dbplugin/databasemiddleware.go b/sdk/database/dbplugin/databasemiddleware.go index 29c806113844b..e7cb0a2f5af12 100644 --- a/sdk/database/dbplugin/databasemiddleware.go +++ b/sdk/database/dbplugin/databasemiddleware.go @@ -323,11 +323,11 @@ func (mw *DatabaseErrorSanitizerMiddleware) sanitize(err error) error { // error without changing the actual error message s, ok := status.FromError(err) if ok { - err = status.Error(s.Code(), strings.ReplaceAll(s.Message(), k, v.(string))) + err = status.Error(s.Code(), strings.Replace(s.Message(), k, v.(string), -1)) continue } - err = errors.New(strings.ReplaceAll(err.Error(), k, v.(string))) + err = errors.New(strings.Replace(err.Error(), k, v.(string), -1)) } } return err diff --git a/sdk/database/dbplugin/v5/middleware.go b/sdk/database/dbplugin/v5/middleware.go index 164094efecd1d..20b4212060299 100644 --- a/sdk/database/dbplugin/v5/middleware.go +++ b/sdk/database/dbplugin/v5/middleware.go @@ -264,11 +264,11 @@ func (mw DatabaseErrorSanitizerMiddleware) sanitize(err error) error { // error while changing the actual error message s, ok := status.FromError(err) if ok { - err = status.Error(s.Code(), strings.ReplaceAll(s.Message(), find, replace)) + err = status.Error(s.Code(), strings.Replace(s.Message(), find, replace, -1)) continue } - err = errors.New(strings.ReplaceAll(err.Error(), find, replace)) + err = errors.New(strings.Replace(err.Error(), find, replace, -1)) } return err } diff --git a/sdk/database/dbplugin/v5/proto/database.pb.go b/sdk/database/dbplugin/v5/proto/database.pb.go index b2010276bca70..a5f52dab999d5 100644 --- a/sdk/database/dbplugin/v5/proto/database.pb.go +++ b/sdk/database/dbplugin/v5/proto/database.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.0 +// protoc-gen-go v1.27.1 // protoc v3.19.4 // source: sdk/database/dbplugin/v5/proto/database.proto diff --git a/sdk/database/helper/dbutil/dbutil.go b/sdk/database/helper/dbutil/dbutil.go index 19198bcfdddd7..84b98d1889679 100644 --- a/sdk/database/helper/dbutil/dbutil.go +++ b/sdk/database/helper/dbutil/dbutil.go @@ -18,7 +18,7 @@ var ( // Query templates a query for us. func QueryHelper(tpl string, data map[string]string) string { for k, v := range data { - tpl = strings.ReplaceAll(tpl, fmt.Sprintf("{{%s}}", k), v) + tpl = strings.Replace(tpl, fmt.Sprintf("{{%s}}", k), v, -1) } return tpl diff --git a/sdk/database/helper/dbutil/quoteidentifier.go b/sdk/database/helper/dbutil/quoteidentifier.go index cc54154a03724..dc63abbe67fd8 100644 --- a/sdk/database/helper/dbutil/quoteidentifier.go +++ b/sdk/database/helper/dbutil/quoteidentifier.go @@ -41,5 +41,5 @@ func QuoteIdentifier(name string) string { if end > -1 { name = name[:end] } - return `"` + strings.ReplaceAll(name, `"`, `""`) + `"` + return `"` + strings.Replace(name, `"`, `""`, -1) + `"` } diff --git a/sdk/framework/backend.go b/sdk/framework/backend.go index 0efb798b9adbe..28071e5acdff7 100644 --- a/sdk/framework/backend.go +++ b/sdk/framework/backend.go @@ -528,16 +528,9 @@ func (b *Backend) handleRootHelp(req *logical.Request) (*logical.Response, error // names in the OAS document. requestResponsePrefix := req.GetString("requestResponsePrefix") - // Generic mount paths will primarily be used for code generation purposes. - // This will result in dynamic mount paths being placed instead of - // hardcoded default paths. For example /auth/approle/login would be replaced - // with /auth/{mountPath}/login. This will be replaced for all secrets - // engines and auth methods that are enabled. - genericMountPaths, _ := req.Get("genericMountPaths").(bool) - // Build OpenAPI response for the entire backend doc := NewOASDocument() - if err := documentPaths(b, requestResponsePrefix, genericMountPaths, doc); err != nil { + if err := documentPaths(b, requestResponsePrefix, doc); err != nil { b.Logger().Warn("error generating OpenAPI", "error", err) } diff --git a/sdk/framework/openapi.go b/sdk/framework/openapi.go index 6d720e222f7d1..2c3377f502d59 100644 --- a/sdk/framework/openapi.go +++ b/sdk/framework/openapi.go @@ -213,9 +213,9 @@ var ( ) // documentPaths parses all paths in a framework.Backend into OpenAPI paths. -func documentPaths(backend *Backend, requestResponsePrefix string, genericMountPaths bool, doc *OASDocument) error { +func documentPaths(backend *Backend, requestResponsePrefix string, doc *OASDocument) error { for _, p := range backend.Paths { - if err := documentPath(p, backend.SpecialPaths(), requestResponsePrefix, genericMountPaths, backend.BackendType, doc); err != nil { + if err := documentPath(p, backend.SpecialPaths(), requestResponsePrefix, backend.BackendType, doc); err != nil { return err } } @@ -224,7 +224,7 @@ func documentPaths(backend *Backend, requestResponsePrefix string, genericMountP } // documentPath parses a framework.Path into one or more OpenAPI paths. -func documentPath(p *Path, specialPaths *logical.Paths, requestResponsePrefix string, genericMountPaths bool, backendType logical.BackendType, doc *OASDocument) error { +func documentPath(p *Path, specialPaths *logical.Paths, requestResponsePrefix string, backendType logical.BackendType, doc *OASDocument) error { var sudoPaths []string var unauthPaths []string @@ -263,21 +263,6 @@ func documentPath(p *Path, specialPaths *logical.Paths, requestResponsePrefix st // Body fields will be added to individual operations. pathFields, bodyFields := splitFields(p.Fields, path) - if genericMountPaths && requestResponsePrefix != "system" && requestResponsePrefix != "identity" { - // Add mount path as a parameter - p := OASParameter{ - Name: "mountPath", - Description: "Path that the backend was mounted at", - In: "path", - Schema: &OASSchema{ - Type: "string", - }, - Required: true, - } - - pi.Parameters = append(pi.Parameters, p) - } - for name, field := range pathFields { location := "path" required := true @@ -553,7 +538,7 @@ func expandPattern(pattern string) []string { if start != -1 && end != -1 && end > start { regexToRemove = base[start+1 : end] } - pattern = strings.ReplaceAll(pattern, regexToRemove, "") + pattern = strings.Replace(pattern, regexToRemove, "", -1) // Simplify named fields that have limited options, e.g. (?Pa|b|c) -> (.+) pattern = altFieldsGroupRe.ReplaceAllStringFunc(pattern, func(s string) string { @@ -767,7 +752,7 @@ func (d *OASDocument) CreateOperationIDs(context string) { // Space-split on non-words, title case everything, recombine opID := nonWordRe.ReplaceAllString(strings.ToLower(path), " ") opID = strings.Title(opID) - opID = method + strings.ReplaceAll(opID, " ", "") + opID = method + strings.Replace(opID, " ", "", -1) // deduplicate operationIds. This is a safeguard, since generated IDs should // already be unique given our current path naming conventions. diff --git a/sdk/framework/openapi_test.go b/sdk/framework/openapi_test.go index 8d3ecfea018b4..592406d9fb722 100644 --- a/sdk/framework/openapi_test.go +++ b/sdk/framework/openapi_test.go @@ -271,7 +271,7 @@ func TestOpenAPI_SpecialPaths(t *testing.T) { Root: test.rootPaths, Unauthenticated: test.unauthPaths, } - err := documentPath(&path, sp, "kv", false, logical.TypeLogical, doc) + err := documentPath(&path, sp, "kv", logical.TypeLogical, doc) if err != nil { t.Fatal(err) } @@ -519,11 +519,11 @@ func TestOpenAPI_OperationID(t *testing.T) { for _, context := range []string{"", "bar"} { doc := NewOASDocument() - err := documentPath(path1, nil, "kv", false, logical.TypeLogical, doc) + err := documentPath(path1, nil, "kv", logical.TypeLogical, doc) if err != nil { t.Fatal(err) } - err = documentPath(path2, nil, "kv", false, logical.TypeLogical, doc) + err = documentPath(path2, nil, "kv", logical.TypeLogical, doc) if err != nil { t.Fatal(err) } @@ -583,7 +583,7 @@ func TestOpenAPI_CustomDecoder(t *testing.T) { } docOrig := NewOASDocument() - err := documentPath(p, nil, "kv", false, logical.TypeLogical, docOrig) + err := documentPath(p, nil, "kv", logical.TypeLogical, docOrig) if err != nil { t.Fatal(err) } @@ -646,7 +646,7 @@ func testPath(t *testing.T, path *Path, sp *logical.Paths, expectedJSON string) t.Helper() doc := NewOASDocument() - if err := documentPath(path, sp, "kv", false, logical.TypeLogical, doc); err != nil { + if err := documentPath(path, sp, "kv", logical.TypeLogical, doc); err != nil { t.Fatal(err) } doc.CreateOperationIDs("") diff --git a/sdk/framework/path.go b/sdk/framework/path.go index 07ce84c97c4dc..b316d2cc1577b 100644 --- a/sdk/framework/path.go +++ b/sdk/framework/path.go @@ -311,7 +311,7 @@ func (p *Path) helpCallback(b *Backend) OperationFunc { // Build OpenAPI response for this path doc := NewOASDocument() - if err := documentPath(p, b.SpecialPaths(), requestResponsePrefix, false, b.BackendType, doc); err != nil { + if err := documentPath(p, b.SpecialPaths(), requestResponsePrefix, b.BackendType, doc); err != nil { b.Logger().Warn("error generating OpenAPI", "error", err) } diff --git a/sdk/helper/certutil/helpers.go b/sdk/helper/certutil/helpers.go index b69eb36aa1472..457de9b022cc0 100644 --- a/sdk/helper/certutil/helpers.go +++ b/sdk/helper/certutil/helpers.go @@ -49,21 +49,6 @@ var expectedNISTPCurveHashBits = map[int]int{ 521: 512, } -// Mapping of constant names<->constant values for SignatureAlgorithm -var SignatureAlgorithmNames = map[string]x509.SignatureAlgorithm{ - "sha256withrsa": x509.SHA256WithRSA, - "sha384withrsa": x509.SHA384WithRSA, - "sha512withrsa": x509.SHA512WithRSA, - "ecdsawithsha256": x509.ECDSAWithSHA256, - "ecdsawithsha384": x509.ECDSAWithSHA384, - "ecdsawithsha512": x509.ECDSAWithSHA512, - "sha256withrsapss": x509.SHA256WithRSAPSS, - "sha384withrsapss": x509.SHA384WithRSAPSS, - "sha512withrsapss": x509.SHA512WithRSAPSS, - "pureed25519": x509.PureEd25519, - "ed25519": x509.PureEd25519, // Duplicated for clarity; most won't expect the "Pure" prefix. -} - // GetHexFormatted returns the byte buffer formatted in hex with // the specified separator between bytes. func GetHexFormatted(buf []byte, sep string) string { @@ -102,16 +87,6 @@ func GetSubjKeyID(privateKey crypto.Signer) ([]byte, error) { return getSubjectKeyID(privateKey.Public()) } -// Returns the explicit SKID when used for cross-signing, else computes a new -// SKID from the key itself. -func getSubjectKeyIDFromBundle(data *CreationBundle) ([]byte, error) { - if len(data.Params.SKID) > 0 { - return data.Params.SKID, nil - } - - return getSubjectKeyID(data.CSR.PublicKey) -} - func getSubjectKeyID(pub interface{}) ([]byte, error) { var publicKeyBytes []byte switch pub := pub.(type) { @@ -781,29 +756,6 @@ func CreateCertificateWithKeyGenerator(data *CreationBundle, randReader io.Reade return createCertificate(data, randReader, keyGenerator) } -// Set correct correct RSA sig algo -func certTemplateSetSigAlgo(certTemplate *x509.Certificate, data *CreationBundle) { - if data.Params.UsePSS { - switch data.Params.SignatureBits { - case 256: - certTemplate.SignatureAlgorithm = x509.SHA256WithRSAPSS - case 384: - certTemplate.SignatureAlgorithm = x509.SHA384WithRSAPSS - case 512: - certTemplate.SignatureAlgorithm = x509.SHA512WithRSAPSS - } - } else { - switch data.Params.SignatureBits { - case 256: - certTemplate.SignatureAlgorithm = x509.SHA256WithRSA - case 384: - certTemplate.SignatureAlgorithm = x509.SHA384WithRSA - case 512: - certTemplate.SignatureAlgorithm = x509.SHA512WithRSA - } - } -} - func createCertificate(data *CreationBundle, randReader io.Reader, privateKeyGenerator KeyGenerator) (*ParsedCertBundle, error) { var err error result := &ParsedCertBundle{} @@ -872,7 +824,14 @@ func createCertificate(data *CreationBundle, randReader io.Reader, privateKeyGen if data.SigningBundle != nil { switch data.SigningBundle.PrivateKeyType { case RSAPrivateKey: - certTemplateSetSigAlgo(certTemplate, data) + switch data.Params.SignatureBits { + case 256: + certTemplate.SignatureAlgorithm = x509.SHA256WithRSA + case 384: + certTemplate.SignatureAlgorithm = x509.SHA384WithRSA + case 512: + certTemplate.SignatureAlgorithm = x509.SHA512WithRSA + } case Ed25519PrivateKey: certTemplate.SignatureAlgorithm = x509.PureEd25519 case ECPrivateKey: @@ -894,7 +853,14 @@ func createCertificate(data *CreationBundle, randReader io.Reader, privateKeyGen switch data.Params.KeyType { case "rsa": - certTemplateSetSigAlgo(certTemplate, data) + switch data.Params.SignatureBits { + case 256: + certTemplate.SignatureAlgorithm = x509.SHA256WithRSA + case 384: + certTemplate.SignatureAlgorithm = x509.SHA384WithRSA + case 512: + certTemplate.SignatureAlgorithm = x509.SHA512WithRSA + } case "ed25519": certTemplate.SignatureAlgorithm = x509.PureEd25519 case "ec": @@ -1100,7 +1066,7 @@ func signCertificate(data *CreationBundle, randReader io.Reader) (*ParsedCertBun return nil, err } - subjKeyID, err := getSubjectKeyIDFromBundle(data) + subjKeyID, err := getSubjectKeyID(data.CSR.PublicKey) if err != nil { return nil, err } @@ -1121,7 +1087,14 @@ func signCertificate(data *CreationBundle, randReader io.Reader) (*ParsedCertBun switch data.SigningBundle.PrivateKeyType { case RSAPrivateKey: - certTemplateSetSigAlgo(certTemplate, data) + switch data.Params.SignatureBits { + case 256: + certTemplate.SignatureAlgorithm = x509.SHA256WithRSA + case 384: + certTemplate.SignatureAlgorithm = x509.SHA384WithRSA + case 512: + certTemplate.SignatureAlgorithm = x509.SHA512WithRSA + } case ECPrivateKey: switch data.Params.SignatureBits { case 256: diff --git a/sdk/helper/certutil/types.go b/sdk/helper/certutil/types.go index 03aba84996b17..a5caa2e4409fd 100644 --- a/sdk/helper/certutil/types.go +++ b/sdk/helper/certutil/types.go @@ -710,7 +710,6 @@ type CAInfoBundle struct { ParsedCertBundle URLs *URLEntries LeafNotAfterBehavior NotAfterBehavior - RevocationSigAlg x509.SignatureAlgorithm } func (b *CAInfoBundle) GetCAChain() []*CertBlock { @@ -783,7 +782,6 @@ type CreationParameters struct { PolicyIdentifiers []string BasicConstraintsValidForNonCA bool SignatureBits int - UsePSS bool ForceAppendCaChain bool // Only used when signing a CA cert @@ -798,9 +796,6 @@ type CreationParameters struct { // The duration the certificate will use NotBefore NotBeforeDuration time.Duration - - // The explicit SKID to use; especially useful for cross-signing. - SKID []byte } type CreationBundle struct { diff --git a/sdk/helper/custommetadata/custom_metadata.go b/sdk/helper/custommetadata/custom_metadata.go deleted file mode 100644 index 7d4ff8763d116..0000000000000 --- a/sdk/helper/custommetadata/custom_metadata.go +++ /dev/null @@ -1,103 +0,0 @@ -package custommetadata - -import ( - "fmt" - - "github.com/mitchellh/mapstructure" - - "github.com/hashicorp/go-multierror" - "github.com/hashicorp/go-secure-stdlib/strutil" -) - -// The following constants are used by Validate and are meant to be imposed -// broadly for consistency. -const ( - maxKeys = 64 - maxKeyLength = 128 - maxValueLength = 512 - validationErrorPrefix = "custom_metadata validation failed" -) - -// Parse is used to effectively convert the TypeMap -// (map[string]interface{}) into a TypeKVPairs (map[string]string) -// which is how custom_metadata is stored. Defining custom_metadata -// as a TypeKVPairs will convert nulls into empty strings. A null, -// however, is essential for a PATCH operation in that it signals -// the handler to remove the field. The filterNils flag should -// only be used during a patch operation. -func Parse(raw map[string]interface{}, filterNils bool) (map[string]string, error) { - customMetadata := map[string]string{} - for k, v := range raw { - if filterNils && v == nil { - continue - } - - var s string - if err := mapstructure.WeakDecode(v, &s); err != nil { - return nil, err - } - - customMetadata[k] = s - } - - return customMetadata, nil -} - -// Validate will perform input validation for custom metadata. -// CustomMetadata should be arbitrary user-provided key-value pairs meant to -// provide supplemental information about a resource. If the key count -// exceeds maxKeys, the validation will be short-circuited to prevent -// unnecessary (and potentially costly) validation to be run. If the key count -// falls at or below maxKeys, multiple checks will be made per key and value. -// These checks include: -// - 0 < length of key <= maxKeyLength -// - 0 < length of value <= maxValueLength -// - keys and values cannot include unprintable characters -func Validate(cm map[string]string) error { - var errs *multierror.Error - - if keyCount := len(cm); keyCount > maxKeys { - errs = multierror.Append(errs, fmt.Errorf("%s: payload must contain at most %d keys, provided %d", - validationErrorPrefix, - maxKeys, - keyCount)) - - return errs.ErrorOrNil() - } - - // Perform validation on each key and value and return ALL errors - for key, value := range cm { - if keyLen := len(key); 0 == keyLen || keyLen > maxKeyLength { - errs = multierror.Append(errs, fmt.Errorf("%s: length of key %q is %d but must be 0 < len(key) <= %d", - validationErrorPrefix, - key, - keyLen, - maxKeyLength)) - } - - if valueLen := len(value); 0 == valueLen || valueLen > maxValueLength { - errs = multierror.Append(errs, fmt.Errorf("%s: length of value for key %q is %d but must be 0 < len(value) <= %d", - validationErrorPrefix, - key, - valueLen, - maxValueLength)) - } - - if !strutil.Printable(key) { - // Include unquoted format (%s) to also include the string without the unprintable - // characters visible to allow for easier debug and key identification - errs = multierror.Append(errs, fmt.Errorf("%s: key %q (%s) contains unprintable characters", - validationErrorPrefix, - key, - key)) - } - - if !strutil.Printable(value) { - errs = multierror.Append(errs, fmt.Errorf("%s: value for key %q contains unprintable characters", - validationErrorPrefix, - key)) - } - } - - return errs.ErrorOrNil() -} diff --git a/sdk/helper/custommetadata/custom_metadata_test.go b/sdk/helper/custommetadata/custom_metadata_test.go deleted file mode 100644 index e71bd59462fed..0000000000000 --- a/sdk/helper/custommetadata/custom_metadata_test.go +++ /dev/null @@ -1,85 +0,0 @@ -package custommetadata - -import ( - "strconv" - "strings" - "testing" -) - -func TestValidate(t *testing.T) { - cases := []struct { - name string - input map[string]string - shouldPass bool - }{ - { - "valid", - map[string]string{ - "foo": "abc", - "bar": "def", - "baz": "ghi", - }, - true, - }, - { - "too_many_keys", - func() map[string]string { - cm := make(map[string]string) - - for i := 0; i < maxKeyLength+1; i++ { - s := strconv.Itoa(i) - cm[s] = s - } - - return cm - }(), - false, - }, - { - "key_too_long", - map[string]string{ - strings.Repeat("a", maxKeyLength+1): "abc", - }, - false, - }, - { - "value_too_long", - map[string]string{ - "foo": strings.Repeat("a", maxValueLength+1), - }, - false, - }, - { - "unprintable_key", - map[string]string{ - "unprint\u200bable": "abc", - }, - false, - }, - { - "unprintable_value", - map[string]string{ - "foo": "unprint\u200bable", - }, - false, - }, - } - - for _, tc := range cases { - tc := tc - - t.Run(tc.name, func(t *testing.T) { - t.Parallel() - - err := Validate(tc.input) - - if tc.shouldPass && err != nil { - t.Fatalf("expected validation to pass, input: %#v, err: %v", tc.input, err) - } - - if !tc.shouldPass && err == nil { - t.Fatalf("expected validation to fail, input: %#v, err: %v", tc.input, err) - } - }) - } -} diff --git a/sdk/helper/dbtxn/dbtxn.go b/sdk/helper/dbtxn/dbtxn.go index 133b360e73e82..a5c8bf961e37a 100644 --- a/sdk/helper/dbtxn/dbtxn.go +++ b/sdk/helper/dbtxn/dbtxn.go @@ -77,7 +77,7 @@ func parseQuery(m map[string]string, tpl string) string { } for k, v := range m { - tpl = strings.ReplaceAll(tpl, fmt.Sprintf("{{%s}}", k), v) + tpl = strings.Replace(tpl, fmt.Sprintf("{{%s}}", k), v, -1) } return tpl } diff --git a/sdk/helper/keysutil/policy.go b/sdk/helper/keysutil/policy.go index 3d5641ff43c39..59029756d2e17 100644 --- a/sdk/helper/keysutil/policy.go +++ b/sdk/helper/keysutil/policy.go @@ -1355,14 +1355,7 @@ func (p *Policy) VerifySignature(context, input []byte, hashAlgorithm HashType, return false, errutil.InternalError{Err: fmt.Sprintf("unsupported rsa signature algorithm %s", sigAlgorithm)} } - if err != nil { - // Don't send back verification errors to caller, only misuse errors. - if errors.Is(err, rsa.ErrVerification) { - return false, nil - } - return false, errutil.InternalError{Err: err.Error()} - } - return true, nil + return err == nil, nil default: return false, errutil.InternalError{Err: fmt.Sprintf("unsupported key type %v", p.Type)} @@ -1392,17 +1385,7 @@ func (p *Policy) Import(ctx context.Context, storage logical.Storage, key []byte } else { parsedPrivateKey, err := x509.ParsePKCS8PrivateKey(key) if err != nil { - if strings.Contains(err.Error(), "unknown elliptic curve") { - var edErr error - parsedPrivateKey, edErr = ParsePKCS8Ed25519PrivateKey(key) - if edErr != nil { - return fmt.Errorf("error parsing asymmetric key:\n - assuming contents are an ed25519 private key: %s\n - original error: %v", edErr, err) - } - - // Parsing as Ed25519-in-PKCS8-ECPrivateKey succeeded! - } else { - return fmt.Errorf("error parsing asymmetric key: %s", err) - } + return fmt.Errorf("error parsing asymmetric key: %s", err) } switch parsedPrivateKey.(type) { @@ -1723,7 +1706,7 @@ func (p *Policy) getVersionPrefix(ver int) string { template = DefaultVersionTemplate } - prefix := strings.ReplaceAll(template, "{{version}}", strconv.Itoa(ver)) + prefix := strings.Replace(template, "{{version}}", strconv.Itoa(ver), -1) p.versionPrefixCache.Store(ver, prefix) return prefix diff --git a/sdk/helper/keysutil/policy_test.go b/sdk/helper/keysutil/policy_test.go index f9a4362b6e883..a2d9206a8acae 100644 --- a/sdk/helper/keysutil/policy_test.go +++ b/sdk/helper/keysutil/policy_test.go @@ -3,7 +3,6 @@ package keysutil import ( "bytes" "context" - "crypto" "crypto/ecdsa" "crypto/elliptic" "crypto/rand" @@ -622,67 +621,6 @@ func Test_BadArchive(t *testing.T) { } } -func Test_RSAVerificationErrors(t *testing.T) { - ctx := context.Background() - lm, _ := NewLockManager(true, 0) - storage := &logical.InmemStorage{} - p, _, err := lm.GetPolicy(ctx, PolicyRequest{ - Upsert: true, - Storage: storage, - KeyType: KeyType_RSA2048, - Name: "test", - }, rand.Reader) - if err != nil { - t.Fatal(err) - } - if p == nil { - t.Fatal("nil policy") - } - - signContext := []byte("context") - - hf := crypto.SHA1.New() - hf.Write([]byte("input")) - input := hf.Sum(nil) - - sig, err := p.Sign(0, signContext, input, HashTypeSHA1, "", MarshalingTypeASN1) - if err != nil { - t.Fatalf("failed signing: %#v", err) - } - - // Normal signature success - matches, err := p.VerifySignature(signContext, input, HashTypeSHA1, "", MarshalingTypeASN1, sig.Signature) - if err != nil { - t.Fatalf("failed signature verification: %#v", err) - } - if !matches { - t.Fatalf("signature verification failed ") - } - - hf.Reset() - hf.Write([]byte("bad-input")) - badInput := hf.Sum(nil) - - // Normal signature failure - matches2, err := p.VerifySignature(signContext, badInput, HashTypeSHA1, "", MarshalingTypeASN1, sig.Signature) - if err != nil { - t.Fatalf("failed signature verification: %#v", err) - } - if matches2 { - t.Fatalf("signature verification passed when it should have failed") - } - - // bad usage (not hashing input will trigger an error that is not rsa.ErrVerification so we - // should get an error back. - matches3, err := p.VerifySignature(signContext, []byte("bad-input"), HashTypeSHA1, "pkcs1v15", MarshalingTypeASN1, sig.Signature) - if err == nil { - t.Fatal("expected error signature without hashing input with pkcs1v15 but got none") - } - if matches3 { - t.Fatalf("signature verification passed when it should have failed with an error returned") - } -} - func Test_Import(t *testing.T) { ctx := context.Background() storage := &logical.InmemStorage{} diff --git a/sdk/helper/keysutil/util.go b/sdk/helper/keysutil/util.go deleted file mode 100644 index 063af5914672d..0000000000000 --- a/sdk/helper/keysutil/util.go +++ /dev/null @@ -1,115 +0,0 @@ -package keysutil - -import ( - "crypto/x509/pkix" - "encoding/asn1" - "errors" - "fmt" - - "golang.org/x/crypto/ed25519" -) - -// pkcs8 reflects an ASN.1, PKCS #8 PrivateKey. See -// ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-8/pkcs-8v1_2.asn -// and RFC 5208. -// -// Copied from Go: https://github.com/golang/go/blob/master/src/crypto/x509/pkcs8.go#L17-L80 -type pkcs8 struct { - Version int - Algo pkix.AlgorithmIdentifier - PrivateKey []byte - // optional attributes omitted. -} - -// ecPrivateKey reflects an ASN.1 Elliptic Curve Private Key Structure. -// References: -// -// RFC 5915 -// SEC1 - http://www.secg.org/sec1-v2.pdf -// -// Per RFC 5915 the NamedCurveOID is marked as ASN.1 OPTIONAL, however in -// most cases it is not. -// -// Copied from Go: https://github.com/golang/go/blob/master/src/crypto/x509/sec1.go#L18-L31 -type ecPrivateKey struct { - Version int - PrivateKey []byte - NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"` - - // Because the PKCS8/RFC 5915 encoding of the Ed25519 key uses the - // RFC 8032 Ed25519 seed format, we can ignore the public key parameter - // and infer it later. -} - -var ( - // See crypto/x509/x509.go in the Go toolchain source distribution. - oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1} - - // NSS encodes Ed25519 private keys with the OID 1.3.6.1.4.1.11591.15.1 - // from https://tools.ietf.org/html/draft-josefsson-pkix-newcurves-01. - // See https://github.com/nss-dev/nss/blob/NSS_3_79_BRANCH/lib/util/secoid.c#L600-L603. - oidNSSPKIXEd25519 = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11591, 15, 1} - - // Other implementations may use the OID 1.3.101.110 from - // https://datatracker.ietf.org/doc/html/rfc8410. - oidRFC8410Ed25519 = asn1.ObjectIdentifier{1, 3, 101, 110} -) - -func isEd25519OID(oid asn1.ObjectIdentifier) bool { - return oidNSSPKIXEd25519.Equal(oid) || oidRFC8410Ed25519.Equal(oid) -} - -// ParsePKCS8PrivateKey parses an unencrypted private key in PKCS #8, ASN.1 DER form. -// -// It returns a *rsa.PrivateKey, a *ecdsa.PrivateKey, or a ed25519.PrivateKey. -// More types might be supported in the future. -// -// This kind of key is commonly encoded in PEM blocks of type "PRIVATE KEY". -func ParsePKCS8Ed25519PrivateKey(der []byte) (key interface{}, err error) { - var privKey pkcs8 - var ed25519Key ecPrivateKey - - var checkedOID bool - - // If this err is nil, we assume we directly have a ECPrivateKey structure - // with explicit OID; ignore this error for now and return the latter err - // instead if neither parse correctly. - if _, err := asn1.Unmarshal(der, &privKey); err == nil { - switch { - case privKey.Algo.Algorithm.Equal(oidPublicKeyECDSA): - bytes := privKey.Algo.Parameters.FullBytes - namedCurveOID := new(asn1.ObjectIdentifier) - if _, err := asn1.Unmarshal(bytes, namedCurveOID); err != nil { - namedCurveOID = nil - } - - if namedCurveOID == nil || !isEd25519OID(*namedCurveOID) { - return nil, errors.New("keysutil: failed to parse private key (invalid, non-ed25519 curve parameter OID)") - } - - der = privKey.PrivateKey - checkedOID = true - default: - // The Go standard library already parses RFC 8410 keys; the - // inclusion of the OID here is in case it is used with the - // regular ECDSA PrivateKey structure, rather than the struct - // recognized by the Go standard library. - return nil, errors.New("keysutil: failed to parse key as ed25519 private key") - } - } - - _, err = asn1.Unmarshal(der, &ed25519Key) - if err != nil { - return nil, fmt.Errorf("keysutil: failed to parse private key (inner Ed25519 ECPrivateKey format was incorrect): %v", err) - } - - if !checkedOID && !isEd25519OID(ed25519Key.NamedCurveOID) { - return nil, errors.New("keysutil: failed to parse private key (invalid, non-ed25519 curve parameter OID)") - } - - if len(ed25519Key.PrivateKey) != 32 { - return nil, fmt.Errorf("keysutil: failed to parse private key as ed25519 private key: got %v bytes but expected %v byte RFC 8032 seed", len(ed25519Key.PrivateKey), ed25519.SeedSize) - } - - return ed25519.NewKeyFromSeed(ed25519Key.PrivateKey), nil -} diff --git a/sdk/helper/pathmanager/pathmanager_test.go b/sdk/helper/pathmanager/pathmanager_test.go index 7d6207b625e60..6924a7cbdecba 100644 --- a/sdk/helper/pathmanager/pathmanager_test.go +++ b/sdk/helper/pathmanager/pathmanager_test.go @@ -20,7 +20,7 @@ func TestPathManager(t *testing.T) { for _, path := range paths { if m.HasPath(path) { - t.Fatalf("path should not exist in filtered paths %q", path) + t.Fatalf("path should not exist in filtered paths '%s'", path) } } @@ -34,7 +34,7 @@ func TestPathManager(t *testing.T) { } for _, path := range paths { if !m.HasPath(path) { - t.Fatalf("path should exist in filtered paths %q", path) + t.Fatalf("path should exist in filtered paths '%s'", path) } } @@ -43,7 +43,7 @@ func TestPathManager(t *testing.T) { for _, path := range paths { if m.HasPath(path) { - t.Fatalf("path should not exist in filtered paths %q", path) + t.Fatalf("path should not exist in filtered paths '%s'", path) } } } @@ -63,7 +63,7 @@ func TestPathManager_RemovePrefix(t *testing.T) { for _, path := range paths { if m.HasPath(path) { - t.Fatalf("path should not exist in filtered paths %q", path) + t.Fatalf("path should not exist in filtered paths '%s'", path) } } @@ -77,7 +77,7 @@ func TestPathManager_RemovePrefix(t *testing.T) { } for _, path := range paths { if !m.HasPath(path) { - t.Fatalf("path should exist in filtered paths %q", path) + t.Fatalf("path should exist in filtered paths '%s'", path) } } @@ -90,7 +90,7 @@ func TestPathManager_RemovePrefix(t *testing.T) { for _, path := range paths { if m.HasPath(path) { - t.Fatalf("path should not exist in filtered paths %q", path) + t.Fatalf("path should not exist in filtered paths '%s'", path) } } } diff --git a/sdk/helper/pluginutil/multiplexing.pb.go b/sdk/helper/pluginutil/multiplexing.pb.go index b681bf3590613..d0ff51e57b242 100644 --- a/sdk/helper/pluginutil/multiplexing.pb.go +++ b/sdk/helper/pluginutil/multiplexing.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.0 +// protoc-gen-go v1.27.1 // protoc v3.19.4 // source: sdk/helper/pluginutil/multiplexing.proto diff --git a/sdk/logical/identity.pb.go b/sdk/logical/identity.pb.go index d0e2ab6227ea2..4b1a36b39826a 100644 --- a/sdk/logical/identity.pb.go +++ b/sdk/logical/identity.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.0 +// protoc-gen-go v1.27.1 // protoc v3.19.4 // source: sdk/logical/identity.proto diff --git a/sdk/logical/plugin.pb.go b/sdk/logical/plugin.pb.go index ed456ef2db90d..1fb53f9a79c92 100644 --- a/sdk/logical/plugin.pb.go +++ b/sdk/logical/plugin.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.0 +// protoc-gen-go v1.27.1 // protoc v3.19.4 // source: sdk/logical/plugin.proto diff --git a/sdk/logical/request.go b/sdk/logical/request.go index 1edb51b3fcc14..1c400a4cb7795 100644 --- a/sdk/logical/request.go +++ b/sdk/logical/request.go @@ -365,7 +365,6 @@ const ( ListOperation = "list" HelpOperation = "help" AliasLookaheadOperation = "alias-lookahead" - ResolveRoleOperation = "resolve-role" // The operations below are called globally, the path is less relevant. RevokeOperation Operation = "revoke" diff --git a/sdk/logical/response.go b/sdk/logical/response.go index 19194f524871c..e8276c789ace6 100644 --- a/sdk/logical/response.go +++ b/sdk/logical/response.go @@ -310,12 +310,3 @@ func (w *StatusHeaderResponseWriter) setCustomResponseHeaders(status int) { } var _ WrappingResponseWriter = &StatusHeaderResponseWriter{} - -// ResolveRoleResponse returns a standard response to be returned by functions handling a ResolveRoleOperation -func ResolveRoleResponse(roleName string) (*Response, error) { - return &Response{ - Data: map[string]interface{}{ - "role": roleName, - }, - }, nil -} diff --git a/sdk/plugin/pb/backend.pb.go b/sdk/plugin/pb/backend.pb.go index 39480c82aea53..dbad4da977ce2 100644 --- a/sdk/plugin/pb/backend.pb.go +++ b/sdk/plugin/pb/backend.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.0 +// protoc-gen-go v1.27.1 // protoc v3.19.4 // source: sdk/plugin/pb/backend.proto diff --git a/sdk/version/version_base.go b/sdk/version/version_base.go index ebbc418e721d2..d7411dd017b10 100644 --- a/sdk/version/version_base.go +++ b/sdk/version/version_base.go @@ -11,7 +11,7 @@ var ( // Whether cgo is enabled or not; set at build time CgoEnabled bool - Version = "1.12.0" - VersionPrerelease = "dev1" + Version = "1.11.3" + VersionPrerelease = "" VersionMetadata = "" ) diff --git a/tools/tools.go b/tools/tools.go index 7458113cec221..008536efe187d 100644 --- a/tools/tools.go +++ b/tools/tools.go @@ -11,6 +11,7 @@ package tools //go:generate go install golang.org/x/tools/cmd/goimports +//go:generate go install github.com/mitchellh/gox //go:generate go install github.com/client9/misspell/cmd/misspell //go:generate go install mvdan.cc/gofumpt //go:generate go install google.golang.org/protobuf/cmd/protoc-gen-go @@ -19,6 +20,8 @@ package tools import ( _ "golang.org/x/tools/cmd/goimports" + _ "github.com/mitchellh/gox" + _ "github.com/client9/misspell/cmd/misspell" _ "mvdan.cc/gofumpt" diff --git a/ui/.browserslistrc b/ui/.browserslistrc index 4a67162a087df..d6104e66505e9 100644 --- a/ui/.browserslistrc +++ b/ui/.browserslistrc @@ -1,4 +1,3 @@ -last 1 chrome version -last 1 firefox version -last 1 safari version -last 1 edge version +defaults +not IE 11 +maintained node versions diff --git a/ui/.eslintrc.js b/ui/.eslintrc.js index 9e626cbc17bba..16b2b22d38bc5 100644 --- a/ui/.eslintrc.js +++ b/ui/.eslintrc.js @@ -13,12 +13,7 @@ module.exports = { }, }, plugins: ['ember'], - extends: [ - 'eslint:recommended', - 'plugin:ember/recommended', - 'plugin:prettier/recommended', - 'plugin:compat/recommended', - ], + extends: ['eslint:recommended', 'plugin:ember/recommended', 'plugin:prettier/recommended'], env: { browser: true, }, diff --git a/ui/README.md b/ui/README.md index c8f224b7e6a56..6bbe9b3368eed 100644 --- a/ui/README.md +++ b/ui/README.md @@ -1,15 +1,15 @@ -**Table of Contents** - +**Table of Contents** + - [Vault UI](#vault-ui) - - [Ember CLI Version Matrix](#ember-cli-version-matrix) - [Prerequisites](#prerequisites) - - [Running a Vault Server](#running-a-vault-server) - [Running / Development](#running--development) - [Code Generators](#code-generators) - [Running Tests](#running-tests) + - [Automated Cross-Browser Testing](#automated-cross-browser-testing) + - [Running Browserstack Locally](#running-browserstack-locally) - [Linting](#linting) - [Building Vault UI into a Vault Binary](#building-vault-ui-into-a-vault-binary) - [Further Reading / Useful Links](#further-reading--useful-links) @@ -106,6 +106,17 @@ acceptance tests then run, proxing requests back to that server. - `yarn run test:oss -s` to keep the test server running after the initial run. - `yarn run test -f="policies"` to filter the tests that are run. `-f` gets passed into [QUnit's `filter` config](https://api.qunitjs.com/config/QUnit.config#qunitconfigfilter-string--default-undefined) +- `yarn run test:browserstack` to run the kv acceptance tests in Browserstack + +#### Automated Cross-Browser Testing + +Vault uses [Browserstack Automate](https://automate.browserstack.com/) to run all the kv acceptance tests on various browsers. You can view the list of browsers we test by viewing `testem.browserstack.js`. + +##### Running Browserstack Locally + +To run the Browserstack tests locally you will need to add your `BROWSERSTACK_USERNAME` and `BROWSERSTACK_ACCESS_KEY` to your environment. Then run `yarn run test:browserstack`. You can view the currently running tests at `localhost:7357` or log in to [Browserstack Automate](https://automate.browserstack.com/) to view a previous build. + +To run the tests locally in a browser other than IE11, swap out `launch_in_ci: ['BS_IE_11']` inside `testem.browserstack.js`. ### Linting @@ -132,3 +143,4 @@ setting `VAULT_UI` environment variable. - Development Browser Extensions - [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi) - [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/) +- [Browserstack Automate](https://automate.browserstack.com/) diff --git a/ui/app/adapters/cluster.js b/ui/app/adapters/cluster.js index 3c53106d71261..f8600442640dc 100644 --- a/ui/app/adapters/cluster.js +++ b/ui/app/adapters/cluster.js @@ -107,7 +107,7 @@ export default ApplicationAdapter.extend({ }, authenticate({ backend, data }) { - const { role, jwt, token, password, username, path, nonce } = data; + const { role, jwt, token, password, username, path } = data; const url = this.urlForAuth(backend, username, path); const verb = backend === 'token' ? 'GET' : 'POST'; let options = { @@ -119,8 +119,6 @@ export default ApplicationAdapter.extend({ }; } else if (backend === 'jwt' || backend === 'oidc') { options.data = { role, jwt }; - } else if (backend === 'okta') { - options.data = { password, nonce }; } else { options.data = token ? { token, password } : { password }; } diff --git a/ui/app/adapters/pki/cert.js b/ui/app/adapters/pki-certificate.js similarity index 97% rename from ui/app/adapters/pki/cert.js rename to ui/app/adapters/pki-certificate.js index 321c406809bda..6e587cedfeee5 100644 --- a/ui/app/adapters/pki/cert.js +++ b/ui/app/adapters/pki-certificate.js @@ -1,5 +1,5 @@ import { assign } from '@ember/polyfills'; -import Adapter from '../pki'; +import Adapter from './pki'; export default Adapter.extend({ url(role) { diff --git a/ui/app/adapters/pki/pki-config.js b/ui/app/adapters/pki-config.js similarity index 98% rename from ui/app/adapters/pki/pki-config.js rename to ui/app/adapters/pki-config.js index c94d30d1c7dab..efc908929a313 100644 --- a/ui/app/adapters/pki/pki-config.js +++ b/ui/app/adapters/pki-config.js @@ -2,7 +2,7 @@ import AdapterError from '@ember-data/adapter/error'; import { hash, resolve } from 'rsvp'; import { capitalize } from '@ember/string'; import { set } from '@ember/object'; -import ApplicationAdapter from '../application'; +import ApplicationAdapter from './application'; export default ApplicationAdapter.extend({ namespace: 'v1', diff --git a/ui/app/adapters/pki/pki-role.js b/ui/app/adapters/role-pki.js similarity index 97% rename from ui/app/adapters/pki/pki-role.js rename to ui/app/adapters/role-pki.js index 44f0163c03071..ad40d848b4d2e 100644 --- a/ui/app/adapters/pki/pki-role.js +++ b/ui/app/adapters/role-pki.js @@ -1,5 +1,5 @@ import { assign } from '@ember/polyfills'; -import ApplicationAdapter from '../application'; +import ApplicationAdapter from './application'; import { encodePath } from 'vault/utils/path-encoding-helpers'; export default ApplicationAdapter.extend({ diff --git a/ui/app/components/alert-popup.js b/ui/app/components/alert-popup.js index 14c05c7b30cea..666f26e69c85d 100644 --- a/ui/app/components/alert-popup.js +++ b/ui/app/components/alert-popup.js @@ -1,4 +1,4 @@ -import Component from '@glimmer/component'; +import OuterHTML from './outer-html'; /** * @module AlertPopup @@ -8,21 +8,14 @@ import Component from '@glimmer/component'; * // All properties are passed in from the flashMessage service. * ``` * - * @param {string} type=null - The alert type. This comes from the message-types helper. - * @param {string} [message=null] - The alert message. - * @param {function} close=null - The close action which will close the alert. - * @param {boolean} isPreformatted - if true modifies class. + * @param type=null {String} - The alert type. This comes from the message-types helper. + * @param [message=null] {String} - The alert message. + * @param close=null {Func} - The close action which will close the alert. * */ -export default class AlertPopup extends Component { - get type() { - return this.args.type || null; - } - get message() { - return this.args.message || null; - } - get close() { - return this.args.close || null; - } -} +export default OuterHTML.extend({ + type: null, + message: null, + close: null, +}); diff --git a/ui/app/components/auth-form.js b/ui/app/components/auth-form.js index eddbb9b27b04b..6d4208ce28c62 100644 --- a/ui/app/components/auth-form.js +++ b/ui/app/components/auth-form.js @@ -18,17 +18,13 @@ const BACKENDS = supportedAuthBackends(); * * @example ```js * // All properties are passed in via query params. - * ``` + * ``` * * @param {string} wrappedToken - The auth method that is currently selected in the dropdown. * @param {object} cluster - The auth method that is currently selected in the dropdown. This corresponds to an Ember Model. * @param {string} namespace- The currently active namespace. * @param {string} selectedAuth - The auth method that is currently selected in the dropdown. - * @param {function} onSuccess - Fired on auth success. - * @param {function} [setOktaNumberChallenge] - Sets whether we are waiting for okta number challenge to be used to sign in. - * @param {boolean} [waitingForOktaNumberChallenge=false] - Determines if we are waiting for the Okta Number Challenge to sign in. - * @param {function} [setCancellingAuth] - Sets whether we are cancelling or not the login authentication for Okta Number Challenge. - * @param {boolean} [cancelAuthForOktaNumberChallenge=false] - Determines if we are cancelling the login authentication for the Okta Number Challenge. + * @param {function} onSuccess - Fired on auth success */ const DEFAULTS = { @@ -55,9 +51,6 @@ export default Component.extend(DEFAULTS, { oldNamespace: null, authMethods: BACKENDS, - // number answer for okta number challenge if applicable - oktaNumberChallengeAnswer: null, - didReceiveAttrs() { this._super(...arguments); let { @@ -67,14 +60,8 @@ export default Component.extend(DEFAULTS, { namespace: ns, selectedAuth: newMethod, oldSelectedAuth: oldMethod, - cancelAuthForOktaNumberChallenge: cancelAuth, } = this; - // if we are cancelling the login then we reset the number challenge answer and cancel the current authenticate and polling tasks - if (cancelAuth) { - this.set('oktaNumberChallengeAnswer', null); - this.authenticate.cancelAll(); - this.pollForOktaNumberChallenge.cancelAll(); - } + next(() => { if (!token && (oldNS === null || oldNS !== ns)) { this.fetchMethods.perform(); @@ -232,11 +219,7 @@ export default Component.extend(DEFAULTS, { cluster: { id: clusterId }, } = this; try { - if (backendType === 'okta') { - this.pollForOktaNumberChallenge.perform(data.nonce, data.path); - } else { - this.delayAuthMessageReminder.perform(); - } + this.delayAuthMessageReminder.perform(); const authResponse = yield this.auth.authenticate({ clusterId, backend: backendType, @@ -253,28 +236,6 @@ export default Component.extend(DEFAULTS, { }) ), - pollForOktaNumberChallenge: task(function* (nonce, mount) { - // yield for 1s to wait to see if there is a login error before polling - yield timeout(1000); - if (this.error) { - return; - } - let response = null; - this.setOktaNumberChallenge(true); - this.setCancellingAuth(false); - // keep polling /auth/okta/verify/:nonce API every 1s until a response is given with the correct number for the Okta Number Challenge - while (response === null) { - // when testing, the polling loop causes promises to be rejected making acceptance tests fail - // so disable the poll in tests - if (Ember.testing) { - return; - } - yield timeout(1000); - response = yield this.auth.getOktaNumberChallengeAnswer(nonce, mount); - } - this.set('oktaNumberChallengeAnswer', response); - }), - delayAuthMessageReminder: task(function* () { if (Ember.testing) { this.showLoading = true; @@ -314,14 +275,6 @@ export default Component.extend(DEFAULTS, { if (this.customPath || backend.id) { data.path = this.customPath || backend.id; } - // add nonce field for okta backend - if (backend.type === 'okta') { - data.nonce = crypto.randomUUID(); - // add a default path of okta if it doesn't exist to be used for Okta Number Challenge - if (!data.path) { - data.path = 'okta'; - } - } return this.authenticate.unlinked().perform(backend.type, data); }, handleError(e) { @@ -330,9 +283,5 @@ export default Component.extend(DEFAULTS, { error: e ? this.auth.handleError(e) : null, }); }, - returnToLoginFromOktaNumberChallenge() { - this.setOktaNumberChallenge(false); - this.set('oktaNumberChallengeAnswer', null); - }, }, }); diff --git a/ui/app/components/auth-jwt.js b/ui/app/components/auth-jwt.js index 1605aadea6bc4..f5ae2a44fb5a6 100644 --- a/ui/app/components/auth-jwt.js +++ b/ui/app/components/auth-jwt.js @@ -1,6 +1,5 @@ import Ember from 'ember'; import { inject as service } from '@ember/service'; -// ARG NOTE: Once you remove outer-html after glimmerizing you can remove the outer-html component import Component from './outer-html'; import { later } from '@ember/runloop'; import { task, timeout, waitForEvent } from 'ember-concurrency'; diff --git a/ui/app/components/block-error.js b/ui/app/components/block-error.js new file mode 100644 index 0000000000000..96167992d7ced --- /dev/null +++ b/ui/app/components/block-error.js @@ -0,0 +1,2 @@ +import OuterHTML from './outer-html'; +export default OuterHTML.extend(); diff --git a/ui/app/components/pki/config-pki-ca.js b/ui/app/components/config-pki-ca.js similarity index 100% rename from ui/app/components/pki/config-pki-ca.js rename to ui/app/components/config-pki-ca.js diff --git a/ui/app/components/pki/config-pki.js b/ui/app/components/config-pki.js similarity index 100% rename from ui/app/components/pki/config-pki.js rename to ui/app/components/config-pki.js diff --git a/ui/app/components/database-role-setting-form.js b/ui/app/components/database-role-setting-form.js index 9107c38b20a1e..01b6170da2bae 100644 --- a/ui/app/components/database-role-setting-form.js +++ b/ui/app/components/database-role-setting-form.js @@ -1,6 +1,3 @@ -import Component from '@glimmer/component'; -import { getStatementFields, getRoleFields } from '../utils/database-helpers'; - /** * @module DatabaseRoleSettingForm * DatabaseRoleSettingForm components are used to handle the role settings section on the database/role form @@ -16,6 +13,9 @@ import { getStatementFields, getRoleFields } from '../utils/database-helpers'; * @param {string} [dbType=default] - type of database, eg 'mongodb-database-plugin' */ +import Component from '@glimmer/component'; +import { getStatementFields, getRoleFields } from '../utils/database-helpers'; + export default class DatabaseRoleSettingForm extends Component { get settingFields() { if (!this.args.roleType) return null; diff --git a/ui/app/components/generate-credentials.js b/ui/app/components/generate-credentials.js index 630c0a0ba0d9a..f71f62ecb11e0 100644 --- a/ui/app/components/generate-credentials.js +++ b/ui/app/components/generate-credentials.js @@ -16,7 +16,7 @@ const MODEL_TYPES = { backIsListLink: true, }, 'pki-issue': { - model: 'pki/cert', + model: 'pki-certificate', title: 'Issue Certificate', }, 'pki-sign': { diff --git a/ui/app/components/generated-item-list.js b/ui/app/components/generated-item-list.js index 8e1f8e6a7c6fc..61258ba040ca6 100644 --- a/ui/app/components/generated-item-list.js +++ b/ui/app/components/generated-item-list.js @@ -1,6 +1,5 @@ import { inject as service } from '@ember/service'; -import Component from '@glimmer/component'; -import { action } from '@ember/object'; +import Component from '@ember/component'; import { getOwner } from '@ember/application'; /** @@ -9,30 +8,24 @@ import { getOwner } from '@ember/application'; * * @example * ```js - * + * * ``` * - * @param {class} model=null - The corresponding item model that is being configured. - * @param {string} itemType - The type of item displayed. - * @param {array} paths - Relevant to the link for the LinkTo element. - * @param {class} methodModel - Model for the particular method selected. + * @property model=null {DS.Model} - The corresponding item model that is being configured. + * @property itemType {String} - the type of item displayed + * */ -export default class GeneratedItemList extends Component { - @service router; - @service store; - - get model() { - return this.args.model || null; - } - get itemType() { - return this.args.itemType || null; - } - - @action - refreshItemList() { - let route = getOwner(this).lookup(`route:${this.router.currentRouteName}`); - this.store.clearAllDatasets(); - route.refresh(); - } -} +export default Component.extend({ + model: null, + itemType: null, + router: service(), + store: service(), + actions: { + refreshItemList() { + let route = getOwner(this).lookup(`route:${this.router.currentRouteName}`); + this.store.clearAllDatasets(); + route.refresh(); + }, + }, +}); diff --git a/ui/app/components/home-link.js b/ui/app/components/home-link.js index 6d406c0d247d0..8d4273477bd4a 100644 --- a/ui/app/components/home-link.js +++ b/ui/app/components/home-link.js @@ -1,4 +1,5 @@ -import Component from '@glimmer/component'; +import Component from '@ember/component'; +import { computed } from '@ember/object'; /** * @module HomeLink @@ -10,19 +11,19 @@ import Component from '@glimmer/component'; * * * ``` - * @param {string} class - Classes attached to the the component. - * @param {string} text - Text displayed instead of logo. * * @see {@link https://github.com/hashicorp/vault/search?l=Handlebars&q=HomeLink|Uses of HomeLink} * @see {@link https://github.com/hashicorp/vault/blob/main/ui/app/components/home-link.js|HomeLink Source Code} */ -export default class HomeLink extends Component { - get text() { +export default Component.extend({ + tagName: '', + + text: computed(function () { return 'home'; - } + }), - get computedClasses() { + computedClasses: computed('classNames', function () { return this.classNames.join(' '); - } -} + }), +}); diff --git a/ui/app/components/hover-copy-button.js b/ui/app/components/hover-copy-button.js index fc2a6705e2760..63a4564ab8464 100644 --- a/ui/app/components/hover-copy-button.js +++ b/ui/app/components/hover-copy-button.js @@ -1,24 +1,11 @@ -import Component from '@glimmer/component'; -import { tracked } from '@glimmer/tracking'; +import Component from '@ember/component'; -/** - * @module HoverCopyButton - * The `HoverCopyButton` is used on dark backgrounds to show a copy button. - * - * @example ```js - * ``` - * - * @param {string} copyValue - The value to be copied. - * @param {boolean} [alwaysShow] - Boolean that affects the class. - */ +export default Component.extend({ + 'data-test-hover-copy': true, + attributeBindings: ['data-test-hover-copy'], + classNameBindings: 'alwaysShow:hover-copy-button-static:hover-copy-button', + copyValue: null, + alwaysShow: false, -export default class HoverCopyButton extends Component { - get alwaysShow() { - return this.args.alwaysShow || false; - } - get copyValue() { - return this.args.copyValue || false; - } - - @tracked tooltipText = 'Copy'; -} + tooltipText: 'Copy', +}); diff --git a/ui/app/components/logo-splash.js b/ui/app/components/logo-splash.js new file mode 100644 index 0000000000000..0fef514611cae --- /dev/null +++ b/ui/app/components/logo-splash.js @@ -0,0 +1 @@ +export { default } from './outer-html'; diff --git a/ui/app/components/mfa/mfa-form.js b/ui/app/components/mfa-form.js similarity index 98% rename from ui/app/components/mfa/mfa-form.js rename to ui/app/components/mfa-form.js index c73fb1197a05c..e83e835a48726 100644 --- a/ui/app/components/mfa/mfa-form.js +++ b/ui/app/components/mfa-form.js @@ -10,7 +10,7 @@ import { numberToWord } from 'vault/helpers/number-to-word'; * * @example * ```js - * + * * ``` * @param {string} clusterId - id of selected cluster * @param {object} authData - data from initial auth request -- { mfa_requirement, backend, data } diff --git a/ui/app/components/mfa/mfa-login-enforcement-form.js b/ui/app/components/mfa-login-enforcement-form.js similarity index 90% rename from ui/app/components/mfa/mfa-login-enforcement-form.js rename to ui/app/components/mfa-login-enforcement-form.js index 250019be60d9e..ef130f0aff314 100644 --- a/ui/app/components/mfa/mfa-login-enforcement-form.js +++ b/ui/app/components/mfa-login-enforcement-form.js @@ -3,7 +3,6 @@ import { tracked } from '@glimmer/tracking'; import { action } from '@ember/object'; import { inject as service } from '@ember/service'; import { task } from 'ember-concurrency'; -import handleHasManySelection from 'core/utils/search-select-has-many'; /** * @module MfaLoginEnforcementForm @@ -116,9 +115,21 @@ export default class MfaLoginEnforcementForm extends Component { @action async onMethodChange(selectedIds) { const methods = await this.args.model.mfa_methods; - handleHasManySelection(selectedIds, methods, this.store, 'mfa-method'); + // first check for existing methods that have been removed from selection + methods.forEach((method) => { + if (!selectedIds.includes(method.id)) { + methods.removeObject(method); + } + }); + // now check for selected items that don't exist and add them to the model + const methodIds = methods.mapBy('id'); + selectedIds.forEach((id) => { + if (!methodIds.includes(id)) { + const model = this.store.peekRecord('mfa-method', id); + methods.addObject(model); + } + }); } - @action onTargetSelect(type) { this.selectedTargetType = type; diff --git a/ui/app/components/mfa/mfa-login-enforcement-header.js b/ui/app/components/mfa-login-enforcement-header.js similarity index 100% rename from ui/app/components/mfa/mfa-login-enforcement-header.js rename to ui/app/components/mfa-login-enforcement-header.js diff --git a/ui/app/components/mfa/mfa-setup-step-one.js b/ui/app/components/mfa-setup-step-one.js similarity index 100% rename from ui/app/components/mfa/mfa-setup-step-one.js rename to ui/app/components/mfa-setup-step-one.js diff --git a/ui/app/components/mfa/mfa-setup-step-two.js b/ui/app/components/mfa-setup-step-two.js similarity index 100% rename from ui/app/components/mfa/mfa-setup-step-two.js rename to ui/app/components/mfa-setup-step-two.js diff --git a/ui/app/components/mount-backend-form.js b/ui/app/components/mount-backend-form.js index 63a26c84c3cdb..263981141892d 100644 --- a/ui/app/components/mount-backend-form.js +++ b/ui/app/components/mount-backend-form.js @@ -1,74 +1,80 @@ import Ember from 'ember'; -import Component from '@glimmer/component'; -import { tracked } from '@glimmer/tracking'; import { inject as service } from '@ember/service'; -import { action, setProperties } from '@ember/object'; +import { computed } from '@ember/object'; +import Component from '@ember/component'; import { task } from 'ember-concurrency'; import { methods } from 'vault/helpers/mountable-auth-methods'; import { engines, KMIP, TRANSFORM, KEYMGMT } from 'vault/helpers/mountable-secret-engines'; import { waitFor } from '@ember/test-waiters'; -/** - * @module MountBackendForm - * The `MountBackendForm` is used to mount either a secret or auth backend. - * - * @example ```js - * ``` - * - * @param {function} onMountSuccess - A function that transitions once the Mount has been successfully posted. - * @param {string} [mountType=auth] - The type of backend we want to mount. - * - */ - const METHODS = methods(); const ENGINES = engines(); -export default class MountBackendForm extends Component { - @service store; - @service wizard; - @service flashMessages; - @service version; - - get mountType() { - return this.args.mountType || 'auth'; - } - - @tracked mountModel = null; - @tracked showEnable = false; +export default Component.extend({ + store: service(), + wizard: service(), + flashMessages: service(), + version: service(), + + /* + * @param Function + * @public + * + * Optional param to call a function upon successfully mounting a backend + * + */ + onMountSuccess() {}, + /* + * @param String + * @public + * the type of backend we want to mount + * defaults to `auth` + * + */ + mountType: 'auth', + + /* + * + * @param DS.Model + * @private + * Ember Data model corresponding to the `mountType`. + * Created and set during `init` + * + */ + mountModel: null, + + showEnable: false, // validation related properties - @tracked modelValidations = null; - @tracked invalidFormAlert = null; + modelValidations: null, + invalidFormAlert: null, - @tracked mountIssue = false; + mountIssue: false, - @tracked errors = ''; - @tracked errorMessage = ''; - - constructor() { - super(...arguments); - const type = this.args.mountType || 'auth'; + init() { + this._super(...arguments); + const type = this.mountType; const modelType = type === 'secret' ? 'secret-engine' : 'auth-method'; const model = this.store.createRecord(modelType); - this.mountModel = model; - } + this.set('mountModel', model); + }, - get mountTypes() { + mountTypes: computed('engines', 'mountType', function () { return this.mountType === 'secret' ? this.engines : METHODS; - } + }), - get engines() { + engines: computed('version.{features[],isEnterprise}', function () { if (this.version.isEnterprise) { return ENGINES.concat([KMIP, TRANSFORM, KEYMGMT]); } return ENGINES; - } + }), willDestroy() { + this._super(...arguments); // if unsaved, we want to unload so it doesn't show up in the auth mount list - super.willDestroy(...arguments); this.mountModel.rollbackAttributes(); - } + }, checkPathChange(type) { let mount = this.mountModel; @@ -78,115 +84,114 @@ export default class MountBackendForm extends Component { // change it here to match the new type let isUnchanged = list.findBy('type', currentPath); if (!currentPath || isUnchanged) { - mount.path = type; + mount.set('path', type); } - } + }, checkModelValidity(model) { const { isValid, state, invalidFormMessage } = model.validate(); - setProperties(this, { + this.setProperties({ modelValidations: state, invalidFormAlert: invalidFormMessage, }); return isValid; - } - - @task - @waitFor - *mountBackend() { - const mountModel = this.mountModel; - const { type, path } = mountModel; - // only submit form if validations pass - if (!this.checkModelValidity(mountModel)) { - return; - } - let capabilities = null; - try { - capabilities = yield this.store.findRecord('capabilities', `${path}/config`); - } catch (err) { - if (Ember.testing) { - //captures mount-backend-form component test - yield mountModel.save(); - let mountType = this.mountType; - mountType = mountType === 'secret' ? `${mountType}s engine` : `${mountType} method`; - this.flashMessages.success(`Successfully mounted the ${type} ${mountType} at ${path}.`); - yield this.args.onMountSuccess(type, path); + }, + + mountBackend: task( + waitFor(function* () { + const mountModel = this.mountModel; + const { type, path } = mountModel; + // only submit form if validations pass + if (!this.checkModelValidity(mountModel)) { return; - } else { - throw err; } - } + let capabilities = null; + try { + capabilities = yield this.store.findRecord('capabilities', `${path}/config`); + } catch (err) { + if (Ember.testing) { + //captures mount-backend-form component test + yield mountModel.save(); + let mountType = this.mountType; + mountType = mountType === 'secret' ? `${mountType}s engine` : `${mountType} method`; + this.flashMessages.success(`Successfully mounted the ${type} ${mountType} at ${path}.`); + yield this.onMountSuccess(type, path); + return; + } else { + throw err; + } + } - let changedAttrKeys = Object.keys(mountModel.changedAttributes()); - let updatesConfig = - changedAttrKeys.includes('casRequired') || - changedAttrKeys.includes('deleteVersionAfter') || - changedAttrKeys.includes('maxVersions'); - - try { - yield mountModel.save(); - } catch (err) { - if (err.httpStatus === 403) { - this.mountIssue = true; - this.flashMessages.danger( - 'You do not have access to the sys/mounts endpoint. The secret engine was not mounted.' - ); + let changedAttrKeys = Object.keys(mountModel.changedAttributes()); + let updatesConfig = + changedAttrKeys.includes('casRequired') || + changedAttrKeys.includes('deleteVersionAfter') || + changedAttrKeys.includes('maxVersions'); + + try { + yield mountModel.save(); + } catch (err) { + if (err.httpStatus === 403) { + this.mountIssue = true; + this.flashMessages.danger( + 'You do not have access to the sys/mounts endpoint. The secret engine was not mounted.' + ); + return; + } + if (err.errors) { + let errors = err.errors.map((e) => { + if (typeof e === 'object') return e.title || e.message || JSON.stringify(e); + return e; + }); + this.set('errors', errors); + } else if (err.message) { + this.set('errorMessage', err.message); + } else { + this.set('errorMessage', 'An error occurred, check the vault logs.'); + } return; } - if (err.errors) { - let errors = err.errors.map((e) => { - if (typeof e === 'object') return e.title || e.message || JSON.stringify(e); - return e; - }); - this.errors = errors; - } else if (err.message) { - this.errorMessage = err.message; - } else { - this.errorMessage = 'An error occurred, check the vault logs.'; + // mountModel must be after the save + if (mountModel.isV2KV && updatesConfig && !capabilities.get('canUpdate')) { + // config error is not thrown from secret-engine adapter, so handling here + this.flashMessages.warning( + 'You do not have access to the config endpoint. The secret engine was mounted, but the configuration settings were not saved.' + ); + // remove the config data from the model otherwise it will save it even if the network request failed. + [this.mountModel.maxVersions, this.mountModel.casRequired, this.mountModel.deleteVersionAfter] = [ + 0, + false, + 0, + ]; } + let mountType = this.mountType; + mountType = mountType === 'secret' ? `${mountType}s engine` : `${mountType} method`; + this.flashMessages.success(`Successfully mounted the ${type} ${mountType} at ${path}.`); + yield this.onMountSuccess(type, path); return; - } - // mountModel must be after the save - if (mountModel.isV2KV && updatesConfig && !capabilities.get('canUpdate')) { - // config error is not thrown from secret-engine adapter, so handling here - this.flashMessages.warning( - 'You do not have access to the config endpoint. The secret engine was mounted, but the configuration settings were not saved.' - ); - // remove the config data from the model otherwise it will save it even if the network request failed. - [this.mountModel.maxVersions, this.mountModel.casRequired, this.mountModel.deleteVersionAfter] = [ - 0, - false, - 0, - ]; - } - let mountType = this.mountType; - mountType = mountType === 'secret' ? `${mountType}s engine` : `${mountType} method`; - this.flashMessages.success(`Successfully mounted the ${type} ${mountType} at ${path}.`); - yield this.args.onMountSuccess(type, path); - return; - } - - @action - onKeyUp(name, value) { - this.mountModel.set(name, value); - } - - @action - onTypeChange(path, value) { - if (path === 'type') { - this.wizard.set('componentState', value); - this.checkPathChange(value); - } - } - - @action - toggleShowEnable(value) { - this.showEnable = value; - if (value === true && this.wizard.featureState === 'idle') { - this.wizard.transitionFeatureMachine(this.wizard.featureState, 'CONTINUE', this.mountModel.type); - } else { - this.wizard.transitionFeatureMachine(this.wizard.featureState, 'RESET', this.mountModel.type); - } - } -} + }) + ).drop(), + + actions: { + onKeyUp(name, value) { + this.mountModel.set(name, value); + }, + + onTypeChange(path, value) { + if (path === 'type') { + this.wizard.set('componentState', value); + this.checkPathChange(value); + } + }, + + toggleShowEnable(value) { + this.set('showEnable', value); + if (value === true && this.wizard.featureState === 'idle') { + this.wizard.transitionFeatureMachine(this.wizard.featureState, 'CONTINUE', this.mountModel.type); + } else { + this.wizard.transitionFeatureMachine(this.wizard.featureState, 'RESET', this.mountModel.type); + } + }, + }, +}); diff --git a/ui/app/components/okta-number-challenge.js b/ui/app/components/okta-number-challenge.js deleted file mode 100644 index 7c9566e11546b..0000000000000 --- a/ui/app/components/okta-number-challenge.js +++ /dev/null @@ -1,24 +0,0 @@ -import Component from '@glimmer/component'; - -/** - * @module OktaNumberChallenge - * OktaNumberChallenge components are used to display loading screen and correct answer for Okta Number Challenge when signing in through Okta - * - * @example - * ```js - * - * ``` - * @param {number} correctAnswer - The correct answer to click for the okta number challenge. - * @param {boolean} hasError - Determines if there is an error being thrown. - * @param {function} onReturnToLogin - Sets waitingForOktaNumberChallenge to false if want to return to main login. - */ - -export default class OktaNumberChallenge extends Component { - get oktaNumberChallengeCorrectAnswer() { - return this.args.correctAnswer; - } - - get errorThrown() { - return this.args.hasError; - } -} diff --git a/ui/app/components/pki-cert-popup.js b/ui/app/components/pki-cert-popup.js new file mode 100644 index 0000000000000..6f4da8d1e3ecb --- /dev/null +++ b/ui/app/components/pki-cert-popup.js @@ -0,0 +1,17 @@ +import Component from '@ember/component'; + +export default Component.extend({ + /* + * @public + * @param DS.Model + * + * the pki-certificate model + */ + item: null, + + actions: { + delete(item) { + item.save({ adapterOptions: { method: 'revoke' } }); + }, + }, +}); diff --git a/ui/app/components/pki/pki-cert-show.js b/ui/app/components/pki-cert-show.js similarity index 79% rename from ui/app/components/pki/pki-cert-show.js rename to ui/app/components/pki-cert-show.js index 0c743eb151814..bd1dad467b351 100644 --- a/ui/app/components/pki/pki-cert-show.js +++ b/ui/app/components/pki-cert-show.js @@ -1,4 +1,4 @@ -import RoleEdit from '../role-edit'; +import RoleEdit from './role-edit'; export default RoleEdit.extend({ actions: { diff --git a/ui/app/components/pki/pki-cert-popup.js b/ui/app/components/pki/pki-cert-popup.js deleted file mode 100644 index 49237e4b6471d..0000000000000 --- a/ui/app/components/pki/pki-cert-popup.js +++ /dev/null @@ -1,24 +0,0 @@ -import Component from '@glimmer/component'; -import { action } from '@ember/object'; - -/** - * @module PkiCertPopup - * PkiCertPopup component is the hotdog menu button that allows you to see details or revoke a certificate. - * - * @example - * ```js - * - * ``` - * @param {class} item - the PKI cert in question. - */ - -export default class PkiCertPopup extends Component { - get item() { - return this.args.item || null; - } - - @action - delete(item) { - item.save({ adapterOptions: { method: 'revoke' } }); - } -} diff --git a/ui/app/components/pki/role-pki-edit.js b/ui/app/components/role-pki-edit.js similarity index 76% rename from ui/app/components/pki/role-pki-edit.js rename to ui/app/components/role-pki-edit.js index 357b00cc2acfc..0134050950147 100644 --- a/ui/app/components/pki/role-pki-edit.js +++ b/ui/app/components/role-pki-edit.js @@ -1,4 +1,4 @@ -import RoleEdit from '../role-edit'; +import RoleEdit from './role-edit'; export default RoleEdit.extend({ init() { diff --git a/ui/app/components/selectable-card.js b/ui/app/components/selectable-card.js index abe19949c5f25..d1f6edc8fcda3 100644 --- a/ui/app/components/selectable-card.js +++ b/ui/app/components/selectable-card.js @@ -1,5 +1,5 @@ -import Component from '@glimmer/component'; - +import Component from '@ember/component'; +import { computed } from '@ember/object'; /** * @module SelectableCard * SelectableCard components are card-like components that display a title, total, subtotal, and anything after the yield. @@ -9,20 +9,30 @@ import Component from '@glimmer/component'; * ```js * * ``` - * @param {string} [cardTitle] - cardTitle displays the card title. - * @param {number} [total = 0] - the number displayed as the largest text in the component. - * @param {string} [subText] - subText describes the total. - * @param {string} [actionText] - action text link. - * @param {string} [actionTo] - route where link will take you. - * @param {string} [queryParam] - tab for the route the link will take you. - * @param {string} [type] - type used in the link type. + * @param cardTitle=null {String} - cardTitle displays the card title + * @param total=0 {Number} - the Total number displays like a title, it's the largest text in the component + * @param subText=null {String} - subText describes the total + * @param actionCard=false {Boolean} - false default selectable card container used in metrics, true a card that focus on actions as seen in database secret engine overview + * @param actionText=null {String} - that action that happens in an actionCard */ -export default class SelectableCard extends Component { - get gridContainer() { - return this.args.gridContainer || false; - } - get total() { - return this.args.total || 0; - } -} +export default Component.extend({ + cardTitle: '', + total: 0, + subText: '', + actionCard: false, + actionText: '', + gridContainer: false, + tagName: '', // do not wrap component with div + formattedCardTitle: computed('total', function () { + const { cardTitle, total } = this; + + if (cardTitle === 'Tokens') { + return total !== 1 ? 'Tokens' : 'Token'; + } else if (cardTitle === 'Entities') { + return total !== 1 ? 'Entities' : 'Entity'; + } + + return cardTitle; + }), +}); diff --git a/ui/app/components/splash-page.js b/ui/app/components/splash-page.js index 8a1d4f5461cd9..5942d3ab8187b 100644 --- a/ui/app/components/splash-page.js +++ b/ui/app/components/splash-page.js @@ -1,33 +1,15 @@ -/** - * @module SplashPage - * SplashPage component is used as a landing page with a box horizontally and center aligned on the page. It's used as the login landing page. - * - * - * @example - * ```js - * - * content here - * - * ``` - * @param {string} [ariaLabel] - aria label for the status icon. - * @param {string} [label] - label for the status menu. - * @param {string} [type] - determines where the component is being used. e.g. replication, auth, etc. - * @param {function} [onLinkClick] - function to handle click on the nested links under content. - * - */ - -export default class StatusMenu extends Component { - @service currentCluster; - @service auth; - @service media; - - get type() { - return this.args.type || 'cluster'; - } - - get glyphName() { - return this.type === 'user' ? 'user' : 'circle-dot'; - } - - @action - handleClick(d) { - this.args.onLinkClick; - d.actions.close(); - } -} +export default Component.extend({ + currentCluster: service('current-cluster'), + cluster: alias('currentCluster.cluster'), + auth: service(), + media: service(), + type: 'cluster', + itemTag: null, + glyphName: computed('type', function () { + return { + cluster: 'circle-dot', + user: 'user', + }[this.type]; + }), +}); diff --git a/ui/app/components/wizard-section.js b/ui/app/components/wizard-section.js new file mode 100644 index 0000000000000..f8c97b4b804d1 --- /dev/null +++ b/ui/app/components/wizard-section.js @@ -0,0 +1,9 @@ +import outerHTMLComponent from './outer-html'; + +export default outerHTMLComponent.extend({ + headerText: null, + headerIcon: null, + docText: null, + docPath: null, + instructions: null, +}); diff --git a/ui/app/controllers/vault/cluster/auth.js b/ui/app/controllers/vault/cluster/auth.js index 496ceaf1c8bcf..41eb3dcb6ec39 100644 --- a/ui/app/controllers/vault/cluster/auth.js +++ b/ui/app/controllers/vault/cluster/auth.js @@ -85,9 +85,5 @@ export default Controller.extend({ mfaErrors: null, }); }, - cancelAuthentication() { - this.set('cancelAuth', true); - this.set('waitingForOktaNumberChallenge', false); - }, }, }); diff --git a/ui/app/helpers/-date-base.js b/ui/app/helpers/-date-base.js index 4ca8dad2a5af9..384cf790907c0 100644 --- a/ui/app/helpers/-date-base.js +++ b/ui/app/helpers/-date-base.js @@ -1,15 +1,10 @@ import { run } from '@ember/runloop'; import Helper from '@ember/component/helper'; -import Ember from 'ember'; export default Helper.extend({ disableInterval: false, compute(value, { interval }) { - if (Ember.testing) { - // issues with flaky test, suspect it has to the do with the run loop not being cleared as intended farther down. - return; - } if (this.disableInterval) { return; } diff --git a/ui/app/helpers/options-for-backend.js b/ui/app/helpers/options-for-backend.js index bf52622288c59..88e457b7932c1 100644 --- a/ui/app/helpers/options-for-backend.js +++ b/ui/app/helpers/options-for-backend.js @@ -31,18 +31,18 @@ const SECRET_BACKENDS = { searchPlaceholder: 'Filter roles', item: 'role', create: 'Create role', - editComponent: 'pki/role-pki-edit', + editComponent: 'role-pki-edit', }, { - name: 'cert', + name: 'certs', modelPrefix: 'cert/', label: 'Certificates', searchPlaceholder: 'Filter certificates', item: 'certificates', create: 'Create role', - tab: 'cert', + tab: 'certs', listItemPartial: 'secret-list/pki-cert-item', - editComponent: 'pki/pki-cert-show', + editComponent: 'pki-cert-show', }, ], }, diff --git a/ui/app/models/pki-ca-certificate.js b/ui/app/models/pki-ca-certificate.js index 28b07084d233c..bb5435561fa88 100644 --- a/ui/app/models/pki-ca-certificate.js +++ b/ui/app/models/pki-ca-certificate.js @@ -1,6 +1,6 @@ import { attr } from '@ember-data/model'; import { computed } from '@ember/object'; -import Certificate from './pki/cert'; +import Certificate from './pki-certificate'; export default Certificate.extend({ DISPLAY_FIELDS: computed(function () { diff --git a/ui/app/models/pki-certificate-sign.js b/ui/app/models/pki-certificate-sign.js index afc937f89cb72..556fe6e94b1d2 100644 --- a/ui/app/models/pki-certificate-sign.js +++ b/ui/app/models/pki-certificate-sign.js @@ -1,7 +1,7 @@ import { attr } from '@ember-data/model'; import { copy } from 'ember-copy'; import { computed } from '@ember/object'; -import Certificate from './pki/cert'; +import Certificate from './pki-certificate'; import { combineFieldGroups } from 'vault/utils/openapi-to-attrs'; export default Certificate.extend({ diff --git a/ui/app/models/pki/cert.js b/ui/app/models/pki-certificate.js similarity index 100% rename from ui/app/models/pki/cert.js rename to ui/app/models/pki-certificate.js diff --git a/ui/app/models/pki/pki-config.js b/ui/app/models/pki-config.js similarity index 100% rename from ui/app/models/pki/pki-config.js rename to ui/app/models/pki-config.js diff --git a/ui/app/models/pki/pki-role.js b/ui/app/models/role-pki.js similarity index 100% rename from ui/app/models/pki/pki-role.js rename to ui/app/models/role-pki.js diff --git a/ui/app/routes/vault/cluster/secrets/backend/list.js b/ui/app/routes/vault/cluster/secrets/backend/list.js index dd5fbfd3500a9..019d4b3ad3b6d 100644 --- a/ui/app/routes/vault/cluster/secrets/backend/list.js +++ b/ui/app/routes/vault/cluster/secrets/backend/list.js @@ -80,7 +80,7 @@ export default Route.extend({ ssh: 'role-ssh', transform: this.modelTypeForTransform(tab), aws: 'role-aws', - pki: `pki/${tab || 'pki-role'}`, + pki: tab === 'certs' ? 'pki-certificate' : 'role-pki', // secret or secret-v2 cubbyhole: 'secret', kv: secretEngine.get('modelTypeForKV'), @@ -130,7 +130,7 @@ export default Route.extend({ afterModel(model) { const { tab } = this.paramsFor(this.routeName); const backend = this.enginePathParam(); - if (!tab || tab !== 'cert') { + if (!tab || tab !== 'certs') { return; } return all( @@ -138,7 +138,7 @@ export default Route.extend({ // possible that there is no certificate for them in order to know, // we fetch them specifically on the list page, and then unload the // records if there is no `certificate` attribute on the resultant model - ['ca', 'crl', 'ca_chain'].map((id) => this.store.queryRecord('pki/cert', { id, backend })) + ['ca', 'crl', 'ca_chain'].map((id) => this.store.queryRecord('pki-certificate', { id, backend })) ).then( (results) => { results.rejectBy('certificate').forEach((record) => record.unloadRecord()); diff --git a/ui/app/routes/vault/cluster/secrets/backend/overview.js b/ui/app/routes/vault/cluster/secrets/backend/overview.js index 7ba2e38c865dc..3952708d1ab73 100644 --- a/ui/app/routes/vault/cluster/secrets/backend/overview.js +++ b/ui/app/routes/vault/cluster/secrets/backend/overview.js @@ -54,7 +54,6 @@ export default Route.extend({ roleCapabilities, staticRoleCapabilities, connectionCapabilities, - icon: 'database', }); }, setupController(controller, model) { diff --git a/ui/app/routes/vault/cluster/secrets/backend/secret-edit.js b/ui/app/routes/vault/cluster/secrets/backend/secret-edit.js index 3b6b796fe3b4d..1ccc5bfdbd5de 100644 --- a/ui/app/routes/vault/cluster/secrets/backend/secret-edit.js +++ b/ui/app/routes/vault/cluster/secrets/backend/secret-edit.js @@ -101,7 +101,7 @@ export default Route.extend(UnloadModelRoute, { ssh: 'role-ssh', transform: this.modelTypeForTransform(secret), aws: 'role-aws', - pki: secret && secret.startsWith('cert/') ? 'pki/cert' : 'pki/pki-role', + pki: secret && secret.startsWith('cert/') ? 'pki-certificate' : 'role-pki', cubbyhole: 'secret', kv: backendModel.get('modelTypeForKV'), keymgmt: `keymgmt/${options.queryParams?.itemType || 'key'}`, @@ -230,7 +230,7 @@ export default Route.extend(UnloadModelRoute, { if (!secret) { secret = '\u0020'; } - if (modelType === 'pki/cert') { + if (modelType === 'pki-certificate') { secret = secret.replace('cert/', ''); } if (modelType.startsWith('transform/')) { diff --git a/ui/app/routes/vault/cluster/settings/configure-secret-backend/section.js b/ui/app/routes/vault/cluster/settings/configure-secret-backend/section.js index ffb1e8d6a2c80..b4aa5da1a2856 100644 --- a/ui/app/routes/vault/cluster/settings/configure-secret-backend/section.js +++ b/ui/app/routes/vault/cluster/settings/configure-secret-backend/section.js @@ -2,7 +2,6 @@ import AdapterError from '@ember-data/adapter/error'; import { set } from '@ember/object'; import Route from '@ember/routing/route'; -// ARG TODO glimmerize const SECTIONS_FOR_TYPE = { pki: ['cert', 'urls', 'crl', 'tidy'], }; @@ -10,21 +9,14 @@ export default Route.extend({ fetchModel() { const { section_name: sectionName } = this.paramsFor(this.routeName); const backendModel = this.modelFor('vault.cluster.settings.configure-secret-backend'); - const type = backendModel.get('type'); - let modelType; - if (type === 'pki') { - // pki models are in models/pki - modelType = `${type}/${type}-config`; - } else { - modelType = `${type}-config`; - } + const modelType = `${backendModel.get('type')}-config`; return this.store .queryRecord(modelType, { backend: backendModel.id, section: sectionName, }) .then((model) => { - model.set('backendType', type); + model.set('backendType', backendModel.get('type')); model.set('section', sectionName); return model; }); diff --git a/ui/app/serializers/pki/cert.js b/ui/app/serializers/pki-certificate.js similarity index 97% rename from ui/app/serializers/pki/cert.js rename to ui/app/serializers/pki-certificate.js index 3a91a3160599b..8991e82f91a41 100644 --- a/ui/app/serializers/pki/cert.js +++ b/ui/app/serializers/pki-certificate.js @@ -2,7 +2,7 @@ import RESTSerializer from '@ember-data/serializer/rest'; import { isNone, isBlank } from '@ember/utils'; import { assign } from '@ember/polyfills'; import { decamelize } from '@ember/string'; -import { parsePkiCert } from '../../helpers/parse-pki-cert'; +import { parsePkiCert } from '../helpers/parse-pki-cert'; export default RESTSerializer.extend({ keyForAttribute: function (attr) { diff --git a/ui/app/serializers/pki/pki-config.js b/ui/app/serializers/pki-config.js similarity index 100% rename from ui/app/serializers/pki/pki-config.js rename to ui/app/serializers/pki-config.js diff --git a/ui/app/serializers/pki/pki-role.js b/ui/app/serializers/role-pki.js similarity index 51% rename from ui/app/serializers/pki/pki-role.js rename to ui/app/serializers/role-pki.js index 9366ee82b1dbe..d36af6b2f38b9 100644 --- a/ui/app/serializers/pki/pki-role.js +++ b/ui/app/serializers/role-pki.js @@ -1,3 +1,3 @@ -import RoleSerializer from '../role'; +import RoleSerializer from './role'; export default RoleSerializer.extend(); diff --git a/ui/app/services/auth.js b/ui/app/services/auth.js index 6134ac014ea4b..95cf6b88dc36e 100644 --- a/ui/app/services/auth.js +++ b/ui/app/services/auth.js @@ -441,21 +441,4 @@ export default Service.extend({ backend: BACKENDS.findBy('type', backend), }); }), - - getOktaNumberChallengeAnswer(nonce, mount) { - const url = `/v1/auth/${mount}/verify/${nonce}`; - return this.ajax(url, 'GET', {}).then( - (resp) => { - return resp.data.correct_answer; - }, - (e) => { - // if error status is 404, return and keep polling for a response - if (e.status === 404) { - return null; - } else { - throw e; - } - } - ); - }, }); diff --git a/ui/app/templates/components/alert-popup.hbs b/ui/app/templates/components/alert-popup.hbs index c95751ff243fd..2a08deced4b05 100644 --- a/ui/app/templates/components/alert-popup.hbs +++ b/ui/app/templates/components/alert-popup.hbs @@ -4,7 +4,7 @@