]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
vici: flush-certs command flushes certificate cache
authorAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 8 Sep 2016 09:59:02 +0000 (11:59 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 13 Sep 2016 15:02:59 +0000 (17:02 +0200)
When fresh CRLs are released with a high update frequency (e.g.
every 24 hours) or OCSP is used then the certificate cache gets
quickly filled with stale CRLs or OCSP responses. The new VICI
flush-certs command allows to flush e.g. cached CRLs or OCSP
responses only. Without the type argument all kind of certificates
(e.g. also received end entity and intermediate CA certificates)
are purged.

src/libcharon/plugins/vici/README.md
src/libcharon/plugins/vici/perl/Vici-Session/README.pod
src/libcharon/plugins/vici/perl/Vici-Session/lib/Vici/Session.pm
src/libcharon/plugins/vici/python/vici/session.py
src/libcharon/plugins/vici/ruby/lib/vici.rb
src/libcharon/plugins/vici/vici_cred.c
src/swanctl/Makefile.am
src/swanctl/command.h
src/swanctl/commands/flush_certs.c [new file with mode: 0644]

index cf5a85a8df8bb273ddd53ef6c63de726e1306334..18a3ef7b5d0ce369f781746025c889410058aebb 100644 (file)
@@ -481,6 +481,19 @@ Load a shared IKE PSK, EAP or XAuth secret into the daemon.
                errmsg = <error string on failure>
        }
 
+### flush-certs() ###
+
+Flushes the certificate cache. The optional type argument allows to flush
+only certificates of a given type, e.g. all cached CRLs.
+
+       {
+               type = <certificate type to filter for, X509|X509_AC|X509_CRL|
+                                                                                               OCSP_RESPONSE|PUBKEY or ANY>
+       } => {
+               success = <yes or no>
+               errmsg = <error string on failure>
+       }
+
 ### clear-creds() ###
 
 Clear all loaded certificate, private key and shared key credentials. This
index de374aa11fa7a242630a9722f2ec453325879ae6..d19739709f164517b580a60bc833f3b3a0395a7e 100644 (file)
@@ -560,6 +560,21 @@ print "----- unload-authority -----\n";
 ($res, $errmsg) = $session->unload_authority(Vici::Message->new(\%vars));
 print $res ? "ok\n" : "failed: $errmsg\n";
 
+=item flush_certs()
+
+flushes the volatile certificate cache. Optionally only a given certificate
+type is flushed.
+
+  my %vars = ( type => 'x509_crl' );
+  my ($res, $errmsg) = $session->flush_certs(Vici::Message->new(\%vars));
+
+=cut
+
+print "----- flush-certs -----\n";
+%vars = ( type => 'x509_crl' );
+($res, $errmsg) = $session->flush_certs(Vici::Message->new(\%vars));
+print $res ? "ok\n" : "failed: $errmsg\n";
+
 =item clear_creds()
 
 clears all loaded certificate, private key and shared key credentials. This
index 78197136aed8bcfa0603d66413cf182c76ed0ca8..5c09b14edf5ce656487309cd8bbebd03455f2e08 100644 (file)
@@ -96,6 +96,10 @@ sub load_shared {
     return request_vars_res('load-shared', @_);
 }
 
+sub flush_certs {
+    return request_vars_res('flush-certs', @_);
+}
+
 sub clear_creds {
    return request_res('clear-creds', @_);
 }
index 66de8590a92b1f159814161e2feec13d55100ce6..eabdb42269d0c731cfae7c37db2ceed54cc41781 100644 (file)
@@ -166,6 +166,17 @@ class Session(object):
         """
         self.handler.request("load-shared", secret)
 
+     def flush_certs(self, filter=None):
+        """Flush the volatile certificate cache.
+
+        Flush the certificate stored temporarily in the cache. The filter
+        allows to flush only a certain type of certificates, e.g. CRLs.
+
+        :param filter: flush only certificates of a given type (optional)
+        :type filter: dict
+        """
+        self.handler.request("flush-certs", filter)
+
     def clear_creds(self):
         """Clear credentials loaded over vici.
 
index 018f507661c0ed401fdeeb392d3421a5548503ea..1a95fc3dd3630fb4fde571b370df5241f4d4331a 100644 (file)
@@ -448,6 +448,12 @@ module Vici
       @transp.request("get-conns").root
     end
 
+    ##
+    # Flush credential cache.
+    def flush_certs((match = nil)
+      check_success(@transp.request("flush-certs", Message.new(match)))
+    end
+
     ##
     # Clear all loaded credentials.
     def clear_creds()
index 3411b7d6cc51dc433a999e445e4b85584e8883c2..40ba57e987829d68e50284cfb849d55394e1834f 100644 (file)
@@ -287,6 +287,24 @@ CALLBACK(clear_creds, vici_message_t*,
        return create_reply(NULL);
 }
 
+CALLBACK(flush_certs, vici_message_t*,
+       private_vici_cred_t *this, char *name, u_int id, vici_message_t *message)
+{
+       certificate_type_t type = CERT_ANY;
+       x509_flag_t flag = X509_NONE;
+       char *str;
+
+       str = message->get_str(message, NULL, "type");
+       if (str && !enum_from_name(certificate_type_names, str, &type) &&
+                          !vici_cert_info_from_str(str, &type, &flag))
+       {
+               return create_reply("invalid certificate type '%s'", str);
+       }
+       lib->credmgr->flush_cache(lib->credmgr, type);
+
+       return create_reply(NULL);
+}
+
 static void manage_command(private_vici_cred_t *this,
                                                   char *name, vici_command_cb_t cb, bool reg)
 {
@@ -300,6 +318,7 @@ static void manage_command(private_vici_cred_t *this,
 static void manage_commands(private_vici_cred_t *this, bool reg)
 {
        manage_command(this, "clear-creds", clear_creds, reg);
+       manage_command(this, "flush-certs", flush_certs, reg);
        manage_command(this, "load-cert", load_cert, reg);
        manage_command(this, "load-key", load_key, reg);
        manage_command(this, "load-shared", load_shared, reg);
index 37a0224c393dd3bfb50fd44d654133d75d91ab3f..409387849ab6ad6d5babd8f5f3667df9b32c577d 100644 (file)
@@ -13,6 +13,7 @@ swanctl_SOURCES = \
        commands/list_certs.c \
        commands/list_pools.c \
        commands/list_algs.c \
+       commands/flush_certs.c \
        commands/load_all.c \
        commands/load_authorities.h  commands/load_authorities.c \
        commands/load_conns.c commands/load_conns.h \
index 8d0a2e6b97bdeac0e70b7a3cb1cd6b256fc1a9f1..7b92ae91a363f8e06d7c1229c6520eab87260215 100644 (file)
@@ -27,7 +27,7 @@
 /**
  * Maximum number of commands (+1).
  */
-#define MAX_COMMANDS 23
+#define MAX_COMMANDS 24
 
 /**
  * Maximum number of options in a command (+3)
diff --git a/src/swanctl/commands/flush_certs.c b/src/swanctl/commands/flush_certs.c
new file mode 100644 (file)
index 0000000..527419f
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2016 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * 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 <errno.h>
+
+#include "command.h"
+
+static int flush_certs(vici_conn_t *conn)
+{
+       vici_req_t *req;
+       vici_res_t *res;
+       command_format_options_t format = COMMAND_FORMAT_NONE;
+       char *arg, *type = NULL;
+       int ret;
+
+       while (TRUE)
+       {
+               switch (command_getopt(&arg))
+               {
+                       case 'h':
+                               return command_usage(NULL);
+                       case 't':
+                               type = arg;
+                               continue;
+                       case 'P':
+                               format |= COMMAND_FORMAT_PRETTY;
+                               /* fall through to raw */
+                       case 'r':
+                               format |= COMMAND_FORMAT_RAW;
+                               continue;
+                       case EOF:
+                               break;
+                       default:
+                               return command_usage("invalid --flush-certs option");
+               }
+               break;
+       }
+       req = vici_begin("flush-certs");
+
+       if (type)
+       {
+               vici_add_key_valuef(req, "type", "%s", type);
+       }
+       res = vici_submit(req, conn);
+
+       if (!res)
+       {
+               ret = errno;
+               fprintf(stderr, "flush-certs request failed: %s\n", strerror(errno));
+               return ret;
+       }
+       if (format & COMMAND_FORMAT_RAW)
+       {
+               vici_dump(res, "flush-certs reply", format & COMMAND_FORMAT_PRETTY,
+                                 stdout);
+       }
+       vici_free_res(res);
+
+       return 0;
+}
+
+/**
+ * Register the command.
+ */
+static void __attribute__ ((constructor))reg()
+{
+       command_register((command_t) {
+               flush_certs, 'f', "flush-certs", "flush cached certificates",
+               {"[--type x509|x509_ac|x509_crl|ocsp_response|pubkey]",
+                "[--raw|--pretty]"},
+               {
+                       {"help",                'h', 0, "show usage information"},
+                       {"type",                't', 1, "filter by certificate type"},
+                       {"raw",                 'r', 0, "dump raw response message"},
+                       {"pretty",              'P', 0, "dump raw response message in pretty print"},
+               }
+       });
+}