Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add function to list available key provides for database #239

Merged
merged 2 commits into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions expected/keyprovider_dependency.out
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ SELECT pg_tde_add_key_provider_vault_v2('V2-vault','vault-token','percona.com/va
3
(1 row)

SELECT * FROM pg_tde_list_all_key_providers();
id | provider_name | provider_type | options
----+---------------+---------------+-----------------------------------------------------------------------------------------------------------------------------------------------
1 | mk-file | file | {"type" : "file", "path" : "/tmp/pg_tde_test_keyring.per"}
2 | free-file | file | {"type" : "file", "path" : "/tmp/pg_tde_test_keyring_2.per"}
3 | V2-vault | vault-v2 | {"type" : "vault-v2", "url" : "percona.com/vault-v2/percona", "token" : "vault-token", "mountPath" : "/mount/dev", "caPath" : "ca-cert-auth"}
(3 rows)

SELECT pg_tde_set_principal_key('test-db-principal-key','mk-file');
pg_tde_set_principal_key
--------------------------
Expand Down
9 changes: 9 additions & 0 deletions pg_tde--1.0.sql
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ AS $$
$$
LANGUAGE SQL;

CREATE FUNCTION pg_tde_list_all_key_providers
dutow marked this conversation as resolved.
Show resolved Hide resolved
(OUT id INT,
OUT provider_name VARCHAR(128),
OUT provider_type VARCHAR(10),
OUT options JSON)
RETURNS SETOF record
AS 'MODULE_PATHNAME'
LANGUAGE C STRICT VOLATILE;

-- Table access method
CREATE FUNCTION pg_tdeam_basic_handler(internal)
RETURNS table_am_handler
Expand Down
2 changes: 2 additions & 0 deletions sql/keyprovider_dependency.sql
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ SELECT pg_tde_add_key_provider_file('mk-file','/tmp/pg_tde_test_keyring.per');
SELECT pg_tde_add_key_provider_file('free-file','/tmp/pg_tde_test_keyring_2.per');
SELECT pg_tde_add_key_provider_vault_v2('V2-vault','vault-token','percona.com/vault-v2/percona','/mount/dev','ca-cert-auth');

SELECT * FROM pg_tde_list_all_key_providers();

SELECT pg_tde_set_principal_key('test-db-principal-key','mk-file');

DROP EXTENSION pg_tde;
80 changes: 77 additions & 3 deletions src/catalog/tde_keyring.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "funcapi.h"
#include "access/xlog.h"
#include "access/xloginsert.h"
#include "access/pg_tde_xlog.h"
Expand All @@ -34,6 +35,8 @@
PG_FUNCTION_INFO_V1(pg_tde_add_key_provider_internal);
Datum pg_tde_add_key_provider_internal(PG_FUNCTION_ARGS);

PG_FUNCTION_INFO_V1(pg_tde_list_all_key_providers);
Datum pg_tde_list_all_key_providers(PG_FUNCTION_ARGS);

#define PG_TDE_KEYRING_FILENAME "pg_tde_keyrings"
/*
Expand All @@ -51,6 +54,7 @@ Datum pg_tde_add_key_provider_internal(PG_FUNCTION_ARGS);
*/
#define FILE_KEYRING_PATH_KEY "path"
#define FILE_KEYRING_TYPE_KEY "type"
#define PG_TDE_LIST_PROVIDERS_COLS 4

typedef enum ProviderScanType
{
Expand All @@ -70,7 +74,7 @@ static char *get_keyring_infofile_path(char *resPath, Oid dbOid, Oid spcOid);
static void key_provider_startup_cleanup(int tde_tbl_count, XLogExtensionInstall *ext_info, bool redo, void *arg);
static uint32 write_key_provider_info(KeyringProvideRecord *provider, Oid database_id, Oid tablespace_id, off_t position, bool redo);
static uint32 save_new_key_provider_info(KeyringProvideRecord *provider);

static const char *get_keyring_provider_typename(ProviderType p_type);
static Size initialize_shared_state(void *start_address);
static Size required_shared_mem_size(void);

Expand Down Expand Up @@ -141,8 +145,22 @@ get_keyring_provider_from_typename(char *provider_type)
return UNKNOWN_KEY_PROVIDER;
}

static GenericKeyring *
load_keyring_provider_from_record(KeyringProvideRecord* provider)
static const char *
get_keyring_provider_typename(ProviderType p_type)
{
switch (p_type)
{
case FILE_KEY_PROVIDER:
return FILE_KEYRING_TYPE;
case VAULT_V2_KEY_PROVIDER:
return VAULTV2_KEYRING_TYPE;
default:
break;
}
return NULL;
}

static GenericKeyring *load_keyring_provider_from_record(KeyringProvideRecord *provider)
{
Datum option_datum;
GenericKeyring *keyring = NULL;
Expand All @@ -155,6 +173,7 @@ load_keyring_provider_from_record(KeyringProvideRecord* provider)
keyring->key_id = provider->provider_id;
strncpy(keyring->provider_name, provider->provider_name, sizeof(keyring->provider_name));
keyring->type = provider->provider_type;
strncpy(keyring->options, provider->options, sizeof(keyring->options));
debug_print_kerying(keyring);
}
return keyring;
Expand Down Expand Up @@ -513,3 +532,58 @@ pg_tde_add_key_provider_internal(PG_FUNCTION_ARGS)

PG_RETURN_INT32(provider.provider_id);
}

Datum
pg_tde_list_all_key_providers(PG_FUNCTION_ARGS)
{
List* all_providers = GetAllKeyringProviders();
ListCell *lc;
Tuplestorestate *tupstore;
TupleDesc tupdesc;
MemoryContext per_query_ctx;
MemoryContext oldcontext;
ReturnSetInfo *rsinfo = (ReturnSetInfo *)fcinfo->resultinfo;
/* check to see if caller supports us returning a tuplestore */
if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("pg_tde_list_all_key_providers: set-valued function called in context that cannot accept a set")));
if (!(rsinfo->allowedModes & SFRM_Materialize))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("pg_tde_list_all_key_providers: materialize mode required, but it is not allowed in this context")));

/* Switch into long-lived context to construct returned data structures */
per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
oldcontext = MemoryContextSwitchTo(per_query_ctx);

/* Build a tuple descriptor for our result type */
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "pg_tde_list_all_key_providers: return type must be a row type");

tupstore = tuplestore_begin_heap(true, false, work_mem);
rsinfo->returnMode = SFRM_Materialize;
rsinfo->setResult = tupstore;
rsinfo->setDesc = tupdesc;

MemoryContextSwitchTo(oldcontext);

foreach (lc, all_providers)
{
Datum values[PG_TDE_LIST_PROVIDERS_COLS] = {0};
bool nulls[PG_TDE_LIST_PROVIDERS_COLS] = {0};
GenericKeyring *keyring = (GenericKeyring *)lfirst(lc);
int i = 0;

values[i++] = Int32GetDatum(keyring->key_id);
values[i++] = CStringGetTextDatum(keyring->provider_name);
values[i++] = CStringGetTextDatum(get_keyring_provider_typename(keyring->type));
values[i++] = CStringGetTextDatum(keyring->options);
tuplestore_putvalues(tupstore, tupdesc, values, nulls);

debug_print_kerying(keyring);
}
tuplestore_donestoring(tupstore);
list_free_deep(all_providers);
return (Datum)0;
}
1 change: 1 addition & 0 deletions src/include/catalog/tde_keyring.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ typedef struct GenericKeyring
ProviderType type; /* Must be the first field */
Oid key_id;
char provider_name[MAX_PROVIDER_NAME_LEN];
char options[MAX_KEYRING_OPTION_LEN]; /* User provided options string*/
} GenericKeyring;

typedef struct FileKeyring
Expand Down
Loading