diff --git a/ci_scripts/setup-keyring-servers.sh b/ci_scripts/setup-keyring-servers.sh index c9f523c8129e8..356d98b586ce9 100755 --- a/ci_scripts/setup-keyring-servers.sh +++ b/ci_scripts/setup-keyring-servers.sh @@ -20,8 +20,9 @@ pykmip-server -f "$SCRIPT_DIR/../contrib/pg_tde/pykmip-server.conf" -l /tmp/kmip TV=$(mktemp) { exec >$TV; vault server -dev; } & sleep 10 -export ROOT_TOKEN=$(cat $TV | grep "Root Token" | cut -d ":" -f 2 | xargs echo -n) -echo "export ROOT_TOKEN=$ROOT_TOKEN" +export ROOT_TOKEN_FILE=$(mktemp) +cat $TV | grep "Root Token" | cut -d ":" -f 2 | xargs echo -n > $ROOT_TOKEN_FILE +echo "export ROOT_TOKEN_FILE=$ROOT_TOKEN_FILE" if [ -v GITHUB_ACTIONS ]; then - echo "ROOT_TOKEN=$ROOT_TOKEN" >> $GITHUB_ENV + echo "ROOT_TOKEN_FILE=$ROOT_TOKEN_FILE" >> $GITHUB_ENV fi diff --git a/contrib/pg_tde/README.md b/contrib/pg_tde/README.md index ec367e2cdcab3..cdcb0bbe47fbc 100644 --- a/contrib/pg_tde/README.md +++ b/contrib/pg_tde/README.md @@ -116,9 +116,9 @@ _See [Make Builds for Developers](https://github.com/percona/pg_tde/wiki/Make-bu -- pg_tde_add_database_key_provider_vault_v2(provider_name, vault_token, vault_url, vault_mount_path, vault_ca_path) SELECT pg_tde_add_database_key_provider_vault_v2( 'vault-provider', - json_object( 'type' VALUE 'remote', 'url' VALUE 'http://localhost:8888/token' ), - json_object( 'type' VALUE 'remote', 'url' VALUE 'http://localhost:8888/url' ), - to_json('secret'::text), NULL); + '/path/to/token_file', + 'https://your.vault.server', + 'secret', NULL); -- For File key provider -- pg_tde_add_database_key_provider_file(provider_name, file_path); diff --git a/contrib/pg_tde/documentation/docs/architecture/index.md b/contrib/pg_tde/documentation/docs/architecture/index.md index e5e1612094610..d2061a8f7058c 100644 --- a/contrib/pg_tde/documentation/docs/architecture/index.md +++ b/contrib/pg_tde/documentation/docs/architecture/index.md @@ -168,11 +168,10 @@ For such situations, `pg_tde` also provides [command line tools](../command-line ### Sensitive key provider information -Key provider information authentication details is a sensitive information. It is not safe to store it together with the database in the `$PGDATA` directory, or even on the same server. +!!! important -To safeguard key providers' sensitive information, `pg_tde` supports references to external services. Instead of specifying authentication details directly, users specify the reference to the external service where it is stored. `pg_tde` then downloads the provider's authentication details when needed. - -The currently supported external services are HTTP and external file references. + Authentication details for key providers are sensitive and must be protected. + Do not store these credentials in the `$PGDATA` directory alongside the database. Instead, ensure they are stored in a secure location with strict file system permissions to prevent unauthorized access. ## User interface diff --git a/contrib/pg_tde/documentation/docs/command-line-tools/pg-tde-change-key-provider.md b/contrib/pg_tde/documentation/docs/command-line-tools/pg-tde-change-key-provider.md index a897634c41c37..f0dc00e582e47 100644 --- a/contrib/pg_tde/documentation/docs/command-line-tools/pg-tde-change-key-provider.md +++ b/contrib/pg_tde/documentation/docs/command-line-tools/pg-tde-change-key-provider.md @@ -31,6 +31,6 @@ Depending on the provider type, the additional parameters are: ```bash pg_tde_change_key_provider [-D ] file -pg_tde_change_key_provider [-D ] vault [] +pg_tde_change_key_provider [-D ] vault [] pg_tde_change_key_provider [-D ] kmip [] ``` diff --git a/contrib/pg_tde/documentation/docs/functions.md b/contrib/pg_tde/documentation/docs/functions.md index ea5095fa8acb8..5dae0deaee72c 100644 --- a/contrib/pg_tde/documentation/docs/functions.md +++ b/contrib/pg_tde/documentation/docs/functions.md @@ -63,14 +63,14 @@ Use the following functions to add the Vault provider: ```sql SELECT pg_tde_add_database_key_provider_vault_v2( 'provider-name', - 'secret_token', + 'secret_token_path', 'url','mount', 'ca_path' ); SELECT pg_tde_add_global_key_provider_vault_v2( 'provider-name', - 'secret_token', + 'secret_token_path', 'url','mount', 'ca_path' ); @@ -81,7 +81,7 @@ These functions change the Vault provider: ```sql SELECT pg_tde_change_database_key_provider_vault_v2( 'provider-name', - 'secret_token', + 'secret_token_path', 'url', 'mount', 'ca_path' @@ -89,7 +89,7 @@ SELECT pg_tde_change_database_key_provider_vault_v2( SELECT pg_tde_change_global_key_provider_vault_v2( 'provider-name', - 'secret_token', + 'secret_token_path', 'url', 'mount', 'ca_path' @@ -101,13 +101,10 @@ where: * `provider-name` is the name of the key provider * `url` is the URL of the Vault server * `mount` is the mount point on the Vault server where the key provider should store the keys -* `secret_token` is an access token with read and write access to the above mount point +* `secret_token_path` is a path to the file that contains an access token with read and write access to the above mount point * **[optional]** `ca_path` is the path of the CA file used for SSL verification -All parameters can be either strings, or JSON objects [referencing remote parameters](how-to/external-parameters.md). -!!! important - Never specify the secret token directly, use a remote parameter instead. #### Adding or modifying KMIP providers @@ -168,7 +165,6 @@ where: !!! note The specified access parameters require permission to read and write keys at the server. -All parameters can be either strings, or JSON objects [referencing remote parameters](how-to/external-parameters.md). ### Adding or modifying local keyfile providers @@ -212,8 +208,6 @@ where: * `provider-name` is the name of the provider. You can specify any name, it's for you to identify the provider. * `/path/to/the/key/provider/data.file` is the path to the key provider file. -!!! note - All parameters can be either strings, or JSON objects [referencing remote parameters](how-to/external-parameters.md). ### Delete a provider diff --git a/contrib/pg_tde/documentation/docs/global-key-provider-configuration/keyring.md b/contrib/pg_tde/documentation/docs/global-key-provider-configuration/keyring.md index f8cb931b81ea8..82829aefd1d12 100644 --- a/contrib/pg_tde/documentation/docs/global-key-provider-configuration/keyring.md +++ b/contrib/pg_tde/documentation/docs/global-key-provider-configuration/keyring.md @@ -1,6 +1,6 @@ # Keyring File Configuration -This setup is intended for development and stores the keys unencrypted in the specified data file. See [how to use external reference to parameters](../how-to/external-parameters.md) to add an extra security layer to your setup. +This setup is intended for development and stores the keys unencrypted in the specified data file. !!! note While keyfiles may be acceptable for **local** or **testing environments**, KMS integration is the recommended approach for production deployments. diff --git a/contrib/pg_tde/documentation/docs/global-key-provider-configuration/vault.md b/contrib/pg_tde/documentation/docs/global-key-provider-configuration/vault.md index bc4df08d6da95..71aaaf075a56d 100644 --- a/contrib/pg_tde/documentation/docs/global-key-provider-configuration/vault.md +++ b/contrib/pg_tde/documentation/docs/global-key-provider-configuration/vault.md @@ -10,7 +10,7 @@ You can configure `pg_tde` to use HashiCorp Vault as a global key provider for m ```sql SELECT pg_tde_add_global_key_provider_vault_v2( 'provider-name', - 'secret_token', + 'secret_token_path', 'url', 'mount', 'ca_path' @@ -20,7 +20,7 @@ SELECT pg_tde_add_global_key_provider_vault_v2( ## Parameter descriptions * `provider-name` is the name to identify this key provider -* `secret_token` is an access token with read and write access to the above mount point +* `secret_token_path` is a path to the file that contains an access token with read and write access to the above mount point * `url` is the URL of the Vault server * `mount` is the mount point where the keyring should store the keys * [optional] `ca_path` is the path of the CA file used for SSL verification @@ -30,7 +30,7 @@ The following example is for testing purposes only. Use secure tokens and proper ```sql SELECT pg_tde_add_global_key_provider_vault_v2( 'my-vault', - 'hvs.zPuyktykA...example...ewUEnIRVaKoBzs2', + '/path/to/token_file', 'http://vault.vault.svc.cluster.local:8200', 'secret/data', NULL diff --git a/contrib/pg_tde/documentation/docs/how-to/external-parameters.md b/contrib/pg_tde/documentation/docs/how-to/external-parameters.md deleted file mode 100644 index 6177a91223532..0000000000000 --- a/contrib/pg_tde/documentation/docs/how-to/external-parameters.md +++ /dev/null @@ -1,33 +0,0 @@ -# Use External Reference to Parameters - -To allow storing secrets or any other parameters in a more secure, external location, `pg_tde` -allows users to specify an external reference instead of hardcoded parameters. - -In the Alpha1 version, `pg_tde` supports the following external storage methods: - -* `file`, which just stores the data in a simple file specified by a `path`. The file should be -readable to the postgres process. -* `remote`, which uses a HTTP request to retrieve the parameter from the specified `url`. - -## Examples - -To use the file provider with a file location specified by the `remote` method, -use the following command: - -```sql -SELECT pg_tde_add_database_key_provider_file( - 'file-provider', - json_object( 'type' VALUE 'remote', 'url' VALUE 'http://localhost:8888/hello' ) - ); -``` - -Or to use the `file` method, use the following command: - -```sql -SELECT pg_tde_add_database_key_provider_file( - 'file-provider', - json_object( 'type' VALUE 'remote', 'path' VALUE '/tmp/datafile-location' ) - );" -``` - -Any parameter specified to the `add_key_provider` function can be a `json_object` instead of the string, similar to the above examples. diff --git a/contrib/pg_tde/documentation/docs/how-to/multi-tenant-setup.md b/contrib/pg_tde/documentation/docs/how-to/multi-tenant-setup.md index 8f7c14f17a421..b128faef55871 100644 --- a/contrib/pg_tde/documentation/docs/how-to/multi-tenant-setup.md +++ b/contrib/pg_tde/documentation/docs/how-to/multi-tenant-setup.md @@ -84,14 +84,14 @@ You must do these steps for every database where you have created the extension. The Vault server setup is out of scope of this document. ```sql - SELECT pg_tde_add_database_key_provider_vault_v2('provider-name','secret_token','url','mount','ca_path'); + SELECT pg_tde_add_database_key_provider_vault_v2('provider-name','secret_token_path','url','mount','ca_path'); ``` where: * `url` is the URL of the Vault server * `mount` is the mount point where the keyring should store the keys - * `secret_token` is an access token with read and write access to the above mount point + * `secret_token_path` is a path to the file that contains an access token with read and write access to the above mount point * [optional] `ca_path` is the path of the CA file used for SSL verification :material-information: Warning: This example is for testing purposes only: @@ -135,4 +135,3 @@ You must do these steps for every database where you have created the extension. !!! note The key is auto-generated. - :material-information: Info: The key provider configuration is stored in the database catalog in an unencrypted table. See [how to use external reference to parameters](external-parameters.md) to add an extra security layer to your setup. diff --git a/contrib/pg_tde/documentation/docs/wal-encryption.md b/contrib/pg_tde/documentation/docs/wal-encryption.md index a40831fcf110b..21f37ed73ae85 100644 --- a/contrib/pg_tde/documentation/docs/wal-encryption.md +++ b/contrib/pg_tde/documentation/docs/wal-encryption.md @@ -40,7 +40,7 @@ Before turning WAL encryption on, you must follow the steps below to create your === "With HashiCorp Vault" ```sql - SELECT pg_tde_add_global_key_provider_vault_v2('provider-name', 'secret_token', 'url', 'mount', 'ca_path'); + SELECT pg_tde_add_global_key_provider_vault_v2('provider-name', 'secret_token_path', 'url', 'mount', 'ca_path'); ``` where: @@ -48,7 +48,7 @@ Before turning WAL encryption on, you must follow the steps below to create your * `provider-name` is the name you define for the key provider * `url` is the URL of the Vault server * `mount` is the mount point where the keyring should store the keys - * `secret_token` is an access token with read and write access to the above mount point + * `secret_token_path` is a path to the file that contains an access token with read and write access to the above mount point * [optional] `ca_path` is the path of the CA file used for SSL verification === "With keyring file" diff --git a/contrib/pg_tde/documentation/mkdocs.yml b/contrib/pg_tde/documentation/mkdocs.yml index f0a31fda328e8..b087c856aca9d 100644 --- a/contrib/pg_tde/documentation/mkdocs.yml +++ b/contrib/pg_tde/documentation/mkdocs.yml @@ -188,7 +188,6 @@ nav: - "pg_checksums": command-line-tools/pg-tde-checksums.md - "Uninstall pg_tde": how-to/uninstall.md - "Configure Multi-tenancy": how-to/multi-tenant-setup.md - - "Use Reference to External Parameters": how-to/external-parameters.md - "Decrypt an Encrypted Table": how-to/decrypt.md - faq.md - "Release Notes": diff --git a/contrib/pg_tde/expected/key_provider.out b/contrib/pg_tde/expected/key_provider.out index 587c0665e7680..47ba57bdca8de 100644 --- a/contrib/pg_tde/expected/key_provider.out +++ b/contrib/pg_tde/expected/key_provider.out @@ -3,7 +3,7 @@ SELECT * FROM pg_tde_key_info(); ERROR: Principal key does not exists for the database HINT: Use set_key interface to set the principal key SELECT pg_tde_add_database_key_provider_file('incorrect-file-provider', json_object('foo' VALUE '/tmp/pg_tde_test_keyring.per')); -ERROR: unexpected field "foo" for external value "path" +ERROR: key provider value cannot be an object SELECT pg_tde_add_database_key_provider_file('file-provider','/tmp/pg_tde_test_keyring.per'); pg_tde_add_database_key_provider_file --------------------------------------- @@ -49,7 +49,7 @@ SELECT * FROM pg_tde_list_all_database_key_providers(); (2 rows) SELECT pg_tde_change_database_key_provider_file('file-provider', json_object('foo' VALUE '/tmp/pg_tde_test_keyring.per')); -ERROR: unexpected field "foo" for external value "path" +ERROR: key provider value cannot be an object SELECT * FROM pg_tde_list_all_database_key_providers(); id | provider_name | provider_type | options ----+----------------+---------------+-------------------------------------------- @@ -177,33 +177,13 @@ SELECT pg_tde_add_database_key_provider('file', 'provider', 'true'); ERROR: key provider options must be an object SELECT pg_tde_add_database_key_provider('file', 'provider', 'null'); ERROR: key provider options must be an object --- Creating key providers fails if an external value object doesn't have all required keys +-- Creating key providers fails if vaules are not scalar SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": {}}'); -ERROR: external value must contain "type" in field "path" -SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": {"type": null}}'); -ERROR: external value must contain "type" in field "path" -SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": {"type": "remote"}}'); -ERROR: external remote value must contain "url" in field "path" -SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": {"type": "remote", "url": null}}'); -ERROR: external remote value must contain "url" in field "path" -SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": {"type": "file"}}'); -ERROR: external file value must contain "path" in field "path" -SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": {"type": "file", "path": null}}'); -ERROR: external file value must contain "path" in field "path" --- Creating key providers fails if values are array instead of scalar +ERROR: key provider value cannot be an object SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": ["array"]}'); ERROR: unexpected array in field "path" -SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": {"type": ["array"]}}'); -ERROR: unexpected array in field "path" -SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": {"type": "file", "path": ["array"]}}'); -ERROR: unexpected array in field "path" --- Creating key providers fails if values are boolean SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": true}'); ERROR: unexpected boolean in field "path" -SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": {"type": true}}'); -ERROR: unexpected boolean in field "path" -SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": {"type": "file", "path": true}}'); -ERROR: unexpected boolean in field "path" -- Modifying key providers fails if any required parameter is NULL SELECT pg_tde_change_database_key_provider(NULL, 'file-keyring', '{}'); ERROR: provider type cannot be null @@ -231,33 +211,13 @@ SELECT pg_tde_change_database_key_provider('file', 'file-provider', 'true'); ERROR: key provider options must be an object SELECT pg_tde_change_database_key_provider('file', 'file-provider', 'null'); ERROR: key provider options must be an object --- Modifying key providers fails if an external value object doesn't have all required keys +-- Modifying key providers fails if vaules are not scalar SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {}}'); -ERROR: external value must contain "type" in field "path" -SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": null}}'); -ERROR: external value must contain "type" in field "path" -SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": "remote"}}'); -ERROR: external remote value must contain "url" in field "path" -SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": "remote", "url": null}}'); -ERROR: external remote value must contain "url" in field "path" -SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": "file"}}'); -ERROR: external file value must contain "path" in field "path" -SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": "file", "path": null}}'); -ERROR: external file value must contain "path" in field "path" --- Modifying key providers fails if values are array instead of scalar +ERROR: key provider value cannot be an object SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": ["array"]}'); ERROR: unexpected array in field "path" -SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": ["array"]}}'); -ERROR: unexpected array in field "path" -SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": "file", "path": ["array"]}}'); -ERROR: unexpected array in field "path" --- Modifying key providers fails if values are boolean SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": true}'); ERROR: unexpected boolean in field "path" -SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": true}}'); -ERROR: unexpected boolean in field "path" -SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": "file", "path": true}}'); -ERROR: unexpected boolean in field "path" -- Modifying key providers fails if new settings can't fetch existing server key SELECT pg_tde_add_global_key_provider_file('global-provider', '/tmp/global-provider-file-1'); pg_tde_add_global_key_provider_file diff --git a/contrib/pg_tde/expected/vault_v2_test.out b/contrib/pg_tde/expected/vault_v2_test.out index 6c2766f6894e0..7042a6fa43642 100644 --- a/contrib/pg_tde/expected/vault_v2_test.out +++ b/contrib/pg_tde/expected/vault_v2_test.out @@ -1,6 +1,6 @@ CREATE EXTENSION IF NOT EXISTS pg_tde; -\getenv root_token ROOT_TOKEN -SELECT pg_tde_add_database_key_provider_vault_v2('vault-incorrect',:'root_token','http://127.0.0.1:8200','DUMMY-TOKEN',NULL); +\getenv root_token_file ROOT_TOKEN_FILE +SELECT pg_tde_add_database_key_provider_vault_v2('vault-incorrect',:'root_token_file','http://127.0.0.1:8200','DUMMY-TOKEN',NULL); pg_tde_add_database_key_provider_vault_v2 ------------------------------------------- @@ -16,7 +16,7 @@ CREATE TABLE test_enc( ) USING tde_heap; ERROR: principal key not configured HINT: create one using pg_tde_set_key before using encrypted tables -SELECT pg_tde_add_database_key_provider_vault_v2('vault-v2',:'root_token','http://127.0.0.1:8200','secret',NULL); +SELECT pg_tde_add_database_key_provider_vault_v2('vault-v2',:'root_token_file','http://127.0.0.1:8200','secret',NULL); pg_tde_add_database_key_provider_vault_v2 ------------------------------------------- @@ -52,6 +52,6 @@ SELECT pg_tde_verify_key(); DROP TABLE test_enc; -- Creating provider fails if we can't connect to vault -SELECT pg_tde_add_database_key_provider_vault_v2('will-not-work', :'root_token', 'http://127.0.0.1:61', 'secret', NULL); +SELECT pg_tde_add_database_key_provider_vault_v2('will-not-work', :'root_token_file', 'http://127.0.0.1:61', 'secret', NULL); ERROR: HTTP(S) request to keyring provider "will-not-work" failed DROP EXTENSION pg_tde; diff --git a/contrib/pg_tde/meson.build b/contrib/pg_tde/meson.build index f5709c08706dd..7cfa87c353036 100644 --- a/contrib/pg_tde/meson.build +++ b/contrib/pg_tde/meson.build @@ -105,20 +105,17 @@ sql_tests = [ tap_tests = [ 't/001_basic.pl', 't/002_rotate_key.pl', - 't/003_remote_config.pl', - 't/004_file_config.pl', - 't/005_multiple_extensions.pl', - 't/006_remote_vault_config.pl', - 't/007_tde_heap.pl', - 't/008_key_rotate_tablespace.pl', - 't/009_wal_encrypt.pl', - 't/010_change_key_provider.pl', - 't/011_unlogged_tables.pl', - 't/012_replication.pl', - 't/013_crash_recovery.pl', - 't/014_pg_waldump_basic.pl', - 't/015_pg_waldump_fullpage.pl', - 't/016_pg_tde_change_key_provider.pl', + 't/003_multiple_extensions.pl', + 't/004_tde_heap.pl', + 't/005_key_rotate_tablespace.pl', + 't/006_wal_encrypt.pl', + 't/007_change_key_provider.pl', + 't/008_unlogged_tables.pl', + 't/009_replication.pl', + 't/010_crash_recovery.pl', + 't/011_pg_waldump_basic.pl', + 't/012_pg_waldump_fullpage.pl', + 't/013_pg_tde_change_key_provider.pl', ] tests += { diff --git a/contrib/pg_tde/pg_tde--1.0-rc.sql b/contrib/pg_tde/pg_tde--1.0-rc.sql index 352ca049f636f..909543f5fe2eb 100644 --- a/contrib/pg_tde/pg_tde--1.0-rc.sql +++ b/contrib/pg_tde/pg_tde--1.0-rc.sql @@ -31,7 +31,7 @@ BEGIN ATOMIC END; CREATE FUNCTION pg_tde_add_database_key_provider_vault_v2(provider_name TEXT, - vault_token TEXT, + vault_token_path TEXT, vault_url TEXT, vault_mount_path TEXT, vault_ca_path TEXT) @@ -42,28 +42,11 @@ BEGIN ATOMIC -- load_vaultV2_keyring_provider_options function. SELECT pg_tde_add_database_key_provider('vault-v2', provider_name, json_object('url' VALUE COALESCE(vault_url, ''), - 'token' VALUE COALESCE(vault_token, ''), + 'tokenPath' VALUE COALESCE(vault_token_path, ''), 'mountPath' VALUE COALESCE(vault_mount_path, ''), 'caPath' VALUE COALESCE(vault_ca_path, ''))); END; -CREATE FUNCTION pg_tde_add_database_key_provider_vault_v2(provider_name TEXT, - vault_token JSON, - vault_url JSON, - vault_mount_path JSON, - vault_ca_path JSON) -RETURNS VOID -LANGUAGE SQL -BEGIN ATOMIC - -- JSON keys in the options must be matched to the keys in - -- load_vaultV2_keyring_provider_options function. - SELECT pg_tde_add_database_key_provider('vault-v2', provider_name, - json_object('url' VALUE vault_url, - 'token' VALUE vault_token, - 'mountPath' VALUE vault_mount_path, - 'caPath' VALUE vault_ca_path)); -END; - CREATE FUNCTION pg_tde_add_database_key_provider_kmip(provider_name TEXT, kmip_host TEXT, kmip_port INT, @@ -83,25 +66,6 @@ BEGIN ATOMIC 'keyPath' VALUE COALESCE(kmip_key_path, ''))); END; -CREATE FUNCTION pg_tde_add_database_key_provider_kmip(provider_name TEXT, - kmip_host JSON, - kmip_port JSON, - kmip_ca_path JSON, - kmip_cert_path JSON, - kmip_key_path JSON) -RETURNS VOID -LANGUAGE SQL -BEGIN ATOMIC - -- JSON keys in the options must be matched to the keys in - -- load_kmip_keyring_provider_options function. - SELECT pg_tde_add_database_key_provider('kmip', provider_name, - json_object('host' VALUE kmip_host, - 'port' VALUE kmip_port, - 'caPath' VALUE kmip_ca_path, - 'certPath' VALUE kmip_cert_path, - 'keyPath' VALUE kmip_key_path)); -END; - CREATE FUNCTION pg_tde_list_all_database_key_providers (OUT id INT, OUT provider_name TEXT, @@ -150,7 +114,7 @@ BEGIN ATOMIC END; CREATE FUNCTION pg_tde_add_global_key_provider_vault_v2(provider_name TEXT, - vault_token TEXT, + vault_token_path TEXT, vault_url TEXT, vault_mount_path TEXT, vault_ca_path TEXT) @@ -161,28 +125,11 @@ BEGIN ATOMIC -- load_vaultV2_keyring_provider_options function. SELECT pg_tde_add_global_key_provider('vault-v2', provider_name, json_object('url' VALUE COALESCE(vault_url, ''), - 'token' VALUE COALESCE(vault_token, ''), + 'tokenPath' VALUE COALESCE(vault_token_path, ''), 'mountPath' VALUE COALESCE(vault_mount_path, ''), 'caPath' VALUE COALESCE(vault_ca_path, ''))); END; -CREATE FUNCTION pg_tde_add_global_key_provider_vault_v2(provider_name TEXT, - vault_token JSON, - vault_url JSON, - vault_mount_path JSON, - vault_ca_path JSON) -RETURNS VOID -LANGUAGE SQL -BEGIN ATOMIC - -- JSON keys in the options must be matched to the keys in - -- load_vaultV2_keyring_provider_options function. - SELECT pg_tde_add_global_key_provider('vault-v2', provider_name, - json_object('url' VALUE vault_url, - 'token' VALUE vault_token, - 'mountPath' VALUE vault_mount_path, - 'caPath' VALUE vault_ca_path)); -END; - CREATE FUNCTION pg_tde_add_global_key_provider_kmip(provider_name TEXT, kmip_host TEXT, kmip_port INT, @@ -202,25 +149,6 @@ BEGIN ATOMIC 'keyPath' VALUE COALESCE(kmip_key_path, ''))); END; -CREATE FUNCTION pg_tde_add_global_key_provider_kmip(provider_name TEXT, - kmip_host JSON, - kmip_port JSON, - kmip_ca_path JSON, - kmip_cert_path JSON, - kmip_key_path JSON) -RETURNS VOID -LANGUAGE SQL -BEGIN ATOMIC - -- JSON keys in the options must be matched to the keys in - -- load_kmip_keyring_provider_options function. - SELECT pg_tde_add_global_key_provider('vault-v2', provider_name, - json_object('host' VALUE kmip_host, - 'port' VALUE kmip_port, - 'caPath' VALUE kmip_ca_path, - 'certPath' VALUE kmip_cert_path, - 'keyPath' VALUE kmip_key_path)); -END; - -- Key Provider Management CREATE FUNCTION pg_tde_change_database_key_provider(provider_type TEXT, provider_name TEXT, options JSON) RETURNS VOID @@ -249,7 +177,7 @@ BEGIN ATOMIC END; CREATE FUNCTION pg_tde_change_database_key_provider_vault_v2(provider_name TEXT, - vault_token TEXT, + vault_token_path TEXT, vault_url TEXT, vault_mount_path TEXT, vault_ca_path TEXT) @@ -260,28 +188,11 @@ BEGIN ATOMIC -- load_vaultV2_keyring_provider_options function. SELECT pg_tde_change_database_key_provider('vault-v2', provider_name, json_object('url' VALUE COALESCE(vault_url, ''), - 'token' VALUE COALESCE(vault_token, ''), + 'tokenPath' VALUE COALESCE(vault_token_path, ''), 'mountPath' VALUE COALESCE(vault_mount_path, ''), 'caPath' VALUE COALESCE(vault_ca_path, ''))); END; -CREATE FUNCTION pg_tde_change_database_key_provider_vault_v2(provider_name TEXT, - vault_token JSON, - vault_url JSON, - vault_mount_path JSON, - vault_ca_path JSON) -RETURNS VOID -LANGUAGE SQL -BEGIN ATOMIC - -- JSON keys in the options must be matched to the keys in - -- load_vaultV2_keyring_provider_options function. - SELECT pg_tde_change_database_key_provider('vault-v2', provider_name, - json_object('url' VALUE vault_url, - 'token' VALUE vault_token, - 'mountPath' VALUE vault_mount_path, - 'caPath' VALUE vault_ca_path)); -END; - CREATE FUNCTION pg_tde_change_database_key_provider_kmip(provider_name TEXT, kmip_host TEXT, kmip_port INT, @@ -301,25 +212,6 @@ BEGIN ATOMIC 'keyPath' VALUE COALESCE(kmip_key_path, ''))); END; -CREATE FUNCTION pg_tde_change_database_key_provider_kmip(provider_name TEXT, - kmip_host JSON, - kmip_port JSON, - kmip_ca_path JSON, - kmip_cert_path JSON, - kmip_key_path JSON) -RETURNS VOID -LANGUAGE SQL -BEGIN ATOMIC - -- JSON keys in the options must be matched to the keys in - -- load_kmip_keyring_provider_options function. - SELECT pg_tde_change_database_key_provider('kmip', provider_name, - json_object('host' VALUE kmip_host, - 'port' VALUE kmip_port, - 'caPath' VALUE kmip_ca_path, - 'certPath' VALUE kmip_cert_path, - 'keyPath' VALUE kmip_key_path)); -END; - -- Global Tablespace Key Provider Management CREATE FUNCTION pg_tde_change_global_key_provider(provider_type TEXT, provider_name TEXT, options JSON) RETURNS VOID @@ -348,7 +240,7 @@ BEGIN ATOMIC END; CREATE FUNCTION pg_tde_change_global_key_provider_vault_v2(provider_name TEXT, - vault_token TEXT, + vault_token_path TEXT, vault_url TEXT, vault_mount_path TEXT, vault_ca_path TEXT) @@ -359,28 +251,11 @@ BEGIN ATOMIC -- load_vaultV2_keyring_provider_options function. SELECT pg_tde_change_global_key_provider('vault-v2', provider_name, json_object('url' VALUE COALESCE(vault_url, ''), - 'token' VALUE COALESCE(vault_token, ''), + 'tokenPath' VALUE COALESCE(vault_token_path, ''), 'mountPath' VALUE COALESCE(vault_mount_path, ''), 'caPath' VALUE COALESCE(vault_ca_path, ''))); END; -CREATE FUNCTION pg_tde_change_global_key_provider_vault_v2(provider_name TEXT, - vault_token JSON, - vault_url JSON, - vault_mount_path JSON, - vault_ca_path JSON) -RETURNS VOID -LANGUAGE SQL -BEGIN ATOMIC - -- JSON keys in the options must be matched to the keys in - -- load_vaultV2_keyring_provider_options function. - SELECT pg_tde_change_global_key_provider('vault-v2', provider_name, - json_object('url' VALUE vault_url, - 'token' VALUE vault_token, - 'mountPath' VALUE vault_mount_path, - 'caPath' VALUE vault_ca_path)); -END; - CREATE FUNCTION pg_tde_change_global_key_provider_kmip(provider_name TEXT, kmip_host TEXT, kmip_port INT, @@ -400,25 +275,6 @@ BEGIN ATOMIC 'keyPath' VALUE COALESCE(kmip_key_path, ''))); END; -CREATE FUNCTION pg_tde_change_global_key_provider_kmip(provider_name TEXT, - kmip_host JSON, - kmip_port JSON, - kmip_ca_path JSON, - kmip_cert_path JSON, - kmip_key_path JSON) -RETURNS VOID -LANGUAGE SQL -BEGIN ATOMIC - -- JSON keys in the options must be matched to the keys in - -- load_kmip_keyring_provider_options function. - SELECT pg_tde_change_global_key_provider('kmip', provider_name, - json_object('host' VALUE kmip_host, - 'port' VALUE kmip_port, - 'caPath' VALUE kmip_ca_path, - 'certPath' VALUE kmip_cert_path, - 'keyPath' VALUE kmip_key_path)); -END; - CREATE FUNCTION pg_tde_is_encrypted(relation REGCLASS) RETURNS BOOLEAN STRICT diff --git a/contrib/pg_tde/sql/key_provider.sql b/contrib/pg_tde/sql/key_provider.sql index ee844af0fada6..819da4d61cb6b 100644 --- a/contrib/pg_tde/sql/key_provider.sql +++ b/contrib/pg_tde/sql/key_provider.sql @@ -73,23 +73,10 @@ SELECT pg_tde_add_database_key_provider('file', 'provider', '["array"]'); SELECT pg_tde_add_database_key_provider('file', 'provider', 'true'); SELECT pg_tde_add_database_key_provider('file', 'provider', 'null'); --- Creating key providers fails if an external value object doesn't have all required keys +-- Creating key providers fails if vaules are not scalar SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": {}}'); -SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": {"type": null}}'); -SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": {"type": "remote"}}'); -SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": {"type": "remote", "url": null}}'); -SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": {"type": "file"}}'); -SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": {"type": "file", "path": null}}'); - --- Creating key providers fails if values are array instead of scalar SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": ["array"]}'); -SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": {"type": ["array"]}}'); -SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": {"type": "file", "path": ["array"]}}'); - --- Creating key providers fails if values are boolean SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": true}'); -SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": {"type": true}}'); -SELECT pg_tde_add_database_key_provider('file', 'provider', '{"path": {"type": "file", "path": true}}'); -- Modifying key providers fails if any required parameter is NULL SELECT pg_tde_change_database_key_provider(NULL, 'file-keyring', '{}'); @@ -109,23 +96,10 @@ SELECT pg_tde_change_database_key_provider('file', 'file-provider', '["array"]') SELECT pg_tde_change_database_key_provider('file', 'file-provider', 'true'); SELECT pg_tde_change_database_key_provider('file', 'file-provider', 'null'); --- Modifying key providers fails if an external value object doesn't have all required keys +-- Modifying key providers fails if vaules are not scalar SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {}}'); -SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": null}}'); -SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": "remote"}}'); -SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": "remote", "url": null}}'); -SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": "file"}}'); -SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": "file", "path": null}}'); - --- Modifying key providers fails if values are array instead of scalar SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": ["array"]}'); -SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": ["array"]}}'); -SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": "file", "path": ["array"]}}'); - --- Modifying key providers fails if values are boolean SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": true}'); -SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": true}}'); -SELECT pg_tde_change_database_key_provider('file', 'file-provider', '{"path": {"type": "file", "path": true}}'); -- Modifying key providers fails if new settings can't fetch existing server key SELECT pg_tde_add_global_key_provider_file('global-provider', '/tmp/global-provider-file-1'); diff --git a/contrib/pg_tde/sql/vault_v2_test.sql b/contrib/pg_tde/sql/vault_v2_test.sql index 205aa1118533f..d0cce4719fccd 100644 --- a/contrib/pg_tde/sql/vault_v2_test.sql +++ b/contrib/pg_tde/sql/vault_v2_test.sql @@ -1,8 +1,8 @@ CREATE EXTENSION IF NOT EXISTS pg_tde; -\getenv root_token ROOT_TOKEN +\getenv root_token_file ROOT_TOKEN_FILE -SELECT pg_tde_add_database_key_provider_vault_v2('vault-incorrect',:'root_token','http://127.0.0.1:8200','DUMMY-TOKEN',NULL); +SELECT pg_tde_add_database_key_provider_vault_v2('vault-incorrect',:'root_token_file','http://127.0.0.1:8200','DUMMY-TOKEN',NULL); -- FAILS SELECT pg_tde_set_key_using_database_key_provider('vault-v2-key','vault-incorrect'); @@ -12,7 +12,7 @@ CREATE TABLE test_enc( PRIMARY KEY (id) ) USING tde_heap; -SELECT pg_tde_add_database_key_provider_vault_v2('vault-v2',:'root_token','http://127.0.0.1:8200','secret',NULL); +SELECT pg_tde_add_database_key_provider_vault_v2('vault-v2',:'root_token_file','http://127.0.0.1:8200','secret',NULL); SELECT pg_tde_set_key_using_database_key_provider('vault-v2-key','vault-v2'); CREATE TABLE test_enc( @@ -32,6 +32,6 @@ SELECT pg_tde_verify_key(); DROP TABLE test_enc; -- Creating provider fails if we can't connect to vault -SELECT pg_tde_add_database_key_provider_vault_v2('will-not-work', :'root_token', 'http://127.0.0.1:61', 'secret', NULL); +SELECT pg_tde_add_database_key_provider_vault_v2('will-not-work', :'root_token_file', 'http://127.0.0.1:61', 'secret', NULL); DROP EXTENSION pg_tde; diff --git a/contrib/pg_tde/src/catalog/tde_keyring.c b/contrib/pg_tde/src/catalog/tde_keyring.c index 5004034de7d33..b4043e476720d 100644 --- a/contrib/pg_tde/src/catalog/tde_keyring.c +++ b/contrib/pg_tde/src/catalog/tde_keyring.c @@ -23,6 +23,7 @@ #include "utils/fmgroids.h" #include "common/pg_tde_utils.h" #include "miscadmin.h" +#include "storage/fd.h" #include "unistd.h" #include "utils/builtins.h" #include "pg_tde.h" @@ -62,6 +63,7 @@ static GenericKeyring *load_keyring_provider_options(ProviderType provider_type, static KmipKeyring *load_kmip_keyring_provider_options(char *keyring_options); static VaultV2Keyring *load_vaultV2_keyring_provider_options(char *keyring_options); static int open_keyring_infofile(Oid dbOid, int flags); +static char *get_file_value(const char *path, const char *field_name); #ifdef FRONTEND @@ -870,19 +872,22 @@ load_vaultV2_keyring_provider_options(char *keyring_options) (GenericKeyring *) vaultV2_keyring, keyring_options, strlen(keyring_options)); - if (vaultV2_keyring->vault_token == NULL || vaultV2_keyring->vault_token[0] == '\0' || + if (vaultV2_keyring->vault_token_path == NULL || vaultV2_keyring->vault_token_path[0] == '\0' || vaultV2_keyring->vault_url == NULL || vaultV2_keyring->vault_url[0] == '\0' || vaultV2_keyring->vault_mount_path == NULL || vaultV2_keyring->vault_mount_path[0] == '\0') { ereport(WARNING, errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("missing in the keyring options:%s%s%s", - (vaultV2_keyring->vault_token != NULL && vaultV2_keyring->vault_token[0] != '\0') ? "" : " token", + (vaultV2_keyring->vault_token_path != NULL && vaultV2_keyring->vault_token_path[0] != '\0') ? "" : " tokenPath", (vaultV2_keyring->vault_url != NULL && vaultV2_keyring->vault_url[0] != '\0') ? "" : " url", (vaultV2_keyring->vault_mount_path != NULL && vaultV2_keyring->vault_mount_path[0] != '\0') ? "" : " mountPath")); return NULL; } + /* TODO: the vault_token mem should be protected from paging to the swap */ + vaultV2_keyring->vault_token = get_file_value(vaultV2_keyring->vault_token_path, "vault_token"); + return vaultV2_keyring; } @@ -916,6 +921,36 @@ load_kmip_keyring_provider_options(char *keyring_options) return kmip_keyring; } +#define MAX_FILE_DATA_LENGTH 1024 + +static char * +get_file_value(const char *path, const char *field_name) +{ + FILE *fd; + char *val; + + fd = AllocateFile(path, "r"); + if (fd == NULL) + { + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not open file \"%s\" for \"%s\": %m", path, field_name))); + } + + val = palloc(MAX_FILE_DATA_LENGTH); + if (fgets(val, MAX_FILE_DATA_LENGTH, fd) == NULL && ferror(fd)) + { + ereport(ERROR, + (errcode_for_file_access(), + errmsg("could not read file \"%s\" for \"%s\": %m", path, field_name))); + } + /* remove trailing whitespace */ + val[strcspn(val, " \t\n\r")] = '\0'; + + FreeFile(fd); + return val; +} + static void debug_print_kerying(GenericKeyring *keyring) { @@ -928,7 +963,7 @@ debug_print_kerying(GenericKeyring *keyring) elog(DEBUG2, "File Keyring Path: %s", ((FileKeyring *) keyring)->file_name); break; case VAULT_V2_KEY_PROVIDER: - elog(DEBUG2, "Vault Keyring Token: %s", ((VaultV2Keyring *) keyring)->vault_token); + elog(DEBUG2, "Vault Keyring Token Path: %s", ((VaultV2Keyring *) keyring)->vault_token_path); elog(DEBUG2, "Vault Keyring URL: %s", ((VaultV2Keyring *) keyring)->vault_url); elog(DEBUG2, "Vault Keyring Mount Path: %s", ((VaultV2Keyring *) keyring)->vault_mount_path); elog(DEBUG2, "Vault Keyring CA Path: %s", ((VaultV2Keyring *) keyring)->vault_ca_path); diff --git a/contrib/pg_tde/src/catalog/tde_keyring_parse_opts.c b/contrib/pg_tde/src/catalog/tde_keyring_parse_opts.c index 38a67ba0c78ea..7414da764f27d 100644 --- a/contrib/pg_tde/src/catalog/tde_keyring_parse_opts.c +++ b/contrib/pg_tde/src/catalog/tde_keyring_parse_opts.c @@ -3,17 +3,7 @@ * tde_keyring_parse_opts.c * Parser routines for the keyring JSON options * - * Each value in the JSON document can be either scalar (string) - a value itself - * or a reference to the external object that contains the value. - * - * Examples: - * {"path" : "/tmp/keyring_data_file"} - * {"path" : {"type" : "file", "path" : "/tmp/datafile-location"}} - * in the latter one, /tmp/datafile-location contains not keyring data but the - * location of such. - * - * A field type can be "file", in this case, we expect "path" field. Or "remote", - * when "url" field is expected. + * We expect one-dimentional JSON object with scalar fields * * IDENTIFICATION * contrib/pg_tde/src/catalog/tde_keyring_parse_opts.c @@ -22,49 +12,33 @@ */ #include "postgres.h" -#include "common/file_perm.h" #include "common/jsonapi.h" #include "mb/pg_wchar.h" -#include "storage/fd.h" #include "utils/jsonfuncs.h" #include "catalog/tde_keyring.h" -#include "keyring/keyring_curl.h" #ifdef FRONTEND #include "pg_tde_fe.h" #endif -#include - -#define MAX_CONFIG_FILE_DATA_LENGTH 1024 - /* * JSON parser state */ typedef enum JsonKeyringSemState { JK_EXPECT_TOP_LEVEL_OBJECT, - JK_EXPECT_TOP_FIELD, - JK_EXPECT_EXTERN_VAL, + JK_EXPECT_FIELD, } JsonKeyringSemState; -#define KEYRING_REMOTE_FIELD_TYPE "remote" -#define KEYRING_FILE_FIELD_TYPE "file" - typedef enum JsonKeyringField { JK_FIELD_UNKNOWN, - /* These are for the objects that can point to a file or a remote url. */ - JK_FIELD_TYPE, - JK_FIELD_URL, - JK_FIELD_PATH, - /* Settings specific for the individual key provider types. */ JK_FILE_PATH, - JK_VAULT_TOKEN, + JK_VAULT_TOKEN_PATH, JK_VAULT_URL, JK_VAULT_MOUNT_PATH, JK_VAULT_CA_PATH, @@ -82,10 +56,6 @@ typedef enum JsonKeyringField static const char *JK_FIELD_NAMES[JK_FIELDS_TOTAL] = { [JK_FIELD_UNKNOWN] = "unknownField", - [JK_FIELD_TYPE] = "type", - [JK_FIELD_URL] = "url", - [JK_FIELD_PATH] = "path", - /* * These values should match pg_tde_add_database_key_provider_vault_v2, * pg_tde_add_database_key_provider_file and @@ -93,7 +63,7 @@ static const char *JK_FIELD_NAMES[JK_FIELDS_TOTAL] = { */ [JK_FILE_PATH] = "path", - [JK_VAULT_TOKEN] = "token", + [JK_VAULT_TOKEN_PATH] = "tokenPath", [JK_VAULT_URL] = "url", [JK_VAULT_MOUNT_PATH] = "mountPath", [JK_VAULT_CA_PATH] = "caPath", @@ -112,33 +82,17 @@ typedef struct JsonKeyringState /* Caller's options to be set from JSON values. */ GenericKeyring *provider_opts; - /* The current field in the top level object */ - JsonKeyringField top_level_field; - - /* Current field in any external field object, if any. */ - JsonKeyringField extern_field; + JsonKeyringField current_field; JsonKeyringSemState state; - - /* - * The rest of the scalar fields might be in the JSON document but has no - * direct value for the caller. Although we need them for the values - * extraction or state tracking. - */ - char *field_type; - char *extern_url; - char *extern_path; } JsonKeyringState; static JsonParseErrorType json_kring_scalar(void *state, char *token, JsonTokenType tokentype); static JsonParseErrorType json_kring_array_start(void *state); static JsonParseErrorType json_kring_object_field_start(void *state, char *fname, bool isnull); static JsonParseErrorType json_kring_object_start(void *state); -static JsonParseErrorType json_kring_object_end(void *state); static void json_kring_assign_scalar(JsonKeyringState *parse, JsonKeyringField field, char *value); -static char *get_remote_kring_value(const char *url, const char *field_name); -static char *get_file_kring_value(const char *path, const char *field_name); /* * Parses json input for the given provider type and sets the provided options. @@ -163,7 +117,7 @@ ParseKeyringJSONOptions(ProviderType provider_type, GenericKeyring *out_opts, ch */ sem.semstate = &parse; sem.object_start = json_kring_object_start; - sem.object_end = json_kring_object_end; + sem.object_end = NULL; sem.array_start = json_kring_array_start; sem.array_end = NULL; sem.object_field_start = json_kring_object_field_start; @@ -207,11 +161,10 @@ json_kring_array_start(void *state) errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("key provider options must be an object")); break; - case JK_EXPECT_TOP_FIELD: - case JK_EXPECT_EXTERN_VAL: + case JK_EXPECT_FIELD: ereport(ERROR, errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("unexpected array in field \"%s\"", JK_FIELD_NAMES[parse->top_level_field])); + errmsg("unexpected array in field \"%s\"", JK_FIELD_NAMES[parse->current_field])); break; } @@ -222,11 +175,6 @@ json_kring_array_start(void *state) /* * Invoked at the start of each object in the JSON document. - * - * In the top level object, we expect either scalar (string) values or objects - * referencing the external value of the field. If we are already parsing top - * level fields, we expect an "external field object" e.g. ({"type" : "remote", - * "url" : "http://localhost:8888/hello"}) */ static JsonParseErrorType json_kring_object_start(void *state) @@ -236,100 +184,21 @@ json_kring_object_start(void *state) switch (parse->state) { case JK_EXPECT_TOP_LEVEL_OBJECT: - parse->state = JK_EXPECT_TOP_FIELD; - break; - case JK_EXPECT_TOP_FIELD: - parse->state = JK_EXPECT_EXTERN_VAL; + parse->state = JK_EXPECT_FIELD; break; - case JK_EXPECT_EXTERN_VAL: - Assert(false); - elog(ERROR, "invalid semantic state"); + case JK_EXPECT_FIELD: + elog(ERROR, "key provider value cannot be an object"); break; } return JSON_SUCCESS; } -/* - * Invoked at the end of each object in the JSON document. - * - * If we're done parsing an external field object we fetch the value from the - * source and assign it to the top level object field. - */ -static JsonParseErrorType -json_kring_object_end(void *state) -{ - JsonKeyringState *parse = state; - - /* - * we're done with the nested object and if it's an external field, the - * value should be extracted and assigned to the parent "field". for - * example if : "field" : {"type" : "remote", "url" : - * "http://localhost:8888/hello"} or "field" : {"type" : "file", "path" : - * "/tmp/datafile-location"} the "field"'s value should be the content of - * "path" or "url" respectively - */ - switch (parse->state) - { - case JK_EXPECT_TOP_LEVEL_OBJECT: - Assert(false); - elog(ERROR, "invalid semantic state"); - break; - case JK_EXPECT_TOP_FIELD: - /* We're done parsing the top level object */ - break; - case JK_EXPECT_EXTERN_VAL: - { - char *value = NULL; - - if (!parse->field_type) - ereport(ERROR, - errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("external value must contain \"type\" in field \"%s\"", JK_FIELD_NAMES[parse->top_level_field])); - - if (strcmp(parse->field_type, KEYRING_REMOTE_FIELD_TYPE) == 0) - { - if (!parse->extern_url) - ereport(ERROR, - errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("external remote value must contain \"url\" in field \"%s\"", JK_FIELD_NAMES[parse->top_level_field])); - - value = get_remote_kring_value(parse->extern_url, JK_FIELD_NAMES[parse->top_level_field]); - pfree(parse->extern_url); - parse->extern_url = NULL; - } - if (strcmp(parse->field_type, KEYRING_FILE_FIELD_TYPE) == 0) - { - if (!parse->extern_path) - ereport(ERROR, - errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("external file value must contain \"path\" in field \"%s\"", JK_FIELD_NAMES[parse->top_level_field])); - - value = get_file_kring_value(parse->extern_path, JK_FIELD_NAMES[parse->top_level_field]); - pfree(parse->extern_path); - parse->extern_path = NULL; - } - - pfree(parse->field_type); - parse->field_type = NULL; - - Assert(value != NULL); - - json_kring_assign_scalar(parse, parse->top_level_field, value); - parse->state = JK_EXPECT_TOP_FIELD; - break; - } - } - - return JSON_SUCCESS; -} - /* * Invoked at the start of each object field in the JSON document. * - * Based on the given field name and the semantic state (we expect a top-level - * field or an external object) we set the state so that when we get the value, - * we know what is it and where to assign it. + * Based on the given field name and the semantic state we set the state so + * that when we get the value, we know what is it and where to assign it. */ static JsonParseErrorType json_kring_object_field_start(void *state, char *fname, bool isnull) @@ -342,15 +211,15 @@ json_kring_object_field_start(void *state, char *fname, bool isnull) Assert(false); elog(ERROR, "invalid semantic state"); break; - case JK_EXPECT_TOP_FIELD: + case JK_EXPECT_FIELD: switch (parse->provider_type) { case FILE_KEY_PROVIDER: if (strcmp(fname, JK_FIELD_NAMES[JK_FILE_PATH]) == 0) - parse->top_level_field = JK_FILE_PATH; + parse->current_field = JK_FILE_PATH; else { - parse->top_level_field = JK_FIELD_UNKNOWN; + parse->current_field = JK_FIELD_UNKNOWN; ereport(ERROR, errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("unexpected field \"%s\" for file provider", fname)); @@ -358,17 +227,17 @@ json_kring_object_field_start(void *state, char *fname, bool isnull) break; case VAULT_V2_KEY_PROVIDER: - if (strcmp(fname, JK_FIELD_NAMES[JK_VAULT_TOKEN]) == 0) - parse->top_level_field = JK_VAULT_TOKEN; + if (strcmp(fname, JK_FIELD_NAMES[JK_VAULT_TOKEN_PATH]) == 0) + parse->current_field = JK_VAULT_TOKEN_PATH; else if (strcmp(fname, JK_FIELD_NAMES[JK_VAULT_URL]) == 0) - parse->top_level_field = JK_VAULT_URL; + parse->current_field = JK_VAULT_URL; else if (strcmp(fname, JK_FIELD_NAMES[JK_VAULT_MOUNT_PATH]) == 0) - parse->top_level_field = JK_VAULT_MOUNT_PATH; + parse->current_field = JK_VAULT_MOUNT_PATH; else if (strcmp(fname, JK_FIELD_NAMES[JK_VAULT_CA_PATH]) == 0) - parse->top_level_field = JK_VAULT_CA_PATH; + parse->current_field = JK_VAULT_CA_PATH; else { - parse->top_level_field = JK_FIELD_UNKNOWN; + parse->current_field = JK_FIELD_UNKNOWN; ereport(ERROR, errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("unexpected field \"%s\" for vault-v2 provider", fname)); @@ -377,18 +246,18 @@ json_kring_object_field_start(void *state, char *fname, bool isnull) case KMIP_KEY_PROVIDER: if (strcmp(fname, JK_FIELD_NAMES[JK_KMIP_HOST]) == 0) - parse->top_level_field = JK_KMIP_HOST; + parse->current_field = JK_KMIP_HOST; else if (strcmp(fname, JK_FIELD_NAMES[JK_KMIP_PORT]) == 0) - parse->top_level_field = JK_KMIP_PORT; + parse->current_field = JK_KMIP_PORT; else if (strcmp(fname, JK_FIELD_NAMES[JK_KMIP_CA_PATH]) == 0) - parse->top_level_field = JK_KMIP_CA_PATH; + parse->current_field = JK_KMIP_CA_PATH; else if (strcmp(fname, JK_FIELD_NAMES[JK_KMIP_CERT_PATH]) == 0) - parse->top_level_field = JK_KMIP_CERT_PATH; + parse->current_field = JK_KMIP_CERT_PATH; else if (strcmp(fname, JK_FIELD_NAMES[JK_KMIP_KEY_PATH]) == 0) - parse->top_level_field = JK_KMIP_KEY_PATH; + parse->current_field = JK_KMIP_KEY_PATH; else { - parse->top_level_field = JK_FIELD_UNKNOWN; + parse->current_field = JK_FIELD_UNKNOWN; ereport(ERROR, errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("unexpected field \"%s\" for vault-v2 provider", fname)); @@ -399,22 +268,6 @@ json_kring_object_field_start(void *state, char *fname, bool isnull) return JSON_INVALID_TOKEN; } break; - - case JK_EXPECT_EXTERN_VAL: - if (strcmp(fname, JK_FIELD_NAMES[JK_FIELD_TYPE]) == 0) - parse->extern_field = JK_FIELD_TYPE; - else if (strcmp(fname, JK_FIELD_NAMES[JK_FIELD_URL]) == 0) - parse->extern_field = JK_FIELD_URL; - else if (strcmp(fname, JK_FIELD_NAMES[JK_FIELD_PATH]) == 0) - parse->extern_field = JK_FIELD_PATH; - else - { - parse->extern_field = JK_FIELD_UNKNOWN; - ereport(ERROR, - errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("unexpected field \"%s\" for external value \"%s\"", fname, JK_FIELD_NAMES[parse->top_level_field])); - } - break; } return JSON_SUCCESS; @@ -430,22 +283,13 @@ static JsonParseErrorType json_kring_scalar(void *state, char *token, JsonTokenType tokentype) { JsonKeyringState *parse = state; - JsonKeyringField *field = NULL; char *value; - switch (parse->state) + if (parse->state == JK_EXPECT_TOP_LEVEL_OBJECT) { - case JK_EXPECT_TOP_LEVEL_OBJECT: - ereport(ERROR, - errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("key provider options must be an object")); - break; - case JK_EXPECT_TOP_FIELD: - field = &parse->top_level_field; - break; - case JK_EXPECT_EXTERN_VAL: - field = &parse->extern_field; - break; + ereport(ERROR, + errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("key provider options must be an object")); } switch (tokentype) @@ -458,7 +302,7 @@ json_kring_scalar(void *state, char *token, JsonTokenType tokentype) case JSON_TOKEN_FALSE: ereport(ERROR, errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("unexpected boolean in field \"%s\"", JK_FIELD_NAMES[parse->top_level_field])); + errmsg("unexpected boolean in field \"%s\"", JK_FIELD_NAMES[parse->current_field])); break; case JSON_TOKEN_NULL: value = NULL; @@ -470,7 +314,7 @@ json_kring_scalar(void *state, char *token, JsonTokenType tokentype) break; } - json_kring_assign_scalar(parse, *field, value); + json_kring_assign_scalar(parse, parse->current_field, value); return JSON_SUCCESS; } @@ -484,22 +328,12 @@ json_kring_assign_scalar(JsonKeyringState *parse, JsonKeyringField field, char * switch (field) { - case JK_FIELD_TYPE: - parse->field_type = value; - break; - case JK_FIELD_URL: - parse->extern_url = value; - break; - case JK_FIELD_PATH: - parse->extern_path = value; - break; - case JK_FILE_PATH: file->file_name = value; break; - case JK_VAULT_TOKEN: - vault->vault_token = value; + case JK_VAULT_TOKEN_PATH: + vault->vault_token_path = value; break; case JK_VAULT_URL: vault->vault_url = value; @@ -532,56 +366,3 @@ json_kring_assign_scalar(JsonKeyringState *parse, JsonKeyringField field, char * elog(ERROR, "json keyring: unexpected scalar field %d", field); } } - -static char * -get_remote_kring_value(const char *url, const char *field_name) -{ - long httpCode; - CurlString outStr; - - outStr.ptr = palloc0(1); - outStr.len = 0; - - if (!curlSetupSession(url, NULL, &outStr)) - { - elog(ERROR, "CURL error for remote object \"%s\"", field_name); - } - if (curl_easy_perform(keyringCurl) != CURLE_OK) - { - elog(ERROR, "HTTP request error for remote object \"%s\"", field_name); - } - if (curl_easy_getinfo(keyringCurl, CURLINFO_RESPONSE_CODE, &httpCode) != CURLE_OK) - { - elog(ERROR, "HTTP error for remote object \"%s\", HTTP code \"%li\"", field_name, httpCode); - } - - /* remove trailing whitespace */ - outStr.ptr[strcspn(outStr.ptr, " \t\n\r")] = '\0'; - - return outStr.ptr; -} - -static char * -get_file_kring_value(const char *path, const char *field_name) -{ - int fd = -1; - char *val; - - fd = BasicOpenFile(path, O_RDONLY); - if (fd < 0) - { - elog(ERROR, "failed to open file \"%s\" for \"%s\"", path, field_name); - } - - val = palloc0(MAX_CONFIG_FILE_DATA_LENGTH); - if (pg_pread(fd, val, MAX_CONFIG_FILE_DATA_LENGTH, 0) == -1) - { - close(fd); - elog(ERROR, "failed to read file \"%s\" for \"%s\"", path, field_name); - } - /* remove trailing whitespace */ - val[strcspn(val, " \t\n\r")] = '\0'; - - close(fd); - return val; -} diff --git a/contrib/pg_tde/src/include/keyring/keyring_api.h b/contrib/pg_tde/src/include/keyring/keyring_api.h index ef322709823c5..a137f67f94041 100644 --- a/contrib/pg_tde/src/include/keyring/keyring_api.h +++ b/contrib/pg_tde/src/include/keyring/keyring_api.h @@ -74,6 +74,7 @@ typedef struct VaultV2Keyring { GenericKeyring keyring; /* Must be the first field */ char *vault_token; + char *vault_token_path; char *vault_url; char *vault_ca_path; char *vault_mount_path; diff --git a/contrib/pg_tde/src/include/pg_tde_fe.h b/contrib/pg_tde/src/include/pg_tde_fe.h index da5631ac75159..53269ea9123be 100644 --- a/contrib/pg_tde/src/include/pg_tde_fe.h +++ b/contrib/pg_tde/src/include/pg_tde_fe.h @@ -86,6 +86,8 @@ static int tde_fe_error_level = 0; #define tde_lwlock_enc_keys() NULL #define BasicOpenFile(fileName, fileFlags) open(fileName, fileFlags, PG_FILE_MODE_OWNER) +#define AllocateFile(name, mode) fopen(name, mode) +#define FreeFile(file) fclose(file) #define pg_fsync(fd) fsync(fd) #endif /* FRONTEND */ diff --git a/contrib/pg_tde/src/pg_tde_change_key_provider.c b/contrib/pg_tde/src/pg_tde_change_key_provider.c index be3e37c1519d2..341c182e93e51 100644 --- a/contrib/pg_tde/src/pg_tde_change_key_provider.c +++ b/contrib/pg_tde/src/pg_tde_change_key_provider.c @@ -27,7 +27,7 @@ help(void) puts("Depending on the provider type, the complete parameter list is:"); puts(""); puts("pg_tde_change_key_provider [-D ] file "); - puts("pg_tde_change_key_provider [-D ] vault-v2 []"); + puts("pg_tde_change_key_provider [-D ] vault-v2 []"); puts("pg_tde_change_key_provider [-D ] kmip []"); puts(""); printf("Use dbOid %d for global key providers.\n", GLOBAL_DATA_TDE_OID); @@ -196,7 +196,7 @@ main(int argc, char *argv[]) if (!build_json(json, 4, "url", argv[4 + argstart], - "token", argv[5 + argstart], + "tokenPath", argv[5 + argstart], "mountPath", argv[6 + argstart], "caPath", (argc - argstart > 7 ? argv[7 + argstart] : ""))) { diff --git a/contrib/pg_tde/t/005_multiple_extensions.pl b/contrib/pg_tde/t/003_multiple_extensions.pl similarity index 100% rename from contrib/pg_tde/t/005_multiple_extensions.pl rename to contrib/pg_tde/t/003_multiple_extensions.pl diff --git a/contrib/pg_tde/t/003_remote_config.pl b/contrib/pg_tde/t/003_remote_config.pl deleted file mode 100644 index d3fbfa677ca95..0000000000000 --- a/contrib/pg_tde/t/003_remote_config.pl +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; -use File::Basename; -use Test::More; -use lib 't'; -use pgtde; - -{ - - package MyWebServer; - - use HTTP::Server::Simple::CGI; - use base qw(HTTP::Server::Simple::CGI); - - my %dispatch = ('/hello' => \&resp_hello,); - - sub handle_request - { - my $self = shift; - my $cgi = shift; - - my $path = $cgi->path_info(); - my $handler = $dispatch{$path}; - - if (ref($handler) eq "CODE") - { - print "HTTP/1.0 200 OK\r\n"; - $handler->($cgi); - - } - else - { - print "HTTP/1.0 404 Not found\r\n"; - print $cgi->header, - $cgi->start_html('Not found'), - $cgi->h1('Not found'), - $cgi->end_html; - } - } - - sub resp_hello - { - my $cgi = shift; - print $cgi->header, "/tmp/http_datafile\r\n"; - } - -} - -my $pid = MyWebServer->new(8888)->background(); -END { kill('TERM', $pid); } - -PGTDE::setup_files_dir(basename($0)); - -my $node = PostgreSQL::Test::Cluster->new('main'); -$node->init; -$node->append_conf('postgresql.conf', "shared_preload_libraries = 'pg_tde'"); -$node->start; - -PGTDE::psql($node, 'postgres', 'CREATE EXTENSION IF NOT EXISTS pg_tde;'); - -PGTDE::psql($node, 'postgres', - "SELECT pg_tde_add_database_key_provider_file('file-provider', json_object('type' VALUE 'remote', 'url' VALUE 'http://localhost:8888/hello'));" -); -PGTDE::psql($node, 'postgres', - "SELECT pg_tde_set_key_using_database_key_provider('test-db-key', 'file-provider');" -); - -PGTDE::psql($node, 'postgres', - 'CREATE TABLE test_enc2 (id SERIAL, k INTEGER, PRIMARY KEY (id)) USING tde_heap;' -); - -PGTDE::psql($node, 'postgres', 'INSERT INTO test_enc2 (k) VALUES (5), (6);'); - -PGTDE::psql($node, 'postgres', 'SELECT * FROM test_enc2 ORDER BY id;'); - -PGTDE::append_to_result_file("-- server restart"); -$node->restart; - -PGTDE::psql($node, 'postgres', 'SELECT * FROM test_enc2 ORDER BY id;'); - -PGTDE::psql($node, 'postgres', 'DROP TABLE test_enc2;'); - -PGTDE::psql($node, 'postgres', 'DROP EXTENSION pg_tde;'); - -$node->stop; - -# Compare the expected and out file -my $compare = PGTDE->compare_results(); - -is($compare, 0, - "Compare Files: $PGTDE::expected_filename_with_path and $PGTDE::out_filename_with_path files." -); - -done_testing(); diff --git a/contrib/pg_tde/t/004_file_config.pl b/contrib/pg_tde/t/004_file_config.pl deleted file mode 100644 index 82a0779e6d196..0000000000000 --- a/contrib/pg_tde/t/004_file_config.pl +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; -use File::Basename; -use Test::More; -use lib 't'; -use pgtde; - -PGTDE::setup_files_dir(basename($0)); - -open my $conf2, '>>', "/tmp/datafile-location"; -print $conf2 "/tmp/keyring_data_file\n"; -close $conf2; - -my $node = PostgreSQL::Test::Cluster->new('main'); -$node->init; -$node->append_conf('postgresql.conf', "shared_preload_libraries = 'pg_tde'"); -$node->start; - -PGTDE::psql($node, 'postgres', 'CREATE EXTENSION IF NOT EXISTS pg_tde;'); - -PGTDE::psql($node, 'postgres', - "SELECT pg_tde_add_database_key_provider_file('file-provider', json_object('type' VALUE 'file', 'path' VALUE '/tmp/datafile-location'));" -); -PGTDE::psql($node, 'postgres', - "SELECT pg_tde_set_key_using_database_key_provider('test-db-key', 'file-provider');" -); - -PGTDE::psql($node, 'postgres', - 'CREATE TABLE test_enc1 (id SERIAL, k INTEGER, PRIMARY KEY (id)) USING tde_heap;' -); - -PGTDE::psql($node, 'postgres', 'INSERT INTO test_enc1 (k) VALUES (5), (6);'); - -PGTDE::psql($node, 'postgres', 'SELECT * FROM test_enc1 ORDER BY id;'); - -PGTDE::append_to_result_file("-- server restart"); -$node->restart; - -PGTDE::psql($node, 'postgres', 'SELECT * FROM test_enc1 ORDER BY id;'); - -PGTDE::psql($node, 'postgres', 'DROP TABLE test_enc1;'); - -PGTDE::psql($node, 'postgres', 'DROP EXTENSION pg_tde;'); - -$node->stop; - -# Compare the expected and out file -my $compare = PGTDE->compare_results(); - -is($compare, 0, - "Compare Files: $PGTDE::expected_filename_with_path and $PGTDE::out_filename_with_path files." -); - -done_testing(); diff --git a/contrib/pg_tde/t/007_tde_heap.pl b/contrib/pg_tde/t/004_tde_heap.pl similarity index 100% rename from contrib/pg_tde/t/007_tde_heap.pl rename to contrib/pg_tde/t/004_tde_heap.pl diff --git a/contrib/pg_tde/t/008_key_rotate_tablespace.pl b/contrib/pg_tde/t/005_key_rotate_tablespace.pl similarity index 100% rename from contrib/pg_tde/t/008_key_rotate_tablespace.pl rename to contrib/pg_tde/t/005_key_rotate_tablespace.pl diff --git a/contrib/pg_tde/t/006_remote_vault_config.pl b/contrib/pg_tde/t/006_remote_vault_config.pl deleted file mode 100644 index c84029637e245..0000000000000 --- a/contrib/pg_tde/t/006_remote_vault_config.pl +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/perl - -use strict; -use warnings; -use Env; -use File::Basename; -use Test::More; -use lib 't'; -use pgtde; - -{ - - package MyWebServer; - - use HTTP::Server::Simple::CGI; - use base qw(HTTP::Server::Simple::CGI); - - my %dispatch = ( - '/token' => \&resp_token, - '/url' => \&resp_url,); - - sub handle_request - { - my $self = shift; - my $cgi = shift; - - my $path = $cgi->path_info(); - my $handler = $dispatch{$path}; - - if (ref($handler) eq "CODE") - { - print "HTTP/1.0 200 OK\r\n"; - $handler->($cgi); - - } - else - { - print "HTTP/1.0 404 Not found\r\n"; - print $cgi->header, - $cgi->start_html('Not found'), - $cgi->h1('Not found'), - $cgi->end_html; - } - } - - sub resp_token - { - my $cgi = shift; - print $cgi->header, "$ENV{'ROOT_TOKEN'}\r\n"; - } - - sub resp_url - { - my $cgi = shift; - print $cgi->header, "http://127.0.0.1:8200\r\n"; - } - -} - -my $pid = MyWebServer->new(8889)->background(); -END { kill('TERM', $pid); } - -PGTDE::setup_files_dir(basename($0)); - -my $node = PostgreSQL::Test::Cluster->new('main'); -$node->init; -$node->append_conf('postgresql.conf', "shared_preload_libraries = 'pg_tde'"); -$node->start; - -PGTDE::psql($node, 'postgres', 'CREATE EXTENSION IF NOT EXISTS pg_tde;'); - -PGTDE::psql($node, 'postgres', - "SELECT pg_tde_add_database_key_provider_vault_v2('vault-provider', json_object('type' VALUE 'remote', 'url' VALUE 'http://localhost:8889/token'), json_object('type' VALUE 'remote', 'url' VALUE 'http://localhost:8889/url'), to_json('secret'::text), NULL);" -); -PGTDE::psql($node, 'postgres', - "SELECT pg_tde_set_key_using_database_key_provider('test-db-key', 'vault-provider');" -); - -PGTDE::psql($node, 'postgres', - 'CREATE TABLE test_enc2 (id SERIAL, k INTEGER, PRIMARY KEY (id)) USING tde_heap;' -); - -PGTDE::psql($node, 'postgres', 'INSERT INTO test_enc2 (k) VALUES (5), (6);'); - -PGTDE::psql($node, 'postgres', 'SELECT * FROM test_enc2 ORDER BY id;'); - -PGTDE::append_to_result_file("-- server restart"); -$node->restart; - -PGTDE::psql($node, 'postgres', 'SELECT * FROM test_enc2 ORDER BY id;'); - -PGTDE::psql($node, 'postgres', 'DROP TABLE test_enc2;'); - -PGTDE::psql($node, 'postgres', 'DROP EXTENSION pg_tde;'); - -$node->stop; - -# Compare the expected and out file -my $compare = PGTDE->compare_results(); - -is($compare, 0, - "Compare Files: $PGTDE::expected_filename_with_path and $PGTDE::out_filename_with_path files." -); - -done_testing(); diff --git a/contrib/pg_tde/t/009_wal_encrypt.pl b/contrib/pg_tde/t/006_wal_encrypt.pl similarity index 100% rename from contrib/pg_tde/t/009_wal_encrypt.pl rename to contrib/pg_tde/t/006_wal_encrypt.pl diff --git a/contrib/pg_tde/t/010_change_key_provider.pl b/contrib/pg_tde/t/007_change_key_provider.pl similarity index 100% rename from contrib/pg_tde/t/010_change_key_provider.pl rename to contrib/pg_tde/t/007_change_key_provider.pl diff --git a/contrib/pg_tde/t/011_unlogged_tables.pl b/contrib/pg_tde/t/008_unlogged_tables.pl similarity index 100% rename from contrib/pg_tde/t/011_unlogged_tables.pl rename to contrib/pg_tde/t/008_unlogged_tables.pl diff --git a/contrib/pg_tde/t/012_replication.pl b/contrib/pg_tde/t/009_replication.pl similarity index 100% rename from contrib/pg_tde/t/012_replication.pl rename to contrib/pg_tde/t/009_replication.pl diff --git a/contrib/pg_tde/t/013_crash_recovery.pl b/contrib/pg_tde/t/010_crash_recovery.pl similarity index 100% rename from contrib/pg_tde/t/013_crash_recovery.pl rename to contrib/pg_tde/t/010_crash_recovery.pl diff --git a/contrib/pg_tde/t/014_pg_waldump_basic.pl b/contrib/pg_tde/t/011_pg_waldump_basic.pl similarity index 100% rename from contrib/pg_tde/t/014_pg_waldump_basic.pl rename to contrib/pg_tde/t/011_pg_waldump_basic.pl diff --git a/contrib/pg_tde/t/015_pg_waldump_fullpage.pl b/contrib/pg_tde/t/012_pg_waldump_fullpage.pl similarity index 100% rename from contrib/pg_tde/t/015_pg_waldump_fullpage.pl rename to contrib/pg_tde/t/012_pg_waldump_fullpage.pl diff --git a/contrib/pg_tde/t/016_pg_tde_change_key_provider.pl b/contrib/pg_tde/t/013_pg_tde_change_key_provider.pl similarity index 97% rename from contrib/pg_tde/t/016_pg_tde_change_key_provider.pl rename to contrib/pg_tde/t/013_pg_tde_change_key_provider.pl index c197f38f15f03..284611d178498 100644 --- a/contrib/pg_tde/t/016_pg_tde_change_key_provider.pl +++ b/contrib/pg_tde/t/013_pg_tde_change_key_provider.pl @@ -22,6 +22,8 @@ q{SELECT oid FROM pg_catalog.pg_database WHERE datname = 'postgres'}); my $options; +my $token_file = $ENV{ROOT_TOKEN_FILE}; + $node->stop; command_like( @@ -64,7 +66,7 @@ 'database-provider', 'vault-v2', 'http://vault-server.example:8200/', - 'secret-token', + $token_file, 'mount-path', '/tmp/ca_path', ], @@ -85,8 +87,8 @@ 'postgres', q{SELECT options FROM pg_tde_list_all_database_key_providers() WHERE provider_name = 'database-provider'} )); -is($options->{token}, 'secret-token', - 'token is set correctly for vault-v2 provider'); +is($options->{tokenPath}, $token_file, + 'tokenPath is set correctly for vault-v2 provider'); is( $options->{url}, 'http://vault-server.example:8200/', 'url is set correctly for vault-v2 provider'); @@ -147,7 +149,7 @@ 'global-provider', 'vault-v2', 'http://vault-server.example:8200/', - 'secret-token', + $token_file, 'mount-path', '/tmp/ca_path', ], diff --git a/contrib/pg_tde/t/expected/005_multiple_extensions.out b/contrib/pg_tde/t/expected/003_multiple_extensions.out similarity index 100% rename from contrib/pg_tde/t/expected/005_multiple_extensions.out rename to contrib/pg_tde/t/expected/003_multiple_extensions.out diff --git a/contrib/pg_tde/t/expected/007_tde_heap.out b/contrib/pg_tde/t/expected/004_tde_heap.out similarity index 100% rename from contrib/pg_tde/t/expected/007_tde_heap.out rename to contrib/pg_tde/t/expected/004_tde_heap.out diff --git a/contrib/pg_tde/t/expected/008_key_rotate_tablespace.out b/contrib/pg_tde/t/expected/005_key_rotate_tablespace.out similarity index 100% rename from contrib/pg_tde/t/expected/008_key_rotate_tablespace.out rename to contrib/pg_tde/t/expected/005_key_rotate_tablespace.out diff --git a/contrib/pg_tde/t/expected/009_wal_encrypt.out b/contrib/pg_tde/t/expected/006_wal_encrypt.out similarity index 100% rename from contrib/pg_tde/t/expected/009_wal_encrypt.out rename to contrib/pg_tde/t/expected/006_wal_encrypt.out diff --git a/contrib/pg_tde/t/expected/010_change_key_provider.out b/contrib/pg_tde/t/expected/007_change_key_provider.out similarity index 100% rename from contrib/pg_tde/t/expected/010_change_key_provider.out rename to contrib/pg_tde/t/expected/007_change_key_provider.out diff --git a/contrib/pg_tde/t/expected/011_unlogged_tables.out b/contrib/pg_tde/t/expected/008_unlogged_tables.out similarity index 100% rename from contrib/pg_tde/t/expected/011_unlogged_tables.out rename to contrib/pg_tde/t/expected/008_unlogged_tables.out diff --git a/contrib/pg_tde/t/expected/012_replication.out b/contrib/pg_tde/t/expected/009_replication.out similarity index 100% rename from contrib/pg_tde/t/expected/012_replication.out rename to contrib/pg_tde/t/expected/009_replication.out diff --git a/contrib/pg_tde/t/expected/013_crash_recovery.out b/contrib/pg_tde/t/expected/010_crash_recovery.out similarity index 100% rename from contrib/pg_tde/t/expected/013_crash_recovery.out rename to contrib/pg_tde/t/expected/010_crash_recovery.out