swanctl: Automatically unload removed shared keys

This commit is contained in:
Tobias Brunner
2017-02-16 19:21:13 +01:00
parent cf57d9a98f
commit d460ab2bff
+49 -15
View File
@@ -50,6 +50,8 @@ typedef struct {
bool noprompt; bool noprompt;
/** list of key ids of loaded private keys */ /** list of key ids of loaded private keys */
hashtable_t *keys; hashtable_t *keys;
/** list of unique ids of loaded shared keys */
hashtable_t *shared;
} load_ctx_t; } load_ctx_t;
/** /**
@@ -629,6 +631,7 @@ static bool load_secret(load_ctx_t *ctx, char *section)
req = vici_begin("load-shared"); req = vici_begin("load-shared");
vici_add_key_valuef(req, "id", "%s", section);
vici_add_key_valuef(req, "type", "%s", type); vici_add_key_valuef(req, "type", "%s", type);
vici_add_key_value(req, "data", data.ptr, data.len); vici_add_key_value(req, "data", data.ptr, data.len);
chunk_clear(&data); chunk_clear(&data);
@@ -667,6 +670,10 @@ static bool load_secret(load_ctx_t *ctx, char *section)
{ {
printf("loaded %s secret '%s'\n", type, section); printf("loaded %s secret '%s'\n", type, section);
} }
if (ret)
{
free(ctx->shared->remove(ctx->shared, section));
}
vici_free_res(res); vici_free_res(res);
return ret; return ret;
} }
@@ -687,9 +694,9 @@ CALLBACK(get_id, int,
} }
/** /**
* Get a list of currently loaded private keys * Get a list of currently loaded private and shared keys
*/ */
static void get_keys(load_ctx_t *ctx) static void get_creds(load_ctx_t *ctx)
{ {
vici_res_t *res; vici_res_t *res;
@@ -704,31 +711,43 @@ static void get_keys(load_ctx_t *ctx)
vici_parse_cb(res, NULL, NULL, get_id, ctx->keys); vici_parse_cb(res, NULL, NULL, get_id, ctx->keys);
vici_free_res(res); vici_free_res(res);
} }
res = vici_submit(vici_begin("get-shared"), ctx->conn);
if (res)
{
if (ctx->format & COMMAND_FORMAT_RAW)
{
vici_dump(res, "get-shared reply", ctx->format & COMMAND_FORMAT_PRETTY,
stdout);
}
vici_parse_cb(res, NULL, NULL, get_id, ctx->shared);
vici_free_res(res);
}
} }
/** /**
* Remove a given key * Remove a given key
*/ */
static bool unload_key(load_ctx_t *ctx, char *id) static bool unload_key(load_ctx_t *ctx, char *command, char *id)
{ {
vici_req_t *req; vici_req_t *req;
vici_res_t *res; vici_res_t *res;
char buf[BUF_LEN];
bool ret = TRUE; bool ret = TRUE;
req = vici_begin("unload-key"); req = vici_begin(command);
vici_add_key_valuef(req, "id", "%s", id); vici_add_key_valuef(req, "id", "%s", id);
res = vici_submit(req, ctx->conn); res = vici_submit(req, ctx->conn);
if (!res) if (!res)
{ {
fprintf(stderr, "unload-key request failed: %s\n", strerror(errno)); fprintf(stderr, "%s request failed: %s\n", command, strerror(errno));
return FALSE; return FALSE;
} }
if (ctx->format & COMMAND_FORMAT_RAW) if (ctx->format & COMMAND_FORMAT_RAW)
{ {
vici_dump(res, "unload-key reply", ctx->format & COMMAND_FORMAT_PRETTY, snprintf(buf, sizeof(buf), "%s reply", command);
stdout); vici_dump(res, buf, ctx->format & COMMAND_FORMAT_PRETTY, stdout);
} }
else if (!streq(vici_find_str(res, "no", "success"), "yes")) else if (!streq(vici_find_str(res, "no", "success"), "yes"))
{ {
@@ -740,6 +759,22 @@ static bool unload_key(load_ctx_t *ctx, char *id)
return ret; return ret;
} }
/**
* Remove all keys in the given hashtable using the given command
*/
static void unload_keys(load_ctx_t *ctx, hashtable_t *ht, char *command)
{
enumerator_t *enumerator;
char *id;
enumerator = ht->create_enumerator(ht);
while (enumerator->enumerate(enumerator, &id, NULL))
{
unload_key(ctx, command, id);
}
enumerator->destroy(enumerator);
}
/** /**
* Clear all currently loaded credentials * Clear all currently loaded credentials
*/ */
@@ -769,13 +804,14 @@ int load_creds_cfg(vici_conn_t *conn, command_format_options_t format,
settings_t *cfg, bool clear, bool noprompt) settings_t *cfg, bool clear, bool noprompt)
{ {
enumerator_t *enumerator; enumerator_t *enumerator;
char *section, *id; char *section;
load_ctx_t ctx = { load_ctx_t ctx = {
.conn = conn, .conn = conn,
.format = format, .format = format,
.noprompt = noprompt, .noprompt = noprompt,
.cfg = cfg, .cfg = cfg,
.keys = hashtable_create(hashtable_hash_str, hashtable_equals_str, 8), .keys = hashtable_create(hashtable_hash_str, hashtable_equals_str, 8),
.shared = hashtable_create(hashtable_hash_str, hashtable_equals_str, 8),
}; };
if (clear) if (clear)
@@ -786,7 +822,7 @@ int load_creds_cfg(vici_conn_t *conn, command_format_options_t format,
} }
} }
get_keys(&ctx); get_creds(&ctx);
load_certs(&ctx, "x509", SWANCTL_X509DIR); load_certs(&ctx, "x509", SWANCTL_X509DIR);
load_certs(&ctx, "x509ca", SWANCTL_X509CADIR); load_certs(&ctx, "x509ca", SWANCTL_X509CADIR);
@@ -811,13 +847,11 @@ int load_creds_cfg(vici_conn_t *conn, command_format_options_t format,
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
enumerator = ctx.keys->create_enumerator(ctx.keys); unload_keys(&ctx, ctx.keys, "unload-key");
while (enumerator->enumerate(enumerator, &id, NULL)) unload_keys(&ctx, ctx.shared, "unload-shared");
{
unload_key(&ctx, id);
}
enumerator->destroy(enumerator);
ctx.keys->destroy_function(ctx.keys, (void*)free); ctx.keys->destroy_function(ctx.keys, (void*)free);
ctx.shared->destroy_function(ctx.shared, (void*)free);
return 0; return 0;
} }