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 <[email protected]>
---
Hello strongswan-developers,

I was wondering if I could get this patch upstream. It is particularly
helpful to deal with private proposal strings. They are comprised of a
prefix followed by their private ID. Since none of the given mechanisms
(static keywords, nor keyword registration) allows my to parse a whole
class of algorithm names like described, I would rather use a user
provided parser. What do you think? Any suggestions on how to get this
upstream are appreciated.

Cheers,
Thomas

 .../crypto/proposal/proposal_keywords.c            | 47 +++++++++++++++++++++-
 .../crypto/proposal/proposal_keywords.h            | 11 +++++
 2 files changed, 57 insertions(+), 1 deletion(-)


diff --git a/src/libstrongswan/crypto/proposal/proposal_keywords.c b/src/libstrongswan/crypto/proposal/proposal_keywords.c
index 4db504e..14d4c4f 100644
--- a/src/libstrongswan/crypto/proposal/proposal_keywords.c
+++ b/src/libstrongswan/crypto/proposal/proposal_keywords.c
@@ -56,6 +56,11 @@ struct private_proposal_keywords_t {
 	linked_list_t * tokens;
 
 	/**
+	 * registered algname parsers, as algname_parser_t
+	 */
+	linked_list_t *parsers;
+
+	/**
 	 * rwlock to lock access to modules
 	 */
 	rwlock_t *lock;
@@ -85,11 +90,40 @@ 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)
+{
+	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);
+	if (!token)
+	{
+		token = find_token(this, str);
+	}
+	return token ?: parse_token(this, str);
 }
 
 METHOD(proposal_keywords_t, register_token, void,
@@ -110,6 +144,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, 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 +163,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 +179,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 d6107ab..278a0bf 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*(*algname_parser_t)(const char *algname);
+
 #include <library.h>
 #include <crypto/transform.h>
 
@@ -102,6 +104,15 @@ struct proposal_keywords_t {
 						   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,
+									algname_parser_t parser);
+
+	/**
 	 * Destroy a proposal_keywords_t instance.
 	 */
 	void (*destroy)(proposal_keywords_t *this);

_______________________________________________
Dev mailing list
[email protected]
https://lists.strongswan.org/mailman/listinfo/dev

Reply via email to