From: Thomas Egerer Date: Fri, 29 Nov 2013 12:17:30 +0000 (+0100) Subject: proposal: Add possibility to register custom proposal keyword parser X-Git-Tag: 5.1.2rc1~66 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=568e3022607a98394c53bc5a4922d368d19cbe60;p=thirdparty%2Fstrongswan.git proposal: Add possibility to register custom proposal keyword parser If a proposal string cannot be matched to a token using strcmp (e.g. if you want to register a whole class of algorithms containing their ID, like my_alg_2342), you can use the provided function to register a parser that transforms the given string into a proposal token. Signed-off-by: Thomas Egerer --- diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords.c b/src/libstrongswan/crypto/proposal/proposal_keywords.c index 4db504eb06..bbb97d0885 100644 --- a/src/libstrongswan/crypto/proposal/proposal_keywords.c +++ b/src/libstrongswan/crypto/proposal/proposal_keywords.c @@ -55,6 +55,11 @@ struct private_proposal_keywords_t { */ linked_list_t * tokens; + /** + * registered algname parsers, as proposal_algname_parser_t + */ + linked_list_t *parsers; + /** * rwlock to lock access to modules */ @@ -85,11 +90,46 @@ static const proposal_token_t* find_token(private_proposal_keywords_t *this, return found; } +/** + * Parse the given algorithm into a token with user defined parser functions. + */ +static const proposal_token_t* parse_token(private_proposal_keywords_t *this, + const char *str) +{ + proposal_algname_parser_t parser; + enumerator_t *enumerator; + proposal_token_t *found = NULL; + + this->lock->read_lock(this->lock); + enumerator = this->parsers->create_enumerator(this->parsers); + while (enumerator->enumerate(enumerator, &parser)) + { + found = parser(str); + if (found) + { + break; + } + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); + return found; +} + METHOD(proposal_keywords_t, get_token, const proposal_token_t*, private_proposal_keywords_t *this, const char *str) { - const proposal_token_t *token = proposal_get_token_static(str, strlen(str)); - return token ?: find_token(this, str); + const proposal_token_t *token; + + token = proposal_get_token_static(str, strlen(str)); + if (!token) + { + token = find_token(this, str); + } + if (!token) + { + token = parse_token(this, str); + } + return token; } METHOD(proposal_keywords_t, register_token, void, @@ -110,6 +150,14 @@ METHOD(proposal_keywords_t, register_token, void, this->lock->unlock(this->lock); } +METHOD(proposal_keywords_t, register_algname_parser, void, + private_proposal_keywords_t *this, proposal_algname_parser_t parser) +{ + this->lock->write_lock(this->lock); + this->tokens->insert_first(this->parsers, parser); + this->lock->unlock(this->lock); +} + METHOD(proposal_keywords_t, destroy, void, private_proposal_keywords_t *this) { @@ -121,6 +169,7 @@ METHOD(proposal_keywords_t, destroy, void, free(token); } this->tokens->destroy(this->tokens); + this->parsers->destroy(this->parsers); this->lock->destroy(this->lock); free(this); } @@ -136,9 +185,11 @@ proposal_keywords_t *proposal_keywords_create() .public = { .get_token = _get_token, .register_token = _register_token, + .register_algname_parser = _register_algname_parser, .destroy = _destroy, }, .tokens = linked_list_create(), + .parsers = linked_list_create(), .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), ); diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords.h b/src/libstrongswan/crypto/proposal/proposal_keywords.h index d6107abc0a..5cdbafc516 100644 --- a/src/libstrongswan/crypto/proposal/proposal_keywords.h +++ b/src/libstrongswan/crypto/proposal/proposal_keywords.h @@ -46,6 +46,8 @@ typedef struct proposal_token_t proposal_token_t; typedef struct proposal_keywords_t proposal_keywords_t; +typedef proposal_token_t*(*proposal_algname_parser_t)(const char *algname); + #include #include @@ -101,6 +103,17 @@ struct proposal_keywords_t { transform_type_t type, u_int16_t algorithm, u_int16_t keysize); + /** + * Register an algorithm name parser. + * + * It is meant to parse an algorithm name into a proposal token in a + * generic, user defined way. + * + * @param parser a pointer to the parser function + */ + void (*register_algname_parser)(proposal_keywords_t *this, + proposal_algname_parser_t parser); + /** * Destroy a proposal_keywords_t instance. */