diff options
Diffstat (limited to 'src/libcharon/plugins/stroke')
-rw-r--r-- | src/libcharon/plugins/stroke/Makefile.in | 33 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_config.c | 79 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_control.c | 100 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_counter.c | 222 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_counter.h | 10 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_cred.c | 49 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_list.c | 19 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_socket.c | 44 |
8 files changed, 459 insertions, 97 deletions
diff --git a/src/libcharon/plugins/stroke/Makefile.in b/src/libcharon/plugins/stroke/Makefile.in index 38924708a..77497e2b9 100644 --- a/src/libcharon/plugins/stroke/Makefile.in +++ b/src/libcharon/plugins/stroke/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.11.3 from Makefile.am. +# Makefile.in generated by automake 1.11.6 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -16,6 +16,23 @@ @SET_MAKE@ VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -109,6 +126,11 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libstrongswan_stroke_la_SOURCES) DIST_SOURCES = $(libstrongswan_stroke_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -125,6 +147,8 @@ BTLIB = @BTLIB@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ +CHECK_CFLAGS = @CHECK_CFLAGS@ +CHECK_LIBS = @CHECK_LIBS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ @@ -141,6 +165,7 @@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GPERF = @GPERF@ +GPRBUILD = @GPRBUILD@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ @@ -209,8 +234,6 @@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ attest_plugins = @attest_plugins@ -axis2c_CFLAGS = @axis2c_CFLAGS@ -axis2c_LIBS = @axis2c_LIBS@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ @@ -266,7 +289,6 @@ nm_ca_dir = @nm_ca_dir@ nm_plugins = @nm_plugins@ oldincludedir = @oldincludedir@ openac_plugins = @openac_plugins@ -p_plugins = @p_plugins@ pcsclite_CFLAGS = @pcsclite_CFLAGS@ pcsclite_LIBS = @pcsclite_LIBS@ pdfdir = @pdfdir@ @@ -368,7 +390,6 @@ clean-noinstLTLIBRARIES: done install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) @$(NORMAL_INSTALL) - test -z "$(plugindir)" || $(MKDIR_P) "$(DESTDIR)$(plugindir)" @list='$(plugin_LTLIBRARIES)'; test -n "$(plugindir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ @@ -376,6 +397,8 @@ install-pluginLTLIBRARIES: $(plugin_LTLIBRARIES) else :; fi; \ done; \ test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(plugindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(plugindir)" || exit 1; \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(plugindir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(plugindir)"; \ } diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c index 9f6124dc9..86f0fe431 100644 --- a/src/libcharon/plugins/stroke/stroke_config.c +++ b/src/libcharon/plugins/stroke/stroke_config.c @@ -234,7 +234,8 @@ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg msg->add_conn.other.address, msg->add_conn.other.allow_any, msg->add_conn.other.ikeport, - msg->add_conn.fragmentation); + msg->add_conn.fragmentation, + msg->add_conn.ikedscp); add_proposals(this, msg->add_conn.algorithms.ike, ike_cfg, NULL); return ike_cfg; } @@ -447,39 +448,43 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this, identity = identification_create_from_string(id); if (cert) { - certificate = this->cred->load_peer(this->cred, cert); - if (certificate) + enumerator_t *enumerator; + bool has_subject = FALSE; + certificate_t *first = NULL; + + enumerator = enumerator_create_token(cert, ",", " "); + while (enumerator->enumerate(enumerator, &cert)) { - if (local) - { - this->ca->check_for_hash_and_url(this->ca, certificate); - } - cfg->add(cfg, AUTH_RULE_SUBJECT_CERT, certificate); - if (identity->get_type(identity) == ID_ANY || - !certificate->has_subject(certificate, identity)) + certificate = this->cred->load_peer(this->cred, cert); + if (certificate) { - DBG1(DBG_CFG, " id '%Y' not confirmed by certificate, " - "defaulting to '%Y'", identity, - certificate->get_subject(certificate)); - identity->destroy(identity); - identity = certificate->get_subject(certificate); - identity = identity->clone(identity); + if (local) + { + this->ca->check_for_hash_and_url(this->ca, certificate); + } + cfg->add(cfg, AUTH_RULE_SUBJECT_CERT, certificate); + if (!first) + { + first = certificate; + } + if (identity->get_type(identity) != ID_ANY && + certificate->has_subject(certificate, identity)) + { + has_subject = TRUE; + } } } - } - if (identity->get_type(identity) != ID_ANY) - { - cfg->add(cfg, AUTH_RULE_IDENTITY, identity); - if (loose) + enumerator->destroy(enumerator); + + if (first && !has_subject) { - cfg->add(cfg, AUTH_RULE_IDENTITY_LOOSE, TRUE); + DBG1(DBG_CFG, " id '%Y' not confirmed by certificate, " + "defaulting to '%Y'", identity, first->get_subject(first)); + identity->destroy(identity); + identity = first->get_subject(first); + identity = identity->clone(identity); } } - else - { - identity->destroy(identity); - } - /* add raw RSA public key */ pubkey = end->rsakey; if (pubkey && !streq(pubkey, "") && !streq(pubkey, "%cert")) @@ -491,6 +496,18 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this, cfg->add(cfg, AUTH_RULE_SUBJECT_CERT, certificate); } } + if (identity->get_type(identity) != ID_ANY) + { + cfg->add(cfg, AUTH_RULE_IDENTITY, identity); + if (loose) + { + cfg->add(cfg, AUTH_RULE_IDENTITY_LOOSE, TRUE); + } + } + else + { + identity->destroy(identity); + } /* CA constraint */ if (ca) @@ -877,7 +894,7 @@ static void add_ts(private_stroke_config_t *this, if (end->tohost) { ts = traffic_selector_create_dynamic(end->protocol, - end->port ? end->port : 0, end->port ? end->port : 65535); + end->from_port, end->to_port); child_cfg->add_traffic_selector(child_cfg, local, ts); } else @@ -890,7 +907,7 @@ static void add_ts(private_stroke_config_t *this, if (net) { ts = traffic_selector_create_from_subnet(net, 0, end->protocol, - end->port); + end->from_port, end->to_port); child_cfg->add_traffic_selector(child_cfg, local, ts); } } @@ -902,8 +919,8 @@ static void add_ts(private_stroke_config_t *this, enumerator = enumerator_create_token(end->subnets, ",", " "); while (enumerator->enumerate(enumerator, &subnet)) { - ts = traffic_selector_create_from_cidr(subnet, - end->protocol, end->port); + ts = traffic_selector_create_from_cidr(subnet, end->protocol, + end->from_port, end->to_port); if (ts) { child_cfg->add_traffic_selector(child_cfg, local, ts); diff --git a/src/libcharon/plugins/stroke/stroke_control.c b/src/libcharon/plugins/stroke/stroke_control.c index 233d4088f..91130d1ee 100644 --- a/src/libcharon/plugins/stroke/stroke_control.c +++ b/src/libcharon/plugins/stroke/stroke_control.c @@ -33,6 +33,11 @@ struct private_stroke_control_t { * public functions */ stroke_control_t public; + + /** + * Timeout for stroke commands, im ms + */ + u_int timeout; }; @@ -97,8 +102,8 @@ static child_cfg_t* get_child_from_peer(peer_cfg_t *peer_cfg, char *name) /** * call the charon controller to initiate the connection */ -static void charon_initiate(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg, - stroke_msg_t *msg, FILE *out) +static void charon_initiate(private_stroke_control_t *this, peer_cfg_t *peer_cfg, + child_cfg_t *child_cfg, stroke_msg_t *msg, FILE *out) { if (msg->output_verbosity < 0) { @@ -108,9 +113,27 @@ static void charon_initiate(peer_cfg_t *peer_cfg, child_cfg_t *child_cfg, else { stroke_log_info_t info = { msg->output_verbosity, out }; + status_t status; - charon->controller->initiate(charon->controller, peer_cfg, child_cfg, - (controller_cb_t)stroke_log, &info, 0); + status = charon->controller->initiate(charon->controller, + peer_cfg, child_cfg, (controller_cb_t)stroke_log, + &info, this->timeout); + switch (status) + { + case SUCCESS: + fprintf(out, "connection '%s' established successfully\n", + msg->initiate.name); + break; + case OUT_OF_RES: + fprintf(out, "connection '%s' not established after %dms, " + "detaching\n", msg->initiate.name, this->timeout); + break; + default: + case FAILED: + fprintf(out, "establishing connection '%s' failed\n", + msg->initiate.name); + break; + } } } @@ -133,7 +156,7 @@ METHOD(stroke_control_t, initiate, void, while (enumerator->enumerate(enumerator, &child_cfg)) { empty = FALSE; - charon_initiate(peer_cfg->get_ref(peer_cfg), + charon_initiate(this, peer_cfg->get_ref(peer_cfg), child_cfg->get_ref(child_cfg), msg, out); } enumerator->destroy(enumerator); @@ -169,7 +192,7 @@ METHOD(stroke_control_t, initiate, void, return; } } - charon_initiate(peer_cfg, child_cfg, msg, out); + charon_initiate(this, peer_cfg, child_cfg, msg, out); } /** @@ -239,6 +262,41 @@ static bool parse_specifier(char *string, u_int32_t *id, return TRUE; } +/** + * Report the result of a terminate() call to console + */ +static void report_terminate_status(private_stroke_control_t *this, + status_t status, FILE *out, u_int32_t id, bool child) +{ + char *prefix, *postfix; + + if (child) + { + prefix = "CHILD_SA {"; + postfix = "}"; + } + else + { + prefix = "IKE_SA ["; + postfix = "]"; + } + + switch (status) + { + case SUCCESS: + fprintf(out, "%s%d%s closed successfully\n", prefix, id, postfix); + break; + case OUT_OF_RES: + fprintf(out, "%s%d%s not closed after %dms, detaching\n", + prefix, id, postfix, this->timeout); + break; + default: + case FAILED: + fprintf(out, "closing %s%d%s failed\n", prefix, id, postfix); + break; + } +} + METHOD(stroke_control_t, terminate, void, private_stroke_control_t *this, stroke_msg_t *msg, FILE *out) { @@ -250,6 +308,7 @@ METHOD(stroke_control_t, terminate, void, linked_list_t *ike_list, *child_list; stroke_log_info_t info; uintptr_t del; + status_t status; if (!parse_specifier(msg->terminate.name, &id, &name, &child, &all)) { @@ -264,15 +323,15 @@ METHOD(stroke_control_t, terminate, void, { if (child) { - charon->controller->terminate_child(charon->controller, id, - (controller_cb_t)stroke_log, &info, 0); + status = charon->controller->terminate_child(charon->controller, id, + (controller_cb_t)stroke_log, &info, this->timeout); } else { - charon->controller->terminate_ike(charon->controller, id, - (controller_cb_t)stroke_log, &info, 0); + status = charon->controller->terminate_ike(charon->controller, id, + (controller_cb_t)stroke_log, &info, this->timeout); } - return; + return report_terminate_status(this, status, out, id, child); } ike_list = linked_list_create(); @@ -320,16 +379,18 @@ METHOD(stroke_control_t, terminate, void, enumerator = child_list->create_enumerator(child_list); while (enumerator->enumerate(enumerator, &del)) { - charon->controller->terminate_child(charon->controller, del, - (controller_cb_t)stroke_log, &info, 0); + status = charon->controller->terminate_child(charon->controller, del, + (controller_cb_t)stroke_log, &info, this->timeout); + report_terminate_status(this, status, out, del, TRUE); } enumerator->destroy(enumerator); enumerator = ike_list->create_enumerator(ike_list); while (enumerator->enumerate(enumerator, &del)) { - charon->controller->terminate_ike(charon->controller, del, - (controller_cb_t)stroke_log, &info, 0); + status = charon->controller->terminate_ike(charon->controller, del, + (controller_cb_t)stroke_log, &info, this->timeout); + report_terminate_status(this, status, out, del, FALSE); } enumerator->destroy(enumerator); @@ -487,6 +548,7 @@ METHOD(stroke_control_t, purge_ike, void, linked_list_t *list; uintptr_t del; stroke_log_info_t info; + status_t status; info.out = out; info.level = msg->output_verbosity; @@ -509,8 +571,9 @@ METHOD(stroke_control_t, purge_ike, void, enumerator = list->create_enumerator(list); while (enumerator->enumerate(enumerator, &del)) { - charon->controller->terminate_ike(charon->controller, del, - (controller_cb_t)stroke_log, &info, 0); + status = charon->controller->terminate_ike(charon->controller, del, + (controller_cb_t)stroke_log, &info, this->timeout); + report_terminate_status(this, status, out, del, TRUE); } enumerator->destroy(enumerator); list->destroy(list); @@ -670,8 +733,9 @@ stroke_control_t *stroke_control_create() .unroute = _unroute, .destroy = _destroy, }, + .timeout = lib->settings->get_int(lib->settings, + "%s.plugins.stroke.timeout", 0, charon->name), ); return &this->public; } - diff --git a/src/libcharon/plugins/stroke/stroke_counter.c b/src/libcharon/plugins/stroke/stroke_counter.c index 56eda945a..5fa1fb165 100644 --- a/src/libcharon/plugins/stroke/stroke_counter.c +++ b/src/libcharon/plugins/stroke/stroke_counter.c @@ -16,6 +16,7 @@ #include "stroke_counter.h" #include <threading/spinlock.h> +#include <collections/hashtable.h> ENUM(stroke_counter_type_names, COUNTER_INIT_IKE_SA_REKEY, COUNTER_OUT_INFORMATIONAL_RSP, @@ -55,16 +56,98 @@ struct private_stroke_counter_t { stroke_counter_t public; /** - * Counter values + * Global counter values */ u_int64_t counter[COUNTER_MAX]; /** + * Counters for specific connection names, char* => entry_t + */ + hashtable_t *conns; + + /** * Lock for counter values */ spinlock_t *lock; }; +/** + * Counters for a specific connection name + */ +typedef struct { + /** connection name */ + char *name; + /** counter values for connection */ + u_int64_t counter[COUNTER_MAX]; +} entry_t; + +/** + * Destroy named entry + */ +static void destroy_entry(entry_t *this) +{ + free(this->name); + free(this); +} + +/** + * Hashtable hash function + */ +static u_int hash(char *name) +{ + return chunk_hash(chunk_from_str(name)); +} + +/** + * Hashtable equals function + */ +static bool equals(char *a, char *b) +{ + return streq(a, b); +} + +/** + * Get the name of an IKE_SA, but return NULL if it is not known yet + */ +static char *get_ike_sa_name(ike_sa_t *ike_sa) +{ + peer_cfg_t *peer_cfg; + + if (ike_sa) + { + peer_cfg = ike_sa->get_peer_cfg(ike_sa); + if (peer_cfg) + { + return peer_cfg->get_name(peer_cfg); + } + } + return NULL; +} + +/** + * Increase a counter for a named entry + */ +static void count_named(private_stroke_counter_t *this, + ike_sa_t *ike_sa, stroke_counter_type_t type) +{ + entry_t *entry; + char *name; + + name = get_ike_sa_name(ike_sa); + if (name) + { + entry = this->conns->get(this->conns, name); + if (!entry) + { + INIT(entry, + .name = strdup(name), + ); + this->conns->put(this->conns, entry->name, entry); + } + entry->counter[type]++; + } +} + METHOD(listener_t, alert, bool, private_stroke_counter_t *this, ike_sa_t *ike_sa, alert_t alert, va_list args) @@ -86,6 +169,7 @@ METHOD(listener_t, alert, bool, this->lock->lock(this->lock); this->counter[type]++; + count_named(this, ike_sa, type); this->lock->unlock(this->lock); return TRUE; @@ -109,6 +193,7 @@ METHOD(listener_t, ike_rekey, bool, this->lock->lock(this->lock); this->counter[type]++; + count_named(this, old, type); this->lock->unlock(this->lock); return TRUE; @@ -120,6 +205,7 @@ METHOD(listener_t, child_rekey, bool, { this->lock->lock(this->lock); this->counter[COUNTER_CHILD_SA_REKEY]++; + count_named(this, ike_sa, COUNTER_CHILD_SA_REKEY); this->lock->unlock(this->lock); return TRUE; @@ -194,18 +280,94 @@ METHOD(listener_t, message_hook, bool, this->lock->lock(this->lock); this->counter[type]++; + count_named(this, ike_sa, type); this->lock->unlock(this->lock); return TRUE; } -METHOD(stroke_counter_t, print, void, - private_stroke_counter_t *this, FILE *out) +/** + * Print a single counter value to out + */ +static void print_counter(FILE *out, stroke_counter_type_t type, + u_int64_t counter) +{ + fprintf(out, "%-18N %12llu\n", stroke_counter_type_names, type, counter); +} + +/** + * Print IKE counters for a specific connection + */ +static void print_one(private_stroke_counter_t *this, FILE *out, char *name) +{ + u_int64_t counter[COUNTER_MAX]; + entry_t *entry; + int i; + + this->lock->lock(this->lock); + entry = this->conns->get(this->conns, name); + if (entry) + { + for (i = 0; i < countof(this->counter); i++) + { + counter[i] = entry->counter[i]; + } + } + this->lock->unlock(this->lock); + + if (entry) + { + fprintf(out, "\nList of IKE counters for '%s':\n\n", name); + for (i = 0; i < countof(this->counter); i++) + { + print_counter(out, i, counter[i]); + } + } + else + { + fprintf(out, "No IKE counters found for '%s'\n", name); + } +} + +/** + * Print counters for all connections + */ +static void print_all(private_stroke_counter_t *this, FILE *out) +{ + enumerator_t *enumerator; + entry_t *entry; + linked_list_t *list; + char *name; + + list = linked_list_create(); + + this->lock->lock(this->lock); + enumerator = this->conns->create_enumerator(this->conns); + while (enumerator->enumerate(enumerator, &name, &entry)) + { + list->insert_last(list, strdup(name)); + } + enumerator->destroy(enumerator); + this->lock->unlock(this->lock); + + enumerator = list->create_enumerator(list); + while (enumerator->enumerate(enumerator, &name)) + { + print_one(this, out, name); + } + enumerator->destroy(enumerator); + + list->destroy_function(list, free); +} + +/** + * Print global counters + */ +static void print_global(private_stroke_counter_t *this, FILE *out) { u_int64_t counter[COUNTER_MAX]; int i; - /* Take a snapshot to have congruent results, */ this->lock->lock(this->lock); for (i = 0; i < countof(this->counter); i++) { @@ -215,16 +377,61 @@ METHOD(stroke_counter_t, print, void, fprintf(out, "\nList of IKE counters:\n\n"); - /* but do blocking write without the lock. */ for (i = 0; i < countof(this->counter); i++) { - fprintf(out, "%-18N %12llu\n", stroke_counter_type_names, i, counter[i]); + print_counter(out, i, counter[i]); } } +METHOD(stroke_counter_t, print, void, + private_stroke_counter_t *this, FILE *out, char *name) +{ + if (name) + { + if (streq(name, "all")) + { + return print_all(this, out); + } + return print_one(this, out, name); + } + return print_global(this, out); +} + +METHOD(stroke_counter_t, reset, void, + private_stroke_counter_t *this, char *name) +{ + this->lock->lock(this->lock); + if (name) + { + entry_t *entry; + + entry = this->conns->remove(this->conns, name); + if (entry) + { + destroy_entry(entry); + } + } + else + { + memset(&this->counter, 0, sizeof(this->counter)); + } + this->lock->unlock(this->lock); +} + METHOD(stroke_counter_t, destroy, void, private_stroke_counter_t *this) { + enumerator_t *enumerator; + char *name; + entry_t *entry; + + enumerator = this->conns->create_enumerator(this->conns); + while (enumerator->enumerate(enumerator, &name, &entry)) + { + destroy_entry(entry); + } + enumerator->destroy(enumerator); + this->conns->destroy(this->conns); this->lock->destroy(this->lock); free(this); } @@ -245,8 +452,11 @@ stroke_counter_t *stroke_counter_create() .message = _message_hook, }, .print = _print, + .reset = _reset, .destroy = _destroy, }, + .conns = hashtable_create((hashtable_hash_t)hash, + (hashtable_equals_t)equals, 4), .lock = spinlock_create(), ); diff --git a/src/libcharon/plugins/stroke/stroke_counter.h b/src/libcharon/plugins/stroke/stroke_counter.h index efaae0d6f..fecf39f56 100644 --- a/src/libcharon/plugins/stroke/stroke_counter.h +++ b/src/libcharon/plugins/stroke/stroke_counter.h @@ -87,8 +87,16 @@ struct stroke_counter_t { * Print counter values to an output stream. * * @param out output stream to write to + * @param name connection name to get counters for, NULL for global */ - void (*print)(stroke_counter_t *this, FILE *out); + void (*print)(stroke_counter_t *this, FILE *out, char *name); + + /** + * Reset global or connection specific counters. + * + * @param name name of connection counters to reset, NULL for global + */ + void (*reset)(stroke_counter_t *this, char *name); /** * Destroy a stroke_counter_t. diff --git a/src/libcharon/plugins/stroke/stroke_cred.c b/src/libcharon/plugins/stroke/stroke_cred.c index c401bc6f1..eda746f7e 100644 --- a/src/libcharon/plugins/stroke/stroke_cred.c +++ b/src/libcharon/plugins/stroke/stroke_cred.c @@ -701,7 +701,7 @@ static shared_key_t* pin_cb(pin_cb_data_t *data, shared_key_type_t type, /** * Load a smartcard with a PIN */ -static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr, +static bool load_pin(mem_cred_t *secrets, chunk_t line, int line_nr, FILE *prompt) { chunk_t sc = chunk_empty, secret = chunk_empty; @@ -796,7 +796,7 @@ static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr, if (key) { DBG1(DBG_CFG, " loaded private key from %.*s", (int)sc.len, sc.ptr); - this->creds->add_key(this->creds, key); + secrets->add_key(secrets, key); } return TRUE; } @@ -804,7 +804,7 @@ static bool load_pin(private_stroke_cred_t *this, chunk_t line, int line_nr, /** * Load a private key */ -static bool load_private(private_stroke_cred_t *this, chunk_t line, int line_nr, +static bool load_private(mem_cred_t *secrets, chunk_t line, int line_nr, FILE *prompt, key_type_t key_type) { char path[PATH_MAX]; @@ -894,7 +894,7 @@ static bool load_private(private_stroke_cred_t *this, chunk_t line, int line_nr, { DBG1(DBG_CFG, " loaded %N private key from '%s'", key_type_names, key->get_type(key), path); - this->creds->add_key(this->creds, key); + secrets->add_key(secrets, key); } else { @@ -906,7 +906,7 @@ static bool load_private(private_stroke_cred_t *this, chunk_t line, int line_nr, /** * Load a shared key */ -static bool load_shared(private_stroke_cred_t *this, chunk_t line, int line_nr, +static bool load_shared(mem_cred_t *secrets, chunk_t line, int line_nr, shared_key_type_t type, chunk_t ids) { shared_key_t *shared_key; @@ -961,15 +961,15 @@ static bool load_shared(private_stroke_cred_t *this, chunk_t line, int line_nr, owners->insert_last(owners, identification_create_from_encoding(ID_ANY, chunk_empty)); } - this->creds->add_shared_list(this->creds, shared_key, owners); + secrets->add_shared_list(secrets, shared_key, owners); return TRUE; } /** * reload ipsec.secrets */ -static void load_secrets(private_stroke_cred_t *this, char *file, int level, - FILE *prompt) +static void load_secrets(private_stroke_cred_t *this, mem_cred_t *secrets, + char *file, int level, FILE *prompt) { int line_nr = 0, fd; chunk_t src, line; @@ -991,6 +991,11 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level, close(fd); return; } + if (sb.st_size == 0) + { /* skip empty files, as mmap() complains */ + close(fd); + return; + } addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if (addr == MAP_FAILED) { @@ -1000,9 +1005,9 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level, } src = chunk_create(addr, sb.st_size); - if (level == 0) - { /* flush secrets on non-recursive invocation */ - this->creds->clear_secrets(this->creds); + if (!secrets) + { + secrets = mem_cred_create(); } while (fetchline(&src, &line)) @@ -1072,14 +1077,15 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level, { for (expanded = buf.gl_pathv; *expanded != NULL; expanded++) { - load_secrets(this, *expanded, level + 1, prompt); + load_secrets(this, secrets, *expanded, level + 1, + prompt); } } globfree(&buf); } #else /* HAVE_GLOB_H */ /* if glob(3) is not available, try to load pattern directly */ - load_secrets(this, pattern, level + 1, prompt); + load_secrets(this, secrets, pattern, level + 1, prompt); #endif /* HAVE_GLOB_H */ continue; } @@ -1109,7 +1115,7 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level, } if (match("RSA", &token) || match("ECDSA", &token)) { - if (!load_private(this, line, line_nr, prompt, + if (!load_private(secrets, line, line_nr, prompt, match("RSA", &token) ? KEY_RSA : KEY_ECDSA)) { break; @@ -1117,7 +1123,7 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level, } else if (match("PIN", &token)) { - if (!load_pin(this, line, line_nr, prompt)) + if (!load_pin(secrets, line, line_nr, prompt)) { break; } @@ -1127,7 +1133,7 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level, (match("NTLM", &token) && (type = SHARED_NT_HASH)) || (match("XAUTH", &token) && (type = SHARED_EAP))) { - if (!load_shared(this, line, line_nr, type, ids)) + if (!load_shared(secrets, line, line_nr, type, ids)) { break; } @@ -1141,6 +1147,12 @@ static void load_secrets(private_stroke_cred_t *this, char *file, int level, } munmap(addr, sb.st_size); close(fd); + + if (level == 0) + { /* replace secrets in active credential set */ + this->creds->replace_secrets(this->creds, secrets, FALSE); + secrets->destroy(secrets); + } } /** @@ -1175,7 +1187,7 @@ METHOD(stroke_cred_t, reread, void, if (msg->reread.flags & REREAD_SECRETS) { DBG1(DBG_CFG, "rereading secrets"); - load_secrets(this, SECRETS_FILE, 0, prompt); + load_secrets(this, NULL, SECRETS_FILE, 0, prompt); } if (msg->reread.flags & REREAD_CACERTS) { @@ -1258,8 +1270,7 @@ stroke_cred_t *stroke_cred_create() FALSE, charon->name); load_certs(this); - load_secrets(this, SECRETS_FILE, 0, NULL); + load_secrets(this, NULL, SECRETS_FILE, 0, NULL); return &this->public; } - diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c index b3a20a6c7..a2e1c80a5 100644 --- a/src/libcharon/plugins/stroke/stroke_list.c +++ b/src/libcharon/plugins/stroke/stroke_list.c @@ -205,7 +205,7 @@ static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all) static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) { time_t use_in, use_out, rekey, now; - u_int64_t bytes_in, bytes_out; + u_int64_t bytes_in, bytes_out, packets_in, packets_out; proposal_t *proposal; child_cfg_t *config = child_sa->get_config(child_sa); @@ -273,18 +273,24 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) } } - child_sa->get_usestats(child_sa, TRUE, &use_in, &bytes_in); + child_sa->get_usestats(child_sa, TRUE, + &use_in, &bytes_in, &packets_in); fprintf(out, ", %" PRIu64 " bytes_i", bytes_in); if (use_in) { - fprintf(out, " (%" PRIu64 "s ago)", (u_int64_t)(now - use_in)); + fprintf(out, " (%" PRIu64 " pkt%s, %" PRIu64 "s ago)", + packets_in, (packets_in == 1) ? "": "s", + (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, &packets_out); fprintf(out, ", %" PRIu64 " bytes_o", bytes_out); if (use_out) { - fprintf(out, " (%" PRIu64 "s ago)", (u_int64_t)(now - use_out)); + fprintf(out, " (%" PRIu64 " pkt%s, %" PRIu64 "s ago)", + packets_out, (packets_out == 1) ? "": "s", + (u_int64_t)(now - use_out)); } fprintf(out, ", rekeying "); @@ -1242,7 +1248,7 @@ static void list_algs(FILE *out) int len; fprintf(out, "\n"); - fprintf(out, "List of registered IKEv2 Algorithms:\n"); + fprintf(out, "List of registered IKE algorithms:\n"); fprintf(out, "\n encryption:"); len = 13; enumerator = lib->crypto->create_crypter_enumerator(lib->crypto); @@ -1541,4 +1547,3 @@ stroke_list_t *stroke_list_create(stroke_attribute_t *attribute) return &this->public; } - diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c index 2771f0146..aa5c73b8b 100644 --- a/src/libcharon/plugins/stroke/stroke_socket.c +++ b/src/libcharon/plugins/stroke/stroke_socket.c @@ -388,17 +388,14 @@ static void stroke_status(private_stroke_socket_t *this, /** * list various information */ -static void stroke_list(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out) +static void stroke_list(private_stroke_socket_t *this, stroke_msg_t *msg, + FILE *out) { if (msg->list.flags & LIST_CAINFOS) { this->ca->list(this->ca, msg, out); } this->list->list(this->list, msg, out); - if (msg->list.flags & LIST_COUNTERS) - { - this->counter->print(this->counter, out); - } } /** @@ -505,6 +502,24 @@ static void stroke_user_creds(private_stroke_socket_t *this, } /** + * Print stroke counter values + */ +static void stroke_counters(private_stroke_socket_t *this, + stroke_msg_t *msg, FILE *out) +{ + pop_string(msg, &msg->counters.name); + + if (msg->counters.reset) + { + this->counter->reset(this->counter, msg->counters.name); + } + else + { + this->counter->print(this->counter, out, msg->counters.name); + } +} + +/** * set the verbosity debug output */ static void stroke_loglevel(private_stroke_socket_t *this, @@ -516,11 +531,18 @@ static void stroke_loglevel(private_stroke_socket_t *this, DBG1(DBG_CFG, "received stroke: loglevel %d for %s", msg->loglevel.level, msg->loglevel.type); - group = enum_from_name(debug_names, msg->loglevel.type); - if ((int)group < 0) + if (strcaseeq(msg->loglevel.type, "any")) { - fprintf(out, "invalid type (%s)!\n", msg->loglevel.type); - return; + group = DBG_ANY; + } + else + { + group = enum_from_name(debug_names, msg->loglevel.type); + if ((int)group < 0) + { + fprintf(out, "invalid type (%s)!\n", msg->loglevel.type); + return; + } } charon->set_level(charon, group, msg->loglevel.level); } @@ -665,6 +687,9 @@ static job_requeue_t process(stroke_job_context_t *ctx) case STR_USER_CREDS: stroke_user_creds(this, msg, out); break; + case STR_COUNTERS: + stroke_counters(this, msg, out); + break; default: DBG1(DBG_CFG, "received unknown stroke"); break; @@ -855,4 +880,3 @@ stroke_socket_t *stroke_socket_create() return &this->public; } - |