proposal: Add possibility to register custom proposal keyword parser
authorThomas Egerer <thomas.egerer@secunet.com>
Fri, 29 Nov 2013 12:17:30 +0000 (13:17 +0100)
committerMartin Willi <martin@revosec.ch>
Mon, 20 Jan 2014 15:40:34 +0000 (16:40 +0100)
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 <thomas.egerer@secunet.com>
src/libstrongswan/crypto/proposal/proposal_keywords.c
src/libstrongswan/crypto/proposal/proposal_keywords.h

index 4db504e..bbb97d0 100644 (file)
@@ -56,6 +56,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
         */
        rwlock_t *lock;
@@ -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),
        );
 
index d6107ab..5cdbafc 100644 (file)
@@ -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 <library.h>
 #include <crypto/transform.h>
 
@@ -102,6 +104,17 @@ 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,
+                                                                       proposal_algname_parser_t parser);
+
+       /**
         * Destroy a proposal_keywords_t instance.
         */
        void (*destroy)(proposal_keywords_t *this);