diff options
Diffstat (limited to 'src/libstrongswan/credentials/sets/mem_cred.c')
-rw-r--r-- | src/libstrongswan/credentials/sets/mem_cred.c | 113 |
1 files changed, 107 insertions, 6 deletions
diff --git a/src/libstrongswan/credentials/sets/mem_cred.c b/src/libstrongswan/credentials/sets/mem_cred.c index 0f8bff23f..53e035f98 100644 --- a/src/libstrongswan/credentials/sets/mem_cred.c +++ b/src/libstrongswan/credentials/sets/mem_cred.c @@ -370,14 +370,42 @@ METHOD(mem_cred_t, add_key, void, this->lock->unlock(this->lock); } +METHOD(mem_cred_t, remove_key, bool, + private_mem_cred_t *this, chunk_t fp) +{ + enumerator_t *enumerator; + private_key_t *current; + bool found = FALSE; + + this->lock->write_lock(this->lock); + + enumerator = this->keys->create_enumerator(this->keys); + while (enumerator->enumerate(enumerator, ¤t)) + { + if (current->has_fingerprint(current, fp)) + { + this->keys->remove_at(this->keys, enumerator); + current->destroy(current); + found = TRUE; + break; + } + } + enumerator->destroy(enumerator); + + this->lock->unlock(this->lock); + return found; +} + /** * Shared key entry */ typedef struct { - /* shared key */ + /** shared key */ shared_key_t *shared; - /* list of owners, identification_t */ + /** list of owners, identification_t */ linked_list_t *owners; + /** optional unique identifier */ + char *id; } shared_entry_t; /** @@ -388,11 +416,12 @@ static void shared_entry_destroy(shared_entry_t *entry) entry->owners->destroy_offset(entry->owners, offsetof(identification_t, destroy)); entry->shared->destroy(entry->shared); + free(entry->id); free(entry); } /** - * Check if two shared key entries equal + * Check if two shared key entries are equal (ignoring the unique identifier) */ static bool shared_entry_equals(shared_entry_t *a, shared_entry_t *b) { @@ -528,8 +557,9 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, (void*)shared_filter, data, (void*)shared_data_destroy); } -METHOD(mem_cred_t, add_shared_list, void, - private_mem_cred_t *this, shared_key_t *shared, linked_list_t* owners) +METHOD(mem_cred_t, add_shared_unique, void, + private_mem_cred_t *this, char *id, shared_key_t *shared, + linked_list_t* owners) { shared_entry_t *current, *new; enumerator_t *enumerator; @@ -537,6 +567,7 @@ METHOD(mem_cred_t, add_shared_list, void, INIT(new, .shared = shared, .owners = owners, + .id = strdupnull(id), ); this->lock->write_lock(this->lock); @@ -544,7 +575,10 @@ METHOD(mem_cred_t, add_shared_list, void, enumerator = this->shared->create_enumerator(this->shared); while (enumerator->enumerate(enumerator, ¤t)) { - if (shared_entry_equals(current, new)) + /* always replace keys with the same unique identifier, only compare + * them if both have no unique id assigned */ + if ((id && streq(id, current->id)) || + (!id && !current->id && shared_entry_equals(current, new))) { this->shared->remove_at(this->shared, enumerator); shared_entry_destroy(current); @@ -558,6 +592,12 @@ METHOD(mem_cred_t, add_shared_list, void, this->lock->unlock(this->lock); } +METHOD(mem_cred_t, add_shared_list, void, + private_mem_cred_t *this, shared_key_t *shared, linked_list_t* owners) +{ + add_shared_unique(this, NULL, shared, owners); +} + METHOD(mem_cred_t, add_shared, void, private_mem_cred_t *this, shared_key_t *shared, ...) { @@ -580,6 +620,63 @@ METHOD(mem_cred_t, add_shared, void, add_shared_list(this, shared, owners); } +METHOD(mem_cred_t, remove_shared_unique, void, + private_mem_cred_t *this, char *id) +{ + enumerator_t *enumerator; + shared_entry_t *current; + + if (!id) + { + return; + } + + this->lock->write_lock(this->lock); + + enumerator = this->shared->create_enumerator(this->shared); + while (enumerator->enumerate(enumerator, ¤t)) + { + if (streq(id, current->id)) + { + this->shared->remove_at(this->shared, enumerator); + shared_entry_destroy(current); + break; + } + } + enumerator->destroy(enumerator); + + this->lock->unlock(this->lock); +} + +/** + * Filter unique ids of shared keys (ingore secrets without unique id) + */ +static bool unique_filter(void *unused, + shared_entry_t **in, char **id) +{ + shared_entry_t *entry = *in; + + if (!entry->id) + { + return FALSE; + } + if (id) + { + *id = entry->id; + } + return TRUE; +} + +METHOD(mem_cred_t, create_unique_shared_enumerator, enumerator_t*, + private_mem_cred_t *this) +{ + this->lock->read_lock(this->lock); + return enumerator_create_filter( + this->shared->create_enumerator(this->shared), + (void*)unique_filter, this->lock, + (void*)this->lock->unlock); +} + /** * Certificate distribution point */ @@ -817,8 +914,12 @@ mem_cred_t *mem_cred_create() .get_cert_ref = _get_cert_ref, .add_crl = _add_crl, .add_key = _add_key, + .remove_key = _remove_key, .add_shared = _add_shared, .add_shared_list = _add_shared_list, + .add_shared_unique = _add_shared_unique, + .remove_shared_unique = _remove_shared_unique, + .create_unique_shared_enumerator = _create_unique_shared_enumerator, .add_cdp = _add_cdp, .replace_certs = _replace_certs, .replace_secrets = _replace_secrets, |