output validity of raw public key if available
[strongswan.git] / src / libcharon / plugins / stroke / stroke_list.c
index 7f2097d..514a91e 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "stroke_list.h"
 
 
 #include "stroke_list.h"
 
+#include <inttypes.h>
 #include <time.h>
 
 #ifdef HAVE_MALLINFO
 #include <time.h>
 
 #ifdef HAVE_MALLINFO
@@ -24,6 +25,7 @@
 #include <hydra.h>
 #include <daemon.h>
 #include <utils/linked_list.h>
 #include <hydra.h>
 #include <daemon.h>
 #include <utils/linked_list.h>
+#include <plugins/plugin.h>
 #include <credentials/certificates/x509.h>
 #include <credentials/certificates/ac.h>
 #include <credentials/certificates/crl.h>
 #include <credentials/certificates/x509.h>
 #include <credentials/certificates/ac.h>
 #include <credentials/certificates/crl.h>
@@ -116,7 +118,7 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all)
 
                ike_proposal = ike_sa->get_proposal(ike_sa);
 
 
                ike_proposal = ike_sa->get_proposal(ike_sa);
 
-               fprintf(out, "%12s[%d]: IKE SPIs: %.16llx_i%s %.16llx_r%s",
+               fprintf(out, "%12s[%d]: IKE SPIs: %.16"PRIx64"_i%s %.16"PRIx64"_r%s",
                                ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
                                id->get_initiator_spi(id), id->is_initiator(id) ? "*" : "",
                                id->get_responder_spi(id), id->is_initiator(id) ? "" : "*");
                                ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa),
                                id->get_initiator_spi(id), id->is_initiator(id) ? "*" : "",
                                id->get_responder_spi(id), id->is_initiator(id) ? "" : "*");
@@ -221,11 +223,14 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
                        {
                                u_int16_t encr_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED;
                                u_int16_t encr_size = 0, int_size = 0;
                        {
                                u_int16_t encr_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED;
                                u_int16_t encr_size = 0, int_size = 0;
+                               u_int16_t esn = NO_EXT_SEQ_NUMBERS;
 
                                proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM,
                                                                                &encr_alg, &encr_size);
                                proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM,
                                                                                &int_alg, &int_size);
 
                                proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM,
                                                                                &encr_alg, &encr_size);
                                proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM,
                                                                                &int_alg, &int_size);
+                               proposal->get_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS,
+                                                                               &esn, NULL);
 
                                if (encr_alg != ENCR_UNDEFINED)
                                {
 
                                if (encr_alg != ENCR_UNDEFINED)
                                {
@@ -243,21 +248,25 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all)
                                                fprintf(out, "_%u", int_size);
                                        }
                                }
                                                fprintf(out, "_%u", int_size);
                                        }
                                }
+                               if (esn == EXT_SEQ_NUMBERS)
+                               {
+                                       fprintf(out, "/ESN");
+                               }
                        }
 
                        now = time_monotonic(NULL);
                        child_sa->get_usestats(child_sa, TRUE, &use_in, &bytes_in);
                        }
 
                        now = time_monotonic(NULL);
                        child_sa->get_usestats(child_sa, TRUE, &use_in, &bytes_in);
-                       fprintf(out, ", %llu bytes_i", bytes_in);
+                       fprintf(out, ", %" PRIu64 " bytes_i", bytes_in);
                        if (use_in)
                        {
                        if (use_in)
                        {
-                               fprintf(out, " (%ds ago)", now - use_in);
+                               fprintf(out, " (%" PRIu64 "s ago)", (u_int64_t)(now - use_in));
                        }
 
                        child_sa->get_usestats(child_sa, FALSE, &use_out, &bytes_out);
                        }
 
                        child_sa->get_usestats(child_sa, FALSE, &use_out, &bytes_out);
-                       fprintf(out, ", %llu bytes_o", bytes_out);
+                       fprintf(out, ", %" PRIu64 " bytes_o", bytes_out);
                        if (use_out)
                        {
                        if (use_out)
                        {
-                               fprintf(out, " (%ds ago)", now - use_out);
+                               fprintf(out, " (%" PRIu64 "s ago)", (u_int64_t)(now - use_out));
                        }
                        fprintf(out, ", rekeying ");
 
                        }
                        fprintf(out, ", rekeying ");
 
@@ -324,7 +333,7 @@ static void log_auth_cfgs(FILE *out, peer_cfg_t *peer_cfg, bool local)
                        {
                                if ((uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR))
                                {
                        {
                                if ((uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR))
                                {
-                                       fprintf(out, "EAP_%d-%d authentication",
+                                       fprintf(out, "EAP_%" PRIuPTR "-%" PRIuPTR " authentication",
                                                (uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE),
                                                (uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR));
                                }
                                                (uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE),
                                                (uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR));
                                }
@@ -397,13 +406,14 @@ METHOD(stroke_list_t, status, void,
        child_cfg_t *child_cfg;
        child_sa_t *child_sa;
        ike_sa_t *ike_sa;
        child_cfg_t *child_cfg;
        child_sa_t *child_sa;
        ike_sa_t *ike_sa;
+       linked_list_t *my_ts, *other_ts;
        bool first, found = FALSE;
        char *name = msg->status.name;
        bool first, found = FALSE;
        char *name = msg->status.name;
+       u_int half_open;
 
        if (all)
        {
                peer_cfg_t *peer_cfg;
 
        if (all)
        {
                peer_cfg_t *peer_cfg;
-               plugin_t *plugin;
                char *pool;
                host_t *host;
                u_int32_t dpd;
                char *pool;
                host_t *host;
                u_int32_t dpd;
@@ -438,14 +448,8 @@ METHOD(stroke_list_t, status, void,
                }
                fprintf(out, ", scheduled: %d\n",
                                lib->scheduler->get_job_load(lib->scheduler));
                }
                fprintf(out, ", scheduled: %d\n",
                                lib->scheduler->get_job_load(lib->scheduler));
-               fprintf(out, "  loaded plugins: ");
-               enumerator = lib->plugins->create_plugin_enumerator(lib->plugins);
-               while (enumerator->enumerate(enumerator, &plugin))
-               {
-                       fprintf(out, "%s ", plugin->get_name(plugin));
-               }
-               enumerator->destroy(enumerator);
-               fprintf(out, "\n");
+               fprintf(out, "  loaded plugins: %s\n",
+                               lib->plugins->loaded_plugins(lib->plugins));
 
                first = TRUE;
                enumerator = this->attribute->create_pool_enumerator(this->attribute);
 
                first = TRUE;
                enumerator = this->attribute->create_pool_enumerator(this->attribute);
@@ -501,12 +505,11 @@ METHOD(stroke_list_t, status, void,
                        children = peer_cfg->create_child_cfg_enumerator(peer_cfg);
                        while (children->enumerate(children, &child_cfg))
                        {
                        children = peer_cfg->create_child_cfg_enumerator(peer_cfg);
                        while (children->enumerate(children, &child_cfg))
                        {
-                               linked_list_t *my_ts, *other_ts;
-
                                my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL);
                                other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL);
                                my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL);
                                other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL);
-                               fprintf(out, "%12s:   child:  %#R=== %#R", child_cfg->get_name(child_cfg),
-                                               my_ts, other_ts);
+                               fprintf(out, "%12s:   child:  %#R=== %#R%N",
+                                               child_cfg->get_name(child_cfg), my_ts, other_ts,
+                                               ipsec_mode_names, child_cfg->get_mode(child_cfg));
                                my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
                                other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
 
                                my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
                                other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
 
@@ -522,10 +525,39 @@ METHOD(stroke_list_t, status, void,
                enumerator->destroy(enumerator);
        }
 
                enumerator->destroy(enumerator);
        }
 
+       /* Enumerate shunt policies */
+       first = TRUE;
+       enumerator = charon->shunts->create_enumerator(charon->shunts);
+       while (enumerator->enumerate(enumerator, &child_cfg))
+       {
+               if (name && !streq(name, child_cfg->get_name(child_cfg)))
+               {
+                       continue;
+               }
+               if (first)
+               {
+                       fprintf(out, "Shunted Connections:\n");
+                       first = FALSE;
+               }
+               my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL);
+               other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL);
+               fprintf(out, "%12s:  %#R=== %#R%N\n",
+                               child_cfg->get_name(child_cfg), my_ts, other_ts,
+                               ipsec_mode_names, child_cfg->get_mode(child_cfg));
+               my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
+               other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
+       }
+       enumerator->destroy(enumerator);
+
+       /* Enumerate traps */
        first = TRUE;
        enumerator = charon->traps->create_enumerator(charon->traps);
        while (enumerator->enumerate(enumerator, NULL, &child_sa))
        {
        first = TRUE;
        enumerator = charon->traps->create_enumerator(charon->traps);
        while (enumerator->enumerate(enumerator, NULL, &child_sa))
        {
+               if (name && !streq(name, child_sa->get_name(child_sa)))
+               {
+                       continue;
+               }
                if (first)
                {
                        fprintf(out, "Routed Connections:\n");
                if (first)
                {
                        fprintf(out, "Routed Connections:\n");
@@ -535,13 +567,17 @@ METHOD(stroke_list_t, status, void,
        }
        enumerator->destroy(enumerator);
 
        }
        enumerator->destroy(enumerator);
 
-       fprintf(out, "Security Associations:\n");
+       half_open = charon->ike_sa_manager->get_half_open_count(
+                                                                                               charon->ike_sa_manager, NULL);
+       fprintf(out, "Security Associations (%u up, %u connecting):\n",
+               charon->ike_sa_manager->get_count(charon->ike_sa_manager) - half_open,
+               half_open);
        enumerator = charon->controller->create_ike_sa_enumerator(
                                                                                                        charon->controller, wait);
        while (enumerator->enumerate(enumerator, &ike_sa))
        {
                bool ike_printed = FALSE;
        enumerator = charon->controller->create_ike_sa_enumerator(
                                                                                                        charon->controller, wait);
        while (enumerator->enumerate(enumerator, &ike_sa))
        {
                bool ike_printed = FALSE;
-               iterator_t *children = ike_sa->create_child_sa_iterator(ike_sa);
+               enumerator_t *children = ike_sa->create_child_sa_enumerator(ike_sa);
 
                if (name == NULL || streq(name, ike_sa->get_name(ike_sa)))
                {
 
                if (name == NULL || streq(name, ike_sa->get_name(ike_sa)))
                {
@@ -550,7 +586,7 @@ METHOD(stroke_list_t, status, void,
                        ike_printed = TRUE;
                }
 
                        ike_printed = TRUE;
                }
 
-               while (children->iterate(children, (void**)&child_sa))
+               while (children->enumerate(children, (void**)&child_sa))
                {
                        if (name == NULL || streq(name, child_sa->get_name(child_sa)))
                        {
                {
                        if (name == NULL || streq(name, child_sa->get_name(child_sa)))
                        {
@@ -593,35 +629,30 @@ static linked_list_t* create_unique_cert_list(certificate_type_t type)
 
        while (enumerator->enumerate(enumerator, (void**)&cert))
        {
 
        while (enumerator->enumerate(enumerator, (void**)&cert))
        {
-               iterator_t *iterator = list->create_iterator(list, TRUE);
+               enumerator_t *added = list->create_enumerator(list);
                identification_t *issuer = cert->get_issuer(cert);
                identification_t *issuer = cert->get_issuer(cert);
-               bool previous_same, same = FALSE, last = TRUE;
+               bool previous_same, same = FALSE, found = FALSE;
                certificate_t *list_cert;
 
                certificate_t *list_cert;
 
-               while (iterator->iterate(iterator, (void**)&list_cert))
+               while (added->enumerate(added, (void**)&list_cert))
                {
                {
-                       /* exit if we have a duplicate? */
                        if (list_cert->equals(list_cert, cert))
                        if (list_cert->equals(list_cert, cert))
-                       {
-                               last = FALSE;
+                       {       /* stop if we found a duplicate*/
+                               found = TRUE;
                                break;
                        }
                                break;
                        }
-                       /* group certificates with same issuer */
                        previous_same = same;
                        same = list_cert->has_issuer(list_cert, issuer);
                        if (previous_same && !same)
                        previous_same = same;
                        same = list_cert->has_issuer(list_cert, issuer);
                        if (previous_same && !same)
-                       {
-                               iterator->insert_before(iterator, (void *)cert->get_ref(cert));
-                               last = FALSE;
+                       {       /* group certificates with same issuer */
                                break;
                        }
                }
                                break;
                        }
                }
-               iterator->destroy(iterator);
-
-               if (last)
+               if (!found)
                {
                {
-                       list->insert_last(list, (void *)cert->get_ref(cert));
+                       list->insert_before(list, added, cert->get_ref(cert));
                }
                }
+               added->destroy(added);
        }
        enumerator->destroy(enumerator);
        return list;
        }
        enumerator->destroy(enumerator);
        return list;
@@ -668,12 +699,14 @@ static void list_public_key(public_key_t *public, FILE *out)
 static void stroke_list_pubkeys(linked_list_t *list, bool utc, FILE *out)
 {
        bool first = TRUE;
 static void stroke_list_pubkeys(linked_list_t *list, bool utc, FILE *out)
 {
        bool first = TRUE;
-
-       enumerator_t *enumerator = list->create_enumerator(list);
+       time_t now = time(NULL), notBefore, notAfter;
+       enumerator_t *enumerator;
        certificate_t *cert;
 
        certificate_t *cert;
 
+       enumerator = list->create_enumerator(list);
        while (enumerator->enumerate(enumerator, (void**)&cert))
        {
        while (enumerator->enumerate(enumerator, (void**)&cert))
        {
+               identification_t *subject = cert->get_subject(cert);
                public_key_t *public = cert->get_public_key(cert);
 
                if (public)
                public_key_t *public = cert->get_public_key(cert);
 
                if (public)
@@ -686,6 +719,41 @@ static void stroke_list_pubkeys(linked_list_t *list, bool utc, FILE *out)
                        }
                        fprintf(out, "\n");
 
                        }
                        fprintf(out, "\n");
 
+                       /* list subject if available */
+                       if (subject->get_type(subject) != ID_KEY_ID)
+                       {
+                               fprintf(out, "  subject:   %#Y\n", subject);
+                       }
+
+                       /* list validity if available*/
+                       cert->get_validity(cert, &now, &notBefore, &notAfter);
+                       if (notBefore != UNDEFINED_TIME && notAfter != UNDEFINED_TIME)
+                       {
+                               fprintf(out, "  validity:  not before %T, ", &notBefore, utc);
+                               if (now < notBefore)
+                               {
+                                       fprintf(out, "not valid yet (valid in %V)\n", &now, &notBefore);
+                               }
+                               else
+                               {
+                                       fprintf(out, "ok\n");
+                               }
+                               fprintf(out, "             not after  %T, ", &notAfter, utc);
+                               if (now > notAfter)
+                               {
+                                       fprintf(out, "expired (%V ago)\n", &now, &notAfter);
+                               }
+                               else
+                               {
+                                       fprintf(out, "ok");
+                                       if (now > notAfter - CERT_WARNING_INTERVAL * 60 * 60 * 24)
+                                       {
+                                               fprintf(out, " (expires in %V)", &now, &notAfter);
+                                       }
+                                       fprintf(out, " \n");
+                               }
+                       }
+
                        list_public_key(public, out);
                        public->destroy(public);
                }
                        list_public_key(public, out);
                        public->destroy(public);
                }
@@ -802,7 +870,7 @@ static void stroke_list_certs(linked_list_t *list, char *label,
 
                        fprintf(out, "  subject:  \"%Y\"\n", cert->get_subject(cert));
                        fprintf(out, "  issuer:   \"%Y\"\n", cert->get_issuer(cert));
 
                        fprintf(out, "  subject:  \"%Y\"\n", cert->get_subject(cert));
                        fprintf(out, "  issuer:   \"%Y\"\n", cert->get_issuer(cert));
-                       serial = x509->get_serial(x509);
+                       serial = chunk_skip_zero(x509->get_serial(x509));
                        fprintf(out, "  serial:    %#B\n", &serial);
 
                        /* list validity */
                        fprintf(out, "  serial:    %#B\n", &serial);
 
                        /* list validity */
@@ -915,7 +983,7 @@ static void stroke_list_acerts(linked_list_t *list, bool utc, FILE *out)
                {
                        fprintf(out, "  hissuer:  \"%Y\"\n", id);
                }
                {
                        fprintf(out, "  hissuer:  \"%Y\"\n", id);
                }
-               chunk = ac->get_holderSerial(ac);
+               chunk = chunk_skip_zero(ac->get_holderSerial(ac));
                if (chunk.ptr)
                {
                        fprintf(out, "  hserial:   %#B\n", &chunk);
                if (chunk.ptr)
                {
                        fprintf(out, "  hserial:   %#B\n", &chunk);
@@ -927,7 +995,7 @@ static void stroke_list_acerts(linked_list_t *list, bool utc, FILE *out)
                        groups->destroy(groups);
                }
                fprintf(out, "  issuer:   \"%Y\"\n", cert->get_issuer(cert));
                        groups->destroy(groups);
                }
                fprintf(out, "  issuer:   \"%Y\"\n", cert->get_issuer(cert));
-               chunk  = ac->get_serial(ac);
+               chunk  = chunk_skip_zero(ac->get_serial(ac));
                fprintf(out, "  serial:    %#B\n", &chunk);
 
                /* list validity */
                fprintf(out, "  serial:    %#B\n", &chunk);
 
                /* list validity */
@@ -984,13 +1052,14 @@ static void stroke_list_crls(linked_list_t *list, bool utc, FILE *out)
                fprintf(out, "  issuer:   \"%Y\"\n", cert->get_issuer(cert));
 
                /* list optional crlNumber */
                fprintf(out, "  issuer:   \"%Y\"\n", cert->get_issuer(cert));
 
                /* list optional crlNumber */
-               chunk = crl->get_serial(crl);
+               chunk = chunk_skip_zero(crl->get_serial(crl));
                if (chunk.ptr)
                {
                        fprintf(out, "  serial:    %#B\n", &chunk);
                }
                if (crl->is_delta_crl(crl, &chunk))
                {
                if (chunk.ptr)
                {
                        fprintf(out, "  serial:    %#B\n", &chunk);
                }
                if (crl->is_delta_crl(crl, &chunk))
                {
+                       chunk = chunk_skip_zero(chunk);         
                        fprintf(out, "  delta for: %#B\n", &chunk);
                }
 
                        fprintf(out, "  delta for: %#B\n", &chunk);
                }
 
@@ -1168,6 +1237,58 @@ static void list_algs(FILE *out)
        fprintf(out, "\n");
 }
 
        fprintf(out, "\n");
 }
 
+/**
+ * List loaded plugin information
+ */
+static void list_plugins(FILE *out)
+{
+       plugin_feature_t *features, *fp;
+       enumerator_t *enumerator;
+       linked_list_t *list;
+       plugin_t *plugin;
+       int count, i;
+       bool loaded;
+       char *str;
+
+       fprintf(out, "\n");
+       fprintf(out, "List of loaded Plugins:\n");
+       fprintf(out, "\n");
+
+       enumerator = lib->plugins->create_plugin_enumerator(lib->plugins);
+       while (enumerator->enumerate(enumerator, &plugin, &list))
+       {
+               fprintf(out, "%s:\n", plugin->get_name(plugin));
+               if (plugin->get_features)
+               {
+                       count = plugin->get_features(plugin, &features);
+                       for (i = 0; i < count; i++)
+                       {
+                               str = plugin_feature_get_string(&features[i]);
+                               switch (features[i].kind)
+                               {
+                                       case FEATURE_PROVIDE:
+                                               fp = &features[i];
+                                               loaded = list->find_first(list, NULL,
+                                                                                                 (void**)&fp) == SUCCESS;
+                                               fprintf(out, "    %s%s\n",
+                                                               str, loaded ? "" : " (not loaded)");
+                                               break;
+                                       case FEATURE_DEPENDS:
+                                               fprintf(out, "        %s\n", str);
+                                               break;
+                                       case FEATURE_SDEPEND:
+                                               fprintf(out, "        %s(soft)\n", str);
+                                               break;
+                                       default:
+                                               break;
+                               }
+                               free(str);
+                       }
+               }
+       }
+       enumerator->destroy(enumerator);
+}
+
 METHOD(stroke_list_t, list, void,
        private_stroke_list_t *this, stroke_msg_t *msg, FILE *out)
 {
 METHOD(stroke_list_t, list, void,
        private_stroke_list_t *this, stroke_msg_t *msg, FILE *out)
 {
@@ -1239,6 +1360,10 @@ METHOD(stroke_list_t, list, void,
        {
                list_algs(out);
        }
        {
                list_algs(out);
        }
+       if (msg->list.flags & LIST_PLUGINS)
+       {
+               list_plugins(out);
+       }
 }
 
 /**
 }
 
 /**