Register a certexpire listener collecting trustchain information
authorMartin Willi <martin@revosec.ch>
Thu, 4 Aug 2011 09:52:57 +0000 (11:52 +0200)
committerMartin Willi <martin@revosec.ch>
Mon, 22 Aug 2011 16:42:33 +0000 (18:42 +0200)
src/libcharon/plugins/certexpire/Makefile.am
src/libcharon/plugins/certexpire/certexpire_listener.c [new file with mode: 0644]
src/libcharon/plugins/certexpire/certexpire_listener.h [new file with mode: 0644]
src/libcharon/plugins/certexpire/certexpire_plugin.c

index 806cb94..af20490 100644 (file)
@@ -11,6 +11,7 @@ else
 plugin_LTLIBRARIES = libstrongswan-certexpire.la
 endif
 
-libstrongswan_certexpire_la_SOURCES = certexpire_plugin.h certexpire_plugin.c
+libstrongswan_certexpire_la_SOURCES = certexpire_plugin.h certexpire_plugin.c \
+       certexpire_listener.h certexpire_listener.c
 
 libstrongswan_certexpire_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/certexpire/certexpire_listener.c b/src/libcharon/plugins/certexpire/certexpire_listener.c
new file mode 100644 (file)
index 0000000..67a9a65
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "certexpire_listener.h"
+
+#include <daemon.h>
+
+typedef struct private_certexpire_listener_t private_certexpire_listener_t;
+
+/**
+ * Private data of an certexpire_listener_t object.
+ */
+struct private_certexpire_listener_t {
+
+       /**
+        * Public certexpire_listener_t interface.
+        */
+       certexpire_listener_t public;
+};
+
+METHOD(listener_t, authorize, bool,
+       private_certexpire_listener_t *this, ike_sa_t *ike_sa,
+       bool final, bool *success)
+{
+       enumerator_t *rounds, *enumerator;
+       certificate_t *cert, *ca = NULL;
+       linked_list_t *trustchain;
+       auth_cfg_t *auth;
+       auth_rule_t rule;
+
+       /* Check all rounds in final hook, as local authentication data are
+        * not completely available after round-invocation. */
+       if (!final)
+       {
+               return TRUE;
+       }
+
+       /* collect local certificates */
+       trustchain = linked_list_create();
+       rounds = ike_sa->create_auth_cfg_enumerator(ike_sa, TRUE);
+       while (rounds->enumerate(rounds, &auth))
+       {
+               cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
+               if (cert)
+               {
+                       trustchain->insert_last(trustchain, cert);
+
+                       enumerator = auth->create_enumerator(auth);
+                       while (enumerator->enumerate(enumerator, &rule, &cert))
+                       {
+                               if (rule == AUTH_RULE_IM_CERT)
+                               {
+                                       trustchain->insert_last(trustchain, cert);
+                               }
+                               if (rule == AUTH_RULE_CA_CERT)
+                               {
+                                       /* the last CA cert is the one used in the trustchain.
+                                        * Previous CA certificates have been received as cert
+                                        * requests. */
+                                       ca = cert;
+                               }
+                       }
+                       enumerator->destroy(enumerator);
+                       if (ca)
+                       {
+                               trustchain->insert_last(trustchain, ca);
+                       }
+               }
+       }
+       rounds->destroy(rounds);
+       /* TODO: handle trustchain expiry information */
+       trustchain->destroy(trustchain);
+
+       /* collect remote certificates */
+       trustchain = linked_list_create();
+       rounds = ike_sa->create_auth_cfg_enumerator(ike_sa, FALSE);
+       while (rounds->enumerate(rounds, &auth))
+       {
+               cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT);
+               if (cert)
+               {
+                       trustchain->insert_last(trustchain, cert);
+
+                       enumerator = auth->create_enumerator(auth);
+                       while (enumerator->enumerate(enumerator, &rule, &cert))
+                       {
+                               if (rule == AUTH_RULE_IM_CERT)
+                               {
+                                       trustchain->insert_last(trustchain, cert);
+                               }
+                       }
+                       enumerator->destroy(enumerator);
+
+                       cert = auth->get(auth, AUTH_RULE_CA_CERT);
+                       if (cert)
+                       {
+                               trustchain->insert_last(trustchain, cert);
+                       }
+               }
+       }
+       rounds->destroy(rounds);
+       /* TODO: handle trustchain expiry information */
+       trustchain->destroy(trustchain);
+       return TRUE;
+}
+
+METHOD(certexpire_listener_t, destroy, void,
+       private_certexpire_listener_t *this)
+{
+       free(this);
+}
+
+/**
+ * See header
+ */
+certexpire_listener_t *certexpire_listener_create()
+{
+       private_certexpire_listener_t *this;
+
+       INIT(this,
+               .public = {
+                       .listener = {
+                               .authorize = _authorize,
+                       },
+                       .destroy = _destroy,
+               },
+       );
+
+       return &this->public;
+}
diff --git a/src/libcharon/plugins/certexpire/certexpire_listener.h b/src/libcharon/plugins/certexpire/certexpire_listener.h
new file mode 100644 (file)
index 0000000..7187435
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup certexpire_listener certexpire_listener
+ * @{ @ingroup certexpire
+ */
+
+#ifndef CERTEXPIRE_LISTENER_H_
+#define CERTEXPIRE_LISTENER_H_
+
+#include <bus/listeners/listener.h>
+
+typedef struct certexpire_listener_t certexpire_listener_t;
+
+/**
+ * Listener collecting certificate expire information after authentication.
+ */
+struct certexpire_listener_t {
+
+       /**
+        * Implements listener_t interface.
+        */
+       listener_t listener;
+
+       /**
+        * Destroy a certexpire_listener_t.
+        */
+       void (*destroy)(certexpire_listener_t *this);
+};
+
+/**
+ * Create a certexpire_listener instance.
+ */
+certexpire_listener_t *certexpire_listener_create();
+
+#endif /** CERTEXPIRE_LISTENER_H_ @}*/
index 8f92b58..795e8a1 100644 (file)
@@ -15,6 +15,8 @@
 
 #include "certexpire_plugin.h"
 
+#include "certexpire_listener.h"
+
 #include <daemon.h>
 
 typedef struct private_certexpire_plugin_t private_certexpire_plugin_t;
@@ -28,6 +30,11 @@ struct private_certexpire_plugin_t {
         * Implements plugin interface
         */
        certexpire_plugin_t public;
+
+       /**
+        * Listener collecting expire information
+        */
+       certexpire_listener_t *listener;
 };
 
 METHOD(plugin_t, get_name, char*,
@@ -39,6 +46,8 @@ METHOD(plugin_t, get_name, char*,
 METHOD(plugin_t, destroy, void,
        private_certexpire_plugin_t *this)
 {
+       charon->bus->remove_listener(charon->bus, &this->listener->listener);
+       this->listener->destroy(this->listener);
        free(this);
 }
 
@@ -57,7 +66,9 @@ plugin_t *certexpire_plugin_create()
                                .destroy = _destroy,
                        },
                },
+               .listener = certexpire_listener_create(),
        );
+       charon->bus->add_listener(charon->bus, &this->listener->listener);
 
        return &this->public.plugin;
 }