diff options
Diffstat (limited to 'src')
403 files changed, 6592 insertions, 3089 deletions
diff --git a/src/Makefile.in b/src/Makefile.in index b10237091..17c4a9ad7 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -371,6 +371,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -393,6 +394,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/_copyright/Makefile.in b/src/_copyright/Makefile.in index aa94c55c7..0bea80a10 100644 --- a/src/_copyright/Makefile.in +++ b/src/_copyright/Makefile.in @@ -324,6 +324,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -346,6 +347,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/_updown/Makefile.in b/src/_updown/Makefile.in index 46b81cbc1..ba891c139 100644 --- a/src/_updown/Makefile.in +++ b/src/_updown/Makefile.in @@ -302,6 +302,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -324,6 +325,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/aikgen/Makefile.in b/src/aikgen/Makefile.in index 6b190419f..7096dd6e4 100644 --- a/src/aikgen/Makefile.in +++ b/src/aikgen/Makefile.in @@ -325,6 +325,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -347,6 +348,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/charon-cmd/Makefile.in b/src/charon-cmd/Makefile.in index 3a5f028a8..e4d057fc5 100644 --- a/src/charon-cmd/Makefile.in +++ b/src/charon-cmd/Makefile.in @@ -362,6 +362,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -384,6 +385,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/charon-nm/Makefile.in b/src/charon-nm/Makefile.in index 90cdb8cc3..3efcb8f34 100644 --- a/src/charon-nm/Makefile.in +++ b/src/charon-nm/Makefile.in @@ -361,6 +361,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -383,6 +384,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/charon-nm/charon-nm.c b/src/charon-nm/charon-nm.c index ca12db866..89aa34d98 100644 --- a/src/charon-nm/charon-nm.c +++ b/src/charon-nm/charon-nm.c @@ -196,7 +196,7 @@ int main(int argc, char *argv[]) /* use random ports to avoid conflicts with regular charon */ lib->settings->set_int(lib->settings, "charon-nm.port", 0); - lib->settings->set_int(lib->settings, "charon-nm.port_natt_t", 0); + lib->settings->set_int(lib->settings, "charon-nm.port_nat_t", 0); DBG1(DBG_DMN, "Starting charon NetworkManager backend (strongSwan "VERSION")"); if (lib->integrity) diff --git a/src/charon-nm/nm/nm_creds.c b/src/charon-nm/nm/nm_creds.c index f8fae9504..e70fd9e89 100644 --- a/src/charon-nm/nm/nm_creds.c +++ b/src/charon-nm/nm/nm_creds.c @@ -120,48 +120,49 @@ typedef struct { identification_t *id; } cert_data_t; -/** - * Destroy CA certificate enumerator data - */ -static void cert_data_destroy(cert_data_t *data) +CALLBACK(cert_data_destroy, void, + cert_data_t *data) { data->this->lock->unlock(data->this->lock); free(data); } -/** - * Filter function for certificates enumerator - */ -static bool cert_filter(cert_data_t *data, certificate_t **in, - certificate_t **out) +CALLBACK(cert_filter, bool, + cert_data_t *data, enumerator_t *orig, va_list args) { - certificate_t *cert = *in; + certificate_t *cert, **out; public_key_t *public; - public = cert->get_public_key(cert); - if (!public) - { - return FALSE; - } - if (data->key != KEY_ANY && public->get_type(public) != data->key) - { - public->destroy(public); - return FALSE; - } - if (data->id && data->id->get_type(data->id) == ID_KEY_ID && - public->has_fingerprint(public, data->id->get_encoding(data->id))) + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, &cert)) { + public = cert->get_public_key(cert); + if (!public) + { + continue; + } + if (data->key != KEY_ANY && public->get_type(public) != data->key) + { + public->destroy(public); + continue; + } + if (data->id && data->id->get_type(data->id) == ID_KEY_ID && + public->has_fingerprint(public, data->id->get_encoding(data->id))) + { + public->destroy(public); + *out = cert; + return TRUE; + } public->destroy(public); + if (data->id && !cert->has_subject(cert, data->id)) + { + continue; + } *out = cert; return TRUE; } - public->destroy(public); - if (data->id && !cert->has_subject(cert, data->id)) - { - return FALSE; - } - *out = cert; - return TRUE; + return FALSE; } /** @@ -181,7 +182,7 @@ static enumerator_t *create_trusted_cert_enumerator(private_nm_creds_t *this, this->lock->read_lock(this->lock); return enumerator_create_filter( this->certs->create_enumerator(this->certs), - (void*)cert_filter, data, (void*)cert_data_destroy); + cert_filter, data, cert_data_destroy); } METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, @@ -235,9 +236,13 @@ typedef struct { } shared_enumerator_t; METHOD(enumerator_t, shared_enumerate, bool, - shared_enumerator_t *this, shared_key_t **key, id_match_t *me, - id_match_t *other) + shared_enumerator_t *this, va_list args) { + shared_key_t **key; + id_match_t *me, *other; + + VA_ARGS_VGET(args, key, me, other); + if (this->done) { return FALSE; @@ -307,7 +312,8 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_shared_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _shared_enumerate, .destroy = _shared_destroy, }, .this = this, diff --git a/src/charon-nm/nm/nm_handler.c b/src/charon-nm/nm/nm_handler.c index bdc0667cf..3eb2eb13c 100644 --- a/src/charon-nm/nm/nm_handler.c +++ b/src/charon-nm/nm/nm_handler.c @@ -65,29 +65,33 @@ METHOD(attribute_handler_t, handle, bool, return TRUE; } -/** - * Implementation of create_attribute_enumerator().enumerate() for WINS - */ -static bool enumerate_nbns(enumerator_t *this, - configuration_attribute_type_t *type, chunk_t *data) +METHOD(enumerator_t, enumerate_nbns, bool, + enumerator_t *this, va_list args) { + configuration_attribute_type_t *type; + chunk_t *data; + + VA_ARGS_VGET(args, type, data); *type = INTERNAL_IP4_NBNS; *data = chunk_empty; - /* done */ - this->enumerate = (void*)return_false; + this->venumerate = (void*)return_false; return TRUE; } /** * Implementation of create_attribute_enumerator().enumerate() for DNS */ -static bool enumerate_dns(enumerator_t *this, - configuration_attribute_type_t *type, chunk_t *data) +METHOD(enumerator_t, enumerate_dns, bool, + enumerator_t *this, va_list args) { + configuration_attribute_type_t *type; + chunk_t *data; + + VA_ARGS_VGET(args, type, data); *type = INTERNAL_IP4_DNS; *data = chunk_empty; /* enumerate WINS server as next attribute ... */ - this->enumerate = (void*)enumerate_nbns; + this->venumerate = _enumerate_nbns; return TRUE; } @@ -100,7 +104,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, INIT(enumerator, /* enumerate DNS attribute first ... */ - .enumerate = (void*)enumerate_dns, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_dns, .destroy = (void*)free, ); return enumerator; @@ -108,13 +113,20 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, return enumerator_create_empty(); } -/** - * convert plain byte ptrs to handy chunk during enumeration - */ -static bool filter_chunks(void* null, char **in, chunk_t *out) +CALLBACK(filter_chunks, bool, + void *null, enumerator_t *orig, va_list args) { - *out = chunk_create(*in, 4); - return TRUE; + chunk_t *out; + char *ptr; + + VA_ARGS_VGET(args, out); + + if (orig->enumerate(orig, &ptr)) + { + *out = chunk_create(ptr, 4); + return TRUE; + } + return FALSE; } METHOD(nm_handler_t, create_enumerator, enumerator_t*, @@ -134,7 +146,7 @@ METHOD(nm_handler_t, create_enumerator, enumerator_t*, return enumerator_create_empty(); } return enumerator_create_filter(list->create_enumerator(list), - (void*)filter_chunks, NULL, NULL); + filter_chunks, NULL, NULL); } METHOD(nm_handler_t, reset, void, diff --git a/src/charon-nm/nm/nm_service.c b/src/charon-nm/nm/nm_service.c index 571c0edba..3e8392a57 100644 --- a/src/charon-nm/nm/nm_service.c +++ b/src/charon-nm/nm/nm_service.c @@ -283,9 +283,11 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, NMStrongswanPluginPrivate *priv; NMSettingConnection *conn; NMSettingVPN *vpn; + enumerator_t *enumerator; identification_t *user = NULL, *gateway = NULL; const char *address, *str; - bool virtual, encap; + bool virtual, encap, proposal; + proposal_t *prop; ike_cfg_t *ike_cfg; peer_cfg_t *peer_cfg; child_cfg_t *child_cfg; @@ -344,7 +346,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, str = nm_setting_vpn_get_data_item(vpn, "encap"); encap = streq(str, "yes"); str = nm_setting_vpn_get_data_item(vpn, "ipcomp"); - child.ipcomp = streq(str, "yes"); + child.options |= streq(str, "yes") ? OPT_IPCOMP : 0; str = nm_setting_vpn_get_data_item(vpn, "method"); if (streq(str, "psk")) { @@ -540,8 +542,36 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, charon->socket->get_port(charon->socket, FALSE), (char*)address, IKEV2_UDP_PORT, FRAGMENTATION_YES, 0); - ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE)); - ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE)); + + str = nm_setting_vpn_get_data_item(vpn, "proposal"); + proposal = streq(str, "yes"); + str = nm_setting_vpn_get_data_item(vpn, "ike"); + if (proposal && str && strlen(str)) + { + enumerator = enumerator_create_token(str, ";", ""); + while (enumerator->enumerate(enumerator, &str)) + { + prop = proposal_create_from_string(PROTO_IKE, str); + if (!prop) + { + g_set_error(err, NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED, + "Invalid IKE proposal."); + enumerator->destroy(enumerator); + ike_cfg->destroy(ike_cfg); + gateway->destroy(gateway); + user->destroy(user); + return FALSE; + } + ike_cfg->add_proposal(ike_cfg, prop); + } + enumerator->destroy(enumerator); + } + else + { + ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE)); + ike_cfg->add_proposal(ike_cfg, proposal_create_default_aead(PROTO_IKE)); + } peer_cfg = peer_cfg_create(priv->name, ike_cfg, &peer); if (virtual) @@ -566,8 +596,32 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE); child_cfg = child_cfg_create(priv->name, &child); - child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP)); - child_cfg->add_proposal(child_cfg, proposal_create_default_aead(PROTO_ESP)); + str = nm_setting_vpn_get_data_item(vpn, "esp"); + if (proposal && str && strlen(str)) + { + enumerator = enumerator_create_token(str, ";", ""); + while (enumerator->enumerate(enumerator, &str)) + { + prop = proposal_create_from_string(PROTO_ESP, str); + if (!prop) + { + g_set_error(err, NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED, + "Invalid ESP proposal."); + enumerator->destroy(enumerator); + child_cfg->destroy(child_cfg); + peer_cfg->destroy(peer_cfg); + return FALSE; + } + child_cfg->add_proposal(child_cfg, prop); + } + enumerator->destroy(enumerator); + } + else + { + child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP)); + child_cfg->add_proposal(child_cfg, proposal_create_default_aead(PROTO_ESP)); + } ts = traffic_selector_create_dynamic(0, 0, 65535); child_cfg->add_traffic_selector(child_cfg, TRUE, ts); ts = traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE, diff --git a/src/charon-svc/Makefile.in b/src/charon-svc/Makefile.in index 7dd0fb6fe..9c08e8a01 100644 --- a/src/charon-svc/Makefile.in +++ b/src/charon-svc/Makefile.in @@ -325,6 +325,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -347,6 +348,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/charon-systemd/Makefile.in b/src/charon-systemd/Makefile.in index 1959818c4..937753927 100644 --- a/src/charon-systemd/Makefile.in +++ b/src/charon-systemd/Makefile.in @@ -329,6 +329,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -351,6 +352,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/charon-tkm/Makefile.in b/src/charon-tkm/Makefile.in index 538335b9f..9987b44b6 100644 --- a/src/charon-tkm/Makefile.in +++ b/src/charon-tkm/Makefile.in @@ -272,6 +272,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -294,6 +295,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/charon-tkm/src/tkm/tkm_kernel_sad.c b/src/charon-tkm/src/tkm/tkm_kernel_sad.c index 22d2aac13..97226f1ac 100644 --- a/src/charon-tkm/src/tkm/tkm_kernel_sad.c +++ b/src/charon-tkm/src/tkm/tkm_kernel_sad.c @@ -101,61 +101,63 @@ static void sad_entry_destroy(sad_entry_t *entry) } } -/** - * Find a list entry with given src, dst, (remote) spi and proto values. - */ -static bool sad_entry_match(sad_entry_t * const entry, const host_t * const src, - const host_t * const dst, const uint32_t * const spi, - const uint8_t * const proto) +CALLBACK(sad_entry_match, bool, + sad_entry_t * const entry, va_list args) { + const host_t *src, *dst; + const uint32_t *spi; + const uint8_t *proto; + + VA_ARGS_VGET(args, src, dst, spi, proto); + if (entry->src == NULL || entry->dst == NULL) { return FALSE; } - return src->ip_equals(entry->src, (host_t *)src) && dst->ip_equals(entry->dst, (host_t *)dst) && entry->spi_rem == *spi && entry->proto == *proto; } -/** - * Find a list entry with given reqid, spi and proto values. - */ -static bool sad_entry_match_dst(sad_entry_t * const entry, - const uint32_t * const reqid, - const uint32_t * const spi, - const uint8_t * const proto) +CALLBACK(sad_entry_match_dst, bool, + sad_entry_t * const entry, va_list args) { + const uint32_t *reqid, *spi; + const uint8_t *proto; + + VA_ARGS_VGET(args, reqid, spi, proto); return entry->reqid == *reqid && entry->spi_rem == *spi && entry->proto == *proto; } -/** - * Find a list entry with given esa id. - */ -static bool sad_entry_match_esa_id(sad_entry_t * const entry, - const esa_id_type * const esa_id) +CALLBACK(sad_entry_match_esa_id, bool, + sad_entry_t * const entry, va_list args) { + const esa_id_type *esa_id; + + VA_ARGS_VGET(args, esa_id); return entry->esa_id == *esa_id; } -/** - * Find a list entry with given reqid and different esa id. - */ -static bool sad_entry_match_other_esa(sad_entry_t * const entry, - const esa_id_type * const esa_id, - const uint32_t * const reqid) +CALLBACK(sad_entry_match_other_esa, bool, + sad_entry_t * const entry, va_list args) { + const esa_id_type *esa_id; + const uint32_t *reqid; + + VA_ARGS_VGET(args, esa_id, reqid); return entry->reqid == *reqid && entry->esa_id != *esa_id; } -/** - * Compare two SAD entries for equality. - */ -static bool sad_entry_equal(sad_entry_t * const left, sad_entry_t * const right) +CALLBACK(sad_entry_equal, bool, + sad_entry_t * const left, va_list args) { + sad_entry_t *right; + + VA_ARGS_VGET(args, right); + if (left->src == NULL || left->dst == NULL || right->src == NULL || right->dst == NULL) { @@ -175,8 +177,8 @@ METHOD(tkm_kernel_sad_t, insert, bool, const uint32_t reqid, const host_t * const src, const host_t * const dst, const uint32_t spi_loc, const uint32_t spi_rem, const uint8_t proto) { - status_t result; sad_entry_t *new_entry; + bool found; INIT(new_entry, .esa_id = esa_id, @@ -189,10 +191,9 @@ METHOD(tkm_kernel_sad_t, insert, bool, ); this->mutex->lock(this->mutex); - result = this->data->find_first(this->data, - (linked_list_match_t)sad_entry_equal, NULL, + found = this->data->find_first(this->data, sad_entry_equal, NULL, new_entry); - if (result == NOT_FOUND) + if (!found) { DBG3(DBG_KNL, "inserting SAD entry (esa: %llu, reqid: %u, src: %H, " "dst: %H, spi_loc: %x, spi_rem: %x,proto: %u)", esa_id, reqid, src, @@ -207,7 +208,7 @@ METHOD(tkm_kernel_sad_t, insert, bool, free(new_entry); } this->mutex->unlock(this->mutex); - return result == NOT_FOUND; + return !found; } METHOD(tkm_kernel_sad_t, get_esa_id, esa_id_type, @@ -218,11 +219,10 @@ METHOD(tkm_kernel_sad_t, get_esa_id, esa_id_type, sad_entry_t *entry = NULL; this->mutex->lock(this->mutex); - const status_t res = this->data->find_first(this->data, - (linked_list_match_t)sad_entry_match, - (void**)&entry, src, dst, &spi, - &proto); - if (res == SUCCESS && entry) + const bool res = this->data->find_first(this->data, sad_entry_match, + (void**)&entry, src, dst, &spi, + &proto); + if (res && entry) { id = entry->esa_id; DBG3(DBG_KNL, "returning ESA id %llu of SAD entry (src: %H, dst: %H, " @@ -243,13 +243,12 @@ METHOD(tkm_kernel_sad_t, get_other_esa_id, esa_id_type, esa_id_type id = 0; sad_entry_t *entry = NULL; uint32_t reqid; - status_t res; + bool res; this->mutex->lock(this->mutex); - res = this->data->find_first(this->data, - (linked_list_match_t)sad_entry_match_esa_id, + res = this->data->find_first(this->data, sad_entry_match_esa_id, (void**)&entry, &esa_id); - if (res == SUCCESS && entry) + if (res && entry) { reqid = entry->reqid; } @@ -260,10 +259,9 @@ METHOD(tkm_kernel_sad_t, get_other_esa_id, esa_id_type, return id; } - res = this->data->find_first(this->data, - (linked_list_match_t)sad_entry_match_other_esa, + res = this->data->find_first(this->data, sad_entry_match_other_esa, (void**)&entry, &esa_id, &reqid); - if (res == SUCCESS && entry) + if (res && entry) { id = entry->esa_id; DBG3(DBG_KNL, "returning ESA id %llu of other SAD entry with reqid %u", @@ -281,10 +279,9 @@ METHOD(tkm_kernel_sad_t, get_dst_host, host_t *, sad_entry_t *entry = NULL; this->mutex->lock(this->mutex); - const status_t res = this->data->find_first(this->data, - (linked_list_match_t)sad_entry_match_dst, - (void**)&entry, &reqid, &spi, &proto); - if (res == SUCCESS && entry) + const bool res = this->data->find_first(this->data, sad_entry_match_dst, + (void**)&entry, &reqid, &spi, &proto); + if (res && entry) { dst = entry->dst; DBG3(DBG_KNL, "returning destination host %H of SAD entry (reqid: %u," diff --git a/src/charon/Makefile.in b/src/charon/Makefile.in index 8cf782fa2..d4cec547e 100644 --- a/src/charon/Makefile.in +++ b/src/charon/Makefile.in @@ -328,6 +328,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -350,6 +351,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/checksum/Makefile.in b/src/checksum/Makefile.in index 5e7a4ca7f..e4e3a16e6 100644 --- a/src/checksum/Makefile.in +++ b/src/checksum/Makefile.in @@ -397,6 +397,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -419,6 +420,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/conftest/Makefile.in b/src/conftest/Makefile.in index 14b8351cd..c7d4c6bbe 100644 --- a/src/conftest/Makefile.in +++ b/src/conftest/Makefile.in @@ -342,6 +342,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -364,6 +365,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/conftest/config.c b/src/conftest/config.c index 06a685047..d926dfca2 100644 --- a/src/conftest/config.c +++ b/src/conftest/config.c @@ -36,13 +36,20 @@ struct private_config_t { linked_list_t *configs; }; -/** - * filter function for ike configs - */ -static bool ike_filter(void *data, peer_cfg_t **in, ike_cfg_t **out) +CALLBACK(ike_filter, bool, + void *data, enumerator_t *orig, va_list args) { - *out = (*in)->get_ike_cfg(*in); - return TRUE; + peer_cfg_t *cfg; + ike_cfg_t **out; + + VA_ARGS_VGET(args, out); + + if (orig->enumerate(orig, &cfg)) + { + *out = cfg->get_ike_cfg(cfg); + return TRUE; + } + return FALSE; } METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, @@ -51,7 +58,7 @@ METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, return enumerator_create_filter( this->configs->create_enumerator(this->configs), - (void*)ike_filter, NULL, NULL); + ike_filter, NULL, NULL); } METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*, diff --git a/src/dumm/Makefile.in b/src/dumm/Makefile.in index dc1e3dc8f..276ca2ef2 100644 --- a/src/dumm/Makefile.in +++ b/src/dumm/Makefile.in @@ -363,6 +363,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -385,6 +386,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/dumm/cowfs.c b/src/dumm/cowfs.c index 28c62c217..5332ba551 100644 --- a/src/dumm/cowfs.c +++ b/src/dumm/cowfs.c @@ -92,11 +92,12 @@ static void overlay_destroy(overlay_t *this) free(this); } -/** - * compare two overlays by path - */ -static bool overlay_equals(overlay_t *this, overlay_t *other) +CALLBACK(overlay_equals, bool, + overlay_t *this, va_list args) { + overlay_t *other; + + VA_ARGS_VGET(args, other); return streq(this->path, other->path); } @@ -108,8 +109,8 @@ static bool overlay_remove(private_cowfs_t *this, char *path) { overlay_t over, *current; over.path = path; - if (this->overlays->find_first(this->overlays, - (linked_list_match_t)overlay_equals, (void**)¤t, &over) != SUCCESS) + if (!this->overlays->find_first(this->overlays, overlay_equals, + (void**)¤t, &over)) { return FALSE; } diff --git a/src/dumm/dumm.c b/src/dumm/dumm.c index cc4f5a16b..d147b2df0 100644 --- a/src/dumm/dumm.c +++ b/src/dumm/dumm.c @@ -267,10 +267,12 @@ typedef struct { } template_enumerator_t; METHOD(enumerator_t, template_enumerate, bool, - template_enumerator_t *this, char **template) + template_enumerator_t *this, va_list args) { struct stat st; - char *rel; + char *rel, **template; + + VA_ARGS_VGET(args, template); while (this->inner->enumerate(this->inner, &rel, NULL, &st)) { @@ -296,7 +298,8 @@ METHOD(dumm_t, create_template_enumerator, enumerator_t*, template_enumerator_t *enumerator; INIT(enumerator, .public = { - .enumerate = (void*)_template_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _template_enumerate, .destroy = (void*)_template_enumerator_destroy, }, .inner = enumerator_create_directory(TEMPLATE_DIR), diff --git a/src/include/Makefile.in b/src/include/Makefile.in index 068cae15d..569574fc9 100644 --- a/src/include/Makefile.in +++ b/src/include/Makefile.in @@ -272,6 +272,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -294,6 +295,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/include/linux/xfrm.h b/src/include/linux/xfrm.h index 02d5125a5..dbaa4f128 100644 --- a/src/include/linux/xfrm.h +++ b/src/include/linux/xfrm.h @@ -296,10 +296,12 @@ enum xfrm_attr_type_t { XFRMA_ALG_AUTH_TRUNC, /* struct xfrm_algo_auth */ XFRMA_MARK, /* struct xfrm_mark */ XFRMA_TFCPAD, /* __u32 */ - XFRMA_REPLAY_ESN_VAL, /* struct xfrm_replay_esn */ + XFRMA_REPLAY_ESN_VAL, /* struct xfrm_replay_state_esn */ XFRMA_SA_EXTRA_FLAGS, /* __u32 */ XFRMA_PROTO, /* __u8 */ XFRMA_ADDRESS_FILTER, /* struct xfrm_address_filter */ + XFRMA_PAD, + XFRMA_OFFLOAD_DEV, /* struct xfrm_state_offload */ __XFRMA_MAX #define XFRMA_MAX (__XFRMA_MAX - 1) @@ -491,6 +493,13 @@ struct xfrm_address_filter { __u8 dplen; }; +struct xfrm_user_offload { + int ifindex; + __u8 flags; +}; +#define XFRM_OFFLOAD_IPV6 1 +#define XFRM_OFFLOAD_INBOUND 2 + #ifndef __KERNEL__ /* backwards compatibility for userspace */ #define XFRMGRP_ACQUIRE 1 diff --git a/src/ipsec/Makefile.in b/src/ipsec/Makefile.in index faf7c76fc..1a922427b 100644 --- a/src/ipsec/Makefile.in +++ b/src/ipsec/Makefile.in @@ -305,6 +305,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -327,6 +328,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/ipsec/_ipsec.8 b/src/ipsec/_ipsec.8 index 1ae6375c8..3f4316dd6 100644 --- a/src/ipsec/_ipsec.8 +++ b/src/ipsec/_ipsec.8 @@ -1,4 +1,4 @@ -.TH IPSEC 8 "2013-10-29" "5.5.2dr4" "strongSwan" +.TH IPSEC 8 "2013-10-29" "5.5.3dr2" "strongSwan" . .SH NAME . diff --git a/src/libcharon/Makefile.am b/src/libcharon/Makefile.am index 8461d6230..3fcaedc3b 100644 --- a/src/libcharon/Makefile.am +++ b/src/libcharon/Makefile.am @@ -184,6 +184,15 @@ if USE_ME sa/ikev2/tasks/ike_me.c sa/ikev2/tasks/ike_me.h endif +if STATIC_PLUGIN_CONSTRUCTORS +BUILT_SOURCES = $(srcdir)/plugin_constructors.c +CLEANFILES = $(srcdir)/plugin_constructors.c + +$(srcdir)/plugin_constructors.c: $(top_srcdir)/src/libstrongswan/plugins/plugin_constructors.py + $(AM_V_GEN) \ + $(PYTHON) $(top_srcdir)/src/libstrongswan/plugins/plugin_constructors.py ${c_plugins} > $@ +endif + # build optional plugins ######################## diff --git a/src/libcharon/Makefile.in b/src/libcharon/Makefile.in index 8f6dc89a3..ef9ffd39b 100644 --- a/src/libcharon/Makefile.in +++ b/src/libcharon/Makefile.in @@ -934,6 +934,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -956,6 +957,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ @@ -1167,6 +1169,8 @@ libcharon_la_LIBADD = \ $(am__append_141) $(am__append_143) $(am__append_145) \ $(am__append_147) EXTRA_DIST = Android.mk +@STATIC_PLUGIN_CONSTRUCTORS_TRUE@BUILT_SOURCES = $(srcdir)/plugin_constructors.c +@STATIC_PLUGIN_CONSTRUCTORS_TRUE@CLEANFILES = $(srcdir)/plugin_constructors.c @MONOLITHIC_FALSE@SUBDIRS = . $(am__append_6) $(am__append_8) \ @MONOLITHIC_FALSE@ $(am__append_10) $(am__append_12) \ @MONOLITHIC_FALSE@ $(am__append_14) $(am__append_16) \ @@ -1240,7 +1244,8 @@ EXTRA_DIST = Android.mk @MONOLITHIC_TRUE@ $(am__append_138) $(am__append_140) \ @MONOLITHIC_TRUE@ $(am__append_142) $(am__append_144) \ @MONOLITHIC_TRUE@ $(am__append_146) . tests -all: all-recursive +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .c .lo .o .obj @@ -2095,14 +2100,16 @@ distdir: $(DISTFILES) fi; \ done check-am: all-am -check: check-recursive +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive all-am: Makefile $(LTLIBRARIES) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(ipseclibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done -install: install-recursive +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive @@ -2124,6 +2131,7 @@ install-strip: mostlyclean-generic: clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) @@ -2170,6 +2178,7 @@ distclean-generic: maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-recursive clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \ @@ -2241,7 +2250,8 @@ ps-am: uninstall-am: uninstall-ipseclibLTLIBRARIES -.MAKE: $(am__recursive_targets) install-am install-strip +.MAKE: $(am__recursive_targets) all check install install-am \ + install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-ipseclibLTLIBRARIES \ @@ -2264,6 +2274,10 @@ uninstall-am: uninstall-ipseclibLTLIBRARIES daemon.lo : $(top_builddir)/config.status +@STATIC_PLUGIN_CONSTRUCTORS_TRUE@$(srcdir)/plugin_constructors.c: $(top_srcdir)/src/libstrongswan/plugins/plugin_constructors.py +@STATIC_PLUGIN_CONSTRUCTORS_TRUE@ $(AM_V_GEN) \ +@STATIC_PLUGIN_CONSTRUCTORS_TRUE@ $(PYTHON) $(top_srcdir)/src/libstrongswan/plugins/plugin_constructors.py ${c_plugins} > $@ + @MONOLITHIC_TRUE@@USE_SIMAKA_TRUE@ # otherwise this library is linked to both the eap_aka and the eap_sim plugin @MONOLITHIC_TRUE@@USE_TLS_TRUE@ # otherwise this library is linked to eap_tls diff --git a/src/libcharon/attributes/attribute_manager.c b/src/libcharon/attributes/attribute_manager.c index 2ab7ed118..3a4a21a02 100644 --- a/src/libcharon/attributes/attribute_manager.c +++ b/src/libcharon/attributes/attribute_manager.c @@ -237,14 +237,14 @@ typedef struct { linked_list_t *vips; } initiator_enumerator_t; -/** - * Enumerator implementation for initiator attributes - */ -static bool initiator_enumerate(initiator_enumerator_t *this, - attribute_handler_t **handler, - configuration_attribute_type_t *type, - chunk_t *value) +METHOD(enumerator_t, initiator_enumerate, bool, + initiator_enumerator_t *this, va_list args) { + configuration_attribute_type_t *type; + attribute_handler_t **handler; + chunk_t *value; + + VA_ARGS_VGET(args, handler, type, value); /* enumerate inner attributes using outer handler enumerator */ while (!this->inner || !this->inner->enumerate(this->inner, type, value)) { @@ -261,10 +261,8 @@ static bool initiator_enumerate(initiator_enumerator_t *this, return TRUE; } -/** - * Cleanup function of initiator attribute enumerator - */ -static void initiator_destroy(initiator_enumerator_t *this) +METHOD(enumerator_t, initiator_destroy, void, + initiator_enumerator_t *this) { this->this->lock->unlock(this->this->lock); this->outer->destroy(this->outer); @@ -281,8 +279,9 @@ METHOD(attribute_manager_t, create_initiator_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)initiator_enumerate, - .destroy = (void*)initiator_destroy, + .enumerate = enumerator_enumerate_default, + .venumerate = _initiator_enumerate, + .destroy = _initiator_destroy, }, .this = this, .ike_sa = ike_sa, diff --git a/src/libcharon/attributes/mem_pool.c b/src/libcharon/attributes/mem_pool.c index a2b7c2803..e1a9a6dce 100644 --- a/src/libcharon/attributes/mem_pool.c +++ b/src/libcharon/attributes/mem_pool.c @@ -512,10 +512,15 @@ typedef struct { } lease_enumerator_t; METHOD(enumerator_t, lease_enumerate, bool, - lease_enumerator_t *this, identification_t **id, host_t **addr, bool *online) + lease_enumerator_t *this, va_list args) { - u_int *offset; + identification_t **id; unique_lease_t *lease; + host_t **addr; + u_int *offset; + bool *online; + + VA_ARGS_VGET(args, id, addr, online); DESTROY_IF(this->addr); this->addr = NULL; @@ -570,7 +575,8 @@ METHOD(mem_pool_t, create_lease_enumerator, enumerator_t*, this->mutex->lock(this->mutex); INIT(enumerator, .public = { - .enumerate = (void*)_lease_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _lease_enumerate, .destroy = _lease_enumerator_destroy, }, .pool = this, diff --git a/src/libcharon/bus/bus.c b/src/libcharon/bus/bus.c index f4bba872f..77a910197 100644 --- a/src/libcharon/bus/bus.c +++ b/src/libcharon/bus/bus.c @@ -207,20 +207,20 @@ static inline void register_logger(private_bus_t *this, debug_t group, } } -/** - * Find the log level of the first registered logger that implements log or - * vlog (or both). - */ -static bool find_max_levels(log_entry_t *entry, debug_t *group, level_t *level, - level_t *vlevel) +CALLBACK(find_max_levels, bool, + log_entry_t *entry, va_list args) { + level_t *level, *vlevel; + debug_t group; + + VA_ARGS_VGET(args, group, level, vlevel); if (entry->logger->log && *level == LEVEL_SILENT) { - *level = entry->levels[*group]; + *level = entry->levels[group]; } if (entry->logger->vlog && *vlevel == LEVEL_SILENT) { - *vlevel = entry->levels[*group]; + *vlevel = entry->levels[group]; } return *level > LEVEL_SILENT && *vlevel > LEVEL_SILENT; } @@ -258,8 +258,8 @@ static inline void unregister_logger(private_bus_t *this, logger_t *logger) loggers = this->loggers[group]; loggers->remove(loggers, found, NULL); - loggers->find_first(loggers, (linked_list_match_t)find_max_levels, - NULL, &group, &level, &vlevel); + loggers->find_first(loggers, find_max_levels, NULL, group, + &level, &vlevel); set_level(&this->max_level[group], level); set_level(&this->max_vlevel[group], vlevel); } @@ -330,11 +330,12 @@ typedef struct { va_list args; } log_data_t; -/** - * logger->log() invocation as a invoke_function callback - */ -static void log_cb(log_entry_t *entry, log_data_t *data) +CALLBACK(log_cb, void, + log_entry_t *entry, va_list args) { + log_data_t *data; + + VA_ARGS_VGET(args, data); if (entry->logger->log && entry->levels[data->group] >= data->level) { entry->logger->log(entry->logger, data->group, data->level, @@ -342,11 +343,12 @@ static void log_cb(log_entry_t *entry, log_data_t *data) } } -/** - * logger->vlog() invocation as a invoke_function callback - */ -static void vlog_cb(log_entry_t *entry, log_data_t *data) +CALLBACK(vlog_cb, void, + log_entry_t *entry, va_list args) { + log_data_t *data; + + VA_ARGS_VGET(args, data); if (entry->logger->vlog && entry->levels[data->group] >= data->level) { va_list copy; @@ -405,8 +407,7 @@ METHOD(bus_t, vlog, void, } if (len > 0) { - loggers->invoke_function(loggers, (linked_list_invoke_t)log_cb, - &data); + loggers->invoke_function(loggers, log_cb, &data); } if (data.message != buf) { @@ -422,7 +423,7 @@ METHOD(bus_t, vlog, void, data.message = format; va_copy(data.args, args); - loggers->invoke_function(loggers, (linked_list_invoke_t)vlog_cb, &data); + loggers->invoke_function(loggers, vlog_cb, &data); va_end(data.args); } diff --git a/src/libcharon/config/backend_manager.c b/src/libcharon/config/backend_manager.c index 79f1d9fee..4f154df9b 100644 --- a/src/libcharon/config/backend_manager.c +++ b/src/libcharon/config/backend_manager.c @@ -265,20 +265,24 @@ static void peer_enum_destroy(peer_data_t *data) free(data); } -/** - * convert enumerator value from match_entry to config - */ -static bool peer_enum_filter(linked_list_t *configs, - match_entry_t **in, peer_cfg_t **out) +CALLBACK(peer_enum_filter, bool, + linked_list_t *configs, enumerator_t *orig, va_list args) { - *out = (*in)->cfg; - return TRUE; + match_entry_t *entry; + peer_cfg_t **out; + + VA_ARGS_VGET(args, out); + + if (orig->enumerate(orig, &entry)) + { + *out = entry->cfg; + return TRUE; + } + return FALSE; } -/** - * Clean up temporary config list - */ -static void peer_enum_filter_destroy(linked_list_t *configs) +CALLBACK(peer_enum_filter_destroy, void, + linked_list_t *configs) { match_entry_t *entry; @@ -379,8 +383,8 @@ METHOD(backend_manager_t, create_peer_cfg_enumerator, enumerator_t*, helper->destroy(helper); return enumerator_create_filter(configs->create_enumerator(configs), - (void*)peer_enum_filter, configs, - (void*)peer_enum_filter_destroy); + peer_enum_filter, configs, + peer_enum_filter_destroy); } METHOD(backend_manager_t, get_peer_cfg_by_name, peer_cfg_t*, diff --git a/src/libcharon/config/child_cfg.c b/src/libcharon/config/child_cfg.c index 3c6dd5198..ec2a12431 100644 --- a/src/libcharon/config/child_cfg.c +++ b/src/libcharon/config/child_cfg.c @@ -1,6 +1,6 @@ /* + * Copyright (C) 2008-2017 Tobias Brunner * Copyright (C) 2016 Andreas Steffen - * Copyright (C) 2008-2016 Tobias Brunner * Copyright (C) 2005-2007 Martin Willi * Copyright (C) 2005 Jan Hutter * HSR Hochschule fuer Technik Rapperswil @@ -54,6 +54,11 @@ struct private_child_cfg_t { char *name; /** + * Options + */ + child_cfg_option_t options; + + /** * list for all proposals */ linked_list_t *proposals; @@ -74,11 +79,6 @@ struct private_child_cfg_t { char *updown; /** - * allow host access - */ - bool hostaccess; - - /** * Mode to propose for a initiated CHILD: tunnel/transport */ ipsec_mode_t mode; @@ -104,11 +104,6 @@ struct private_child_cfg_t { lifetime_cfg_t lifetime; /** - * enable IPComp - */ - bool use_ipcomp; - - /** * Inactivity timeout */ uint32_t inactivity; @@ -144,21 +139,6 @@ struct private_child_cfg_t { char *interface; /** - * set up IPsec transport SA in MIPv6 proxy mode - */ - bool proxy_mode; - - /** - * enable installation and removal of kernel IPsec policies - */ - bool install_policy; - - /** - * Install outbound FWD policies - */ - bool fwd_out_policy; - - /** * anti-replay window size */ uint32_t replay_window; @@ -170,6 +150,12 @@ METHOD(child_cfg_t, get_name, char*, return this->name; } +METHOD(child_cfg_t, has_option, bool, + private_child_cfg_t *this, child_cfg_option_t option) +{ + return this->options & option; +} + METHOD(child_cfg_t, add_proposal, void, private_child_cfg_t *this, proposal_t *proposal) { @@ -179,8 +165,12 @@ METHOD(child_cfg_t, add_proposal, void, } } -static bool match_proposal(proposal_t *item, proposal_t *proposal) +CALLBACK(match_proposal, bool, + proposal_t *item, va_list args) { + proposal_t *proposal; + + VA_ARGS_VGET(args, proposal); return item->equals(item, proposal); } @@ -199,8 +189,7 @@ METHOD(child_cfg_t, get_proposals, linked_list_t*, { current->strip_dh(current, MODP_NONE); } - if (proposals->find_first(proposals, (linked_list_match_t)match_proposal, - NULL, current) == SUCCESS) + if (proposals->find_first(proposals, match_proposal, NULL, current)) { current->destroy(current); continue; @@ -311,8 +300,9 @@ METHOD(child_cfg_t, get_traffic_selectors, linked_list_t*, { if (hosts && hosts->get_count(hosts)) { /* set hosts if TS is dynamic or as initiator in transport mode */ - bool dynamic = ts1->is_dynamic(ts1); - if (dynamic || (this->mode == MODE_TRANSPORT && !this->proxy_mode && + bool dynamic = ts1->is_dynamic(ts1), + proxy_mode = has_option(this, OPT_PROXY_MODE); + if (dynamic || (this->mode == MODE_TRANSPORT && !proxy_mode && !supplied)) { e2 = hosts->create_enumerator(hosts); @@ -428,12 +418,6 @@ METHOD(child_cfg_t, get_updown, char*, return this->updown; } -METHOD(child_cfg_t, get_hostaccess, bool, - private_child_cfg_t *this) -{ - return this->hostaccess; -} - /** * Applies jitter to the rekey value. Returns the new rekey value. * Note: The distribution of random values is not perfect, but it @@ -508,12 +492,6 @@ METHOD(child_cfg_t, get_dh_group, diffie_hellman_group_t, return dh_group; } -METHOD(child_cfg_t, use_ipcomp, bool, - private_child_cfg_t *this) -{ - return this->use_ipcomp; -} - METHOD(child_cfg_t, get_inactivity, uint32_t, private_child_cfg_t *this) { @@ -562,24 +540,6 @@ METHOD(child_cfg_t, set_replay_window, void, this->replay_window = replay_window; } -METHOD(child_cfg_t, use_proxy_mode, bool, - private_child_cfg_t *this) -{ - return this->proxy_mode; -} - -METHOD(child_cfg_t, install_policy, bool, - private_child_cfg_t *this) -{ - return this->install_policy; -} - -METHOD(child_cfg_t, install_fwd_out_policy, bool, - private_child_cfg_t *this) -{ - return this->fwd_out_policy; -} - #define LT_PART_EQUALS(a, b) ({ a.life == b.life && a.rekey == b.rekey && a.jitter == b.jitter; }) #define LIFETIME_EQUALS(a, b) ({ LT_PART_EQUALS(a.time, b.time) && LT_PART_EQUALS(a.bytes, b.bytes) && LT_PART_EQUALS(a.packets, b.packets); }) @@ -611,13 +571,12 @@ METHOD(child_cfg_t, equals, bool, { return FALSE; } - return this->hostaccess == other->hostaccess && + return this->options == other->options && this->mode == other->mode && this->start_action == other->start_action && this->dpd_action == other->dpd_action && this->close_action == other->close_action && LIFETIME_EQUALS(this->lifetime, other->lifetime) && - this->use_ipcomp == other->use_ipcomp && this->inactivity == other->inactivity && this->reqid == other->reqid && this->mark_in.value == other->mark_in.value && @@ -627,9 +586,6 @@ METHOD(child_cfg_t, equals, bool, this->tfc == other->tfc && this->manual_prio == other->manual_prio && this->replay_window == other->replay_window && - this->proxy_mode == other->proxy_mode && - this->install_policy == other->install_policy && - this->fwd_out_policy == other->fwd_out_policy && streq(this->updown, other->updown) && streq(this->interface, other->interface); } @@ -672,14 +628,12 @@ child_cfg_t *child_cfg_create(char *name, child_cfg_create_t *data) .get_proposals = _get_proposals, .select_proposal = _select_proposal, .get_updown = _get_updown, - .get_hostaccess = _get_hostaccess, .get_mode = _get_mode, .get_start_action = _get_start_action, .get_dpd_action = _get_dpd_action, .get_close_action = _get_close_action, .get_lifetime = _get_lifetime, .get_dh_group = _get_dh_group, - .use_ipcomp = _use_ipcomp, .get_inactivity = _get_inactivity, .get_reqid = _get_reqid, .get_mark = _get_mark, @@ -688,19 +642,16 @@ child_cfg_t *child_cfg_create(char *name, child_cfg_create_t *data) .get_interface = _get_interface, .get_replay_window = _get_replay_window, .set_replay_window = _set_replay_window, - .use_proxy_mode = _use_proxy_mode, - .install_policy = _install_policy, - .install_fwd_out_policy = _install_fwd_out_policy, + .has_option = _has_option, .equals = _equals, .get_ref = _get_ref, .destroy = _destroy, }, .name = strdup(name), + .options = data->options, .updown = strdupnull(data->updown), - .hostaccess = data->hostaccess, .reqid = data->reqid, .mode = data->mode, - .proxy_mode = data->proxy_mode, .start_action = data->start_action, .dpd_action = data->dpd_action, .close_action = data->close_action, @@ -708,12 +659,9 @@ child_cfg_t *child_cfg_create(char *name, child_cfg_create_t *data) .mark_out = data->mark_out, .lifetime = data->lifetime, .inactivity = data->inactivity, - .use_ipcomp = data->ipcomp, .tfc = data->tfc, .manual_prio = data->priority, .interface = strdupnull(data->interface), - .install_policy = !data->suppress_policies, - .fwd_out_policy = data->fwd_out_policies, .refcount = 1, .proposals = linked_list_create(), .my_ts = linked_list_create(), diff --git a/src/libcharon/config/child_cfg.h b/src/libcharon/config/child_cfg.h index b85bfd9bc..a102c459c 100644 --- a/src/libcharon/config/child_cfg.h +++ b/src/libcharon/config/child_cfg.h @@ -1,6 +1,6 @@ /* + * Copyright (C) 2008-2017 Tobias Brunner * Copyright (C) 2016 Andreas Steffen - * Copyright (C) 2008-2016 Tobias Brunner * Copyright (C) 2005-2007 Martin Willi * Copyright (C) 2005 Jan Hutter * HSR Hochschule fuer Technik Rapperswil @@ -25,6 +25,7 @@ #define CHILD_CFG_H_ typedef enum action_t action_t; +typedef enum child_cfg_option_t child_cfg_option_t; typedef struct child_cfg_t child_cfg_t; typedef struct child_cfg_create_t child_cfg_create_t; @@ -147,13 +148,6 @@ struct child_cfg_t { char* (*get_updown)(child_cfg_t *this); /** - * Should we allow access to the local host (gateway)? - * - * @return value of hostaccess flag - */ - bool (*get_hostaccess) (child_cfg_t *this); - - /** * Get the lifetime configuration of a CHILD_SA. * * The rekey limits automatically contain a jitter to avoid simultaneous @@ -203,14 +197,6 @@ struct child_cfg_t { diffie_hellman_group_t (*get_dh_group)(child_cfg_t *this); /** - * Check whether IPComp should be used, if the other peer supports it. - * - * @return TRUE, if IPComp should be used - * FALSE, otherwise - */ - bool (*use_ipcomp)(child_cfg_t *this); - - /** * Get the inactivity timeout value. * * @return inactivity timeout in s @@ -263,33 +249,17 @@ struct child_cfg_t { /** * Set anti-replay window size * - * @param window anti-replay window size + * @param window anti-replay window size */ void (*set_replay_window)(child_cfg_t *this, uint32_t window); /** - * Check whether IPsec transport SA should be set up in proxy mode. - * - * @return TRUE, if proxy mode should be used - * FALSE, otherwise - */ - bool (*use_proxy_mode)(child_cfg_t *this); - - /** - * Check whether IPsec policies should be installed in the kernel. - * - * @return TRUE, if IPsec kernel policies should be installed - * FALSE, otherwise - */ - bool (*install_policy)(child_cfg_t *this); - - /** - * Check whether outbound FWD IPsec policies should be installed. + * Check if an option flag is set. * - * @return TRUE, if outbound FWD policies should be installed - * FALSE, otherwise + * @param option option flag to check + * @return TRUE if option flag set, FALSE otherwise */ - bool (*install_fwd_out_policy)(child_cfg_t *this); + bool (*has_option)(child_cfg_t *this, child_cfg_option_t option); /** * Check if two child_cfg objects are equal. @@ -315,11 +285,39 @@ struct child_cfg_t { void (*destroy) (child_cfg_t *this); }; +/** + * Option flags that may be set on a child_cfg_t object + */ +enum child_cfg_option_t { + + /** Use IPsec transport proxy mode */ + OPT_PROXY_MODE = (1<<0), + + /** Use IPComp, if peer supports it */ + OPT_IPCOMP = (1<<1), + + /** Allow access to the local host */ + OPT_HOSTACCESS = (1<<2), + + /** Don't install any IPsec policies */ + OPT_NO_POLICIES = (1<<3), + + /** Install outbound FWD IPsec policies to bypass drop policies */ + OPT_FWD_OUT_POLICIES = (1<<4), + + /** Enable hardware offload, if supported by the IPsec backend */ + OPT_HW_OFFLOAD = (1<<5), + + /** Force 96-bit truncation for SHA-256 */ + OPT_SHA256_96 = (1<<6), +}; /** * Data passed to the constructor of a child_cfg_t object. */ struct child_cfg_create_t { + /** Options set for CHILD_SA */ + child_cfg_option_t options; /** Specific reqid to use for CHILD_SA, 0 for auto assignment */ uint32_t reqid; /** Optional inbound mark */ @@ -328,10 +326,6 @@ struct child_cfg_create_t { mark_t mark_out; /** Mode to propose for CHILD_SA */ ipsec_mode_t mode; - /** Use IPsec transport proxy mode */ - bool proxy_mode; - /** Use IPComp, if peer supports it */ - bool ipcomp; /** TFC padding size, 0 to disable, -1 to pad to PMTU */ uint32_t tfc; /** Optional manually-set IPsec policy priority */ @@ -350,12 +344,6 @@ struct child_cfg_create_t { action_t close_action; /** updown script to execute on up/down event (cloned) */ char *updown; - /** TRUE to allow access to the local host */ - bool hostaccess; - /** Don't install IPsec policies */ - bool suppress_policies; - /** Install outbound FWD IPsec policies to bypass drop policies */ - bool fwd_out_policies; }; /** diff --git a/src/libcharon/config/ike_cfg.c b/src/libcharon/config/ike_cfg.c index 480dd3720..93300781d 100644 --- a/src/libcharon/config/ike_cfg.c +++ b/src/libcharon/config/ike_cfg.c @@ -224,12 +224,12 @@ static u_int match(linked_list_t *hosts, linked_list_t *ranges, host_t *cand) if (ts->to_subnet(ts, &host, &mask)) { quality = max(quality, mask + 1); - host->destroy(host); } else { quality = max(quality, 1); } + host->destroy(host); } } enumerator->destroy(enumerator); diff --git a/src/libcharon/config/ike_cfg.h b/src/libcharon/config/ike_cfg.h index 4d37264f6..034996f60 100644 --- a/src/libcharon/config/ike_cfg.h +++ b/src/libcharon/config/ike_cfg.h @@ -47,14 +47,16 @@ enum ike_version_t { }; /** - * Proprietary IKEv1 fragmentation + * Proprietary IKEv1 fragmentation and IKEv2 fragmentation */ enum fragmentation_t { /** disable fragmentation */ FRAGMENTATION_NO, - /** enable fragmentation if supported by peer */ + /** announce support, but don't send any fragments */ + FRAGMENTATION_ACCEPT, + /** enable fragmentation, if supported by peer */ FRAGMENTATION_YES, - /** force use of fragmentation (even for the first message) */ + /** force use of fragmentation (even for the first message for IKEv1) */ FRAGMENTATION_FORCE, }; diff --git a/src/libcharon/config/peer_cfg.c b/src/libcharon/config/peer_cfg.c index 5d7ab076e..fcdd6fdeb 100644 --- a/src/libcharon/config/peer_cfg.c +++ b/src/libcharon/config/peer_cfg.c @@ -209,9 +209,12 @@ typedef struct { } child_cfgs_replace_enumerator_t; METHOD(enumerator_t, child_cfgs_replace_enumerate, bool, - child_cfgs_replace_enumerator_t *this, child_cfg_t **chd, bool *added) + child_cfgs_replace_enumerator_t *this, va_list args) { - child_cfg_t *child_cfg; + child_cfg_t *child_cfg, **chd; + bool *added; + + VA_ARGS_VGET(args, chd, added); if (!this->wrapped) { @@ -303,8 +306,9 @@ METHOD(peer_cfg_t, replace_child_cfgs, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_child_cfgs_replace_enumerate, - .destroy = (void*)_child_cfgs_replace_enumerator_destroy, + .enumerate = enumerator_enumerate_default, + .venumerate = _child_cfgs_replace_enumerate, + .destroy = _child_cfgs_replace_enumerator_destroy, }, .removed = removed, .added = added, @@ -336,8 +340,11 @@ METHOD(enumerator_t, child_cfg_enumerator_destroy, void, } METHOD(enumerator_t, child_cfg_enumerate, bool, - child_cfg_enumerator_t *this, child_cfg_t **chd) + child_cfg_enumerator_t *this, va_list args) { + child_cfg_t **chd; + + VA_ARGS_VGET(args, chd); return this->wrapped->enumerate(this->wrapped, chd); } @@ -348,8 +355,9 @@ METHOD(peer_cfg_t, create_child_cfg_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_child_cfg_enumerate, - .destroy = (void*)_child_cfg_enumerator_destroy, + .enumerate = enumerator_enumerate_default, + .venumerate = _child_cfg_enumerate, + .destroy = _child_cfg_enumerator_destroy, }, .mutex = this->mutex, .wrapped = this->child_cfgs->create_enumerator(this->child_cfgs), diff --git a/src/libcharon/config/proposal.c b/src/libcharon/config/proposal.c index a2dc113a5..6c71f78d3 100644 --- a/src/libcharon/config/proposal.c +++ b/src/libcharon/config/proposal.c @@ -94,27 +94,31 @@ METHOD(proposal_t, add_algorithm, void, array_insert(this->transforms, ARRAY_TAIL, &entry); } -/** - * filter function for peer configs - */ -static bool alg_filter(uintptr_t type, entry_t **in, uint16_t *alg, - void **unused, uint16_t *key_size) +CALLBACK(alg_filter, bool, + uintptr_t type, enumerator_t *orig, va_list args) { - entry_t *entry = *in; + entry_t *entry; + uint16_t *alg, *key_size; - if (entry->type != type) - { - return FALSE; - } - if (alg) - { - *alg = entry->alg; - } - if (key_size) + VA_ARGS_VGET(args, alg, key_size); + + while (orig->enumerate(orig, &entry)) { - *key_size = entry->key_size; + if (entry->type != type) + { + continue; + } + if (alg) + { + *alg = entry->alg; + } + if (key_size) + { + *key_size = entry->key_size; + } + return TRUE; } - return TRUE; + return FALSE; } METHOD(proposal_t, create_enumerator, enumerator_t*, @@ -122,7 +126,7 @@ METHOD(proposal_t, create_enumerator, enumerator_t*, { return enumerator_create_filter( array_create_enumerator(this->transforms), - (void*)alg_filter, (void*)(uintptr_t)type, NULL); + alg_filter, (void*)(uintptr_t)type, NULL); } METHOD(proposal_t, get_algorithm, bool, diff --git a/src/libcharon/daemon.c b/src/libcharon/daemon.c index eadc10a6a..7c9f83d12 100644 --- a/src/libcharon/daemon.c +++ b/src/libcharon/daemon.c @@ -118,6 +118,13 @@ struct private_daemon_t { }; /** + * Register plugins if built statically + */ +#ifdef STATIC_PLUGIN_CONSTRUCTORS +#include "plugin_constructors.c" +#endif + +/** * One and only instance of the daemon. */ daemon_t *charon; @@ -275,13 +282,14 @@ static void logger_entry_unregister_destroy(logger_entry_t *this) logger_entry_destroy(this); } -/** - * Match a logger entry by target and whether it is a file or syslog logger - */ -static bool logger_entry_match(logger_entry_t *this, char *target, - logger_type_t *type) +CALLBACK(logger_entry_match, bool, + logger_entry_t *this, va_list args) { - return this->type == *type && streq(this->target, target); + logger_type_t type; + char *target; + + VA_ARGS_VGET(args, target, type); + return this->type == type && streq(this->target, target); } /** @@ -343,8 +351,8 @@ static logger_entry_t *get_logger_entry(char *target, logger_type_t type, { logger_entry_t *entry; - if (existing->find_first(existing, (void*)logger_entry_match, - (void**)&entry, target, &type) != SUCCESS) + if (!existing->find_first(existing, logger_entry_match, (void**)&entry, + target, type)) { INIT(entry, .target = strdup(target), diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c index 50dab9e38..6d850aac0 100644 --- a/src/libcharon/encoding/message.c +++ b/src/libcharon/encoding/message.c @@ -554,10 +554,10 @@ static payload_order_t aggressive_i_order[] = { {PLV1_CERTREQ, 0}, {PLV1_NOTIFY, 0}, {PLV1_VENDOR_ID, 0}, + {PLV1_HASH, 0}, {PLV1_NAT_D, 0}, {PLV1_NAT_D_DRAFT_00_03, 0}, {PLV1_SIGNATURE, 0}, - {PLV1_HASH, 0}, {PLV1_FRAGMENT, 0}, }; diff --git a/src/libcharon/encoding/payloads/certreq_payload.c b/src/libcharon/encoding/payloads/certreq_payload.c index 09bfa2458..643fbc42f 100644 --- a/src/libcharon/encoding/payloads/certreq_payload.c +++ b/src/libcharon/encoding/payloads/certreq_payload.c @@ -190,8 +190,12 @@ struct keyid_enumerator_t { }; METHOD(enumerator_t, keyid_enumerate, bool, - keyid_enumerator_t *this, chunk_t *chunk) + keyid_enumerator_t *this, va_list args) { + chunk_t *chunk; + + VA_ARGS_VGET(args, chunk); + if (this->pos == NULL) { this->pos = this->full.ptr; @@ -224,7 +228,8 @@ METHOD(certreq_payload_t, create_keyid_enumerator, enumerator_t*, } INIT(enumerator, .public = { - .enumerate = (void*)_keyid_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _keyid_enumerate, .destroy = (void*)free, }, .full = this->data, diff --git a/src/libcharon/encoding/payloads/delete_payload.c b/src/libcharon/encoding/payloads/delete_payload.c index 584e6f22b..3634cd36c 100644 --- a/src/libcharon/encoding/payloads/delete_payload.c +++ b/src/libcharon/encoding/payloads/delete_payload.c @@ -306,8 +306,12 @@ typedef struct { } spi_enumerator_t; METHOD(enumerator_t, spis_enumerate, bool, - spi_enumerator_t *this, uint32_t *spi) + spi_enumerator_t *this, va_list args) { + uint32_t *spi; + + VA_ARGS_VGET(args, spi); + if (this->spis.len >= sizeof(*spi)) { memcpy(spi, this->spis.ptr, sizeof(*spi)); @@ -328,7 +332,8 @@ METHOD(delete_payload_t, create_spi_enumerator, enumerator_t*, } INIT(e, .public = { - .enumerate = (void*)_spis_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _spis_enumerate, .destroy = (void*)free, }, .spis = this->spis, diff --git a/src/libcharon/encoding/payloads/eap_payload.c b/src/libcharon/encoding/payloads/eap_payload.c index 8c3fc5933..923135da9 100644 --- a/src/libcharon/encoding/payloads/eap_payload.c +++ b/src/libcharon/encoding/payloads/eap_payload.c @@ -270,8 +270,12 @@ typedef struct { } type_enumerator_t; METHOD(enumerator_t, enumerate_types, bool, - type_enumerator_t *this, eap_type_t *type, uint32_t *vendor) + type_enumerator_t *this, va_list args) { + eap_type_t *type; + uint32_t *vendor; + + VA_ARGS_VGET(args, type, vendor); this->offset = extract_type(this->payload, this->offset, type, vendor); return this->offset; } @@ -289,7 +293,8 @@ METHOD(eap_payload_t, get_types, enumerator_t*, { INIT(enumerator, .public = { - .enumerate = (void*)_enumerate_types, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_types, .destroy = (void*)free, }, .payload = this, diff --git a/src/libcharon/kernel/kernel_interface.c b/src/libcharon/kernel/kernel_interface.c index ea5af9eb8..3d736b25b 100644 --- a/src/libcharon/kernel/kernel_interface.c +++ b/src/libcharon/kernel/kernel_interface.c @@ -632,21 +632,18 @@ METHOD(kernel_interface_t, enable_udp_decap, bool, METHOD(kernel_interface_t, is_interface_usable, bool, private_kernel_interface_t *this, const char *iface) { - status_t expected; - if (!this->ifaces_filter) { return TRUE; } - expected = this->ifaces_exclude ? NOT_FOUND : SUCCESS; - return this->ifaces_filter->find_first(this->ifaces_filter, (void*)streq, - NULL, iface) == expected; + return this->ifaces_filter->find_first(this->ifaces_filter, + linked_list_match_str, NULL, iface) != this->ifaces_exclude; } METHOD(kernel_interface_t, all_interfaces_usable, bool, private_kernel_interface_t *this) { - return this->ifaces_filter == NULL; + return !this->ifaces_filter; } METHOD(kernel_interface_t, get_address_by_ts, status_t, diff --git a/src/libcharon/kernel/kernel_ipsec.h b/src/libcharon/kernel/kernel_ipsec.h index 0ad566068..6fafeb760 100644 --- a/src/libcharon/kernel/kernel_ipsec.h +++ b/src/libcharon/kernel/kernel_ipsec.h @@ -91,6 +91,8 @@ struct kernel_ipsec_add_sa_t { uint16_t cpi; /** TRUE to enable UDP encapsulation for NAT traversal */ bool encap; + /** TRUE to enable hardware offloading if available */ + bool hw_offload; /** TRUE to use Extended Sequence Numbers */ bool esn; /** TRUE if initiator of the exchange creating the SA */ diff --git a/src/libcharon/network/receiver.c b/src/libcharon/network/receiver.c index 1bf93ad40..8fb48281f 100644 --- a/src/libcharon/network/receiver.c +++ b/src/libcharon/network/receiver.c @@ -321,18 +321,16 @@ static bool cookie_required(private_receiver_t *this, */ static bool drop_ike_sa_init(private_receiver_t *this, message_t *message) { - u_int half_open, half_open_r; + u_int half_open; uint32_t now; now = time_monotonic(NULL); half_open = charon->ike_sa_manager->get_half_open_count( - charon->ike_sa_manager, NULL, FALSE); - half_open_r = charon->ike_sa_manager->get_half_open_count( charon->ike_sa_manager, NULL, TRUE); /* check for cookies in IKEv2 */ if (message->get_major_version(message) == IKEV2_MAJOR_VERSION && - cookie_required(this, half_open_r, now) && !check_cookie(this, message)) + cookie_required(this, half_open, now) && !check_cookie(this, message)) { chunk_t cookie; diff --git a/src/libcharon/plugins/addrblock/Makefile.in b/src/libcharon/plugins/addrblock/Makefile.in index f5dfc14d7..60fd19bdc 100644 --- a/src/libcharon/plugins/addrblock/Makefile.in +++ b/src/libcharon/plugins/addrblock/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/addrblock/addrblock_validator.c b/src/libcharon/plugins/addrblock/addrblock_validator.c index d16a1170c..78e377c2a 100644 --- a/src/libcharon/plugins/addrblock/addrblock_validator.c +++ b/src/libcharon/plugins/addrblock/addrblock_validator.c @@ -56,12 +56,12 @@ static bool check_addrblock(private_addrblock_validator_t *this, } if (!subject_const) { - DBG1(DBG_CFG, "subject certficate lacks ipAddrBlocks extension"); + DBG1(DBG_CFG, "subject certificate lacks ipAddrBlocks extension"); return !this->strict; } if (!issuer_const) { - DBG1(DBG_CFG, "issuer certficate lacks ipAddrBlocks extension"); + DBG1(DBG_CFG, "issuer certificate lacks ipAddrBlocks extension"); return FALSE; } subject_enumerator = subject->create_ipAddrBlock_enumerator(subject); diff --git a/src/libcharon/plugins/android_dns/Makefile.in b/src/libcharon/plugins/android_dns/Makefile.in index d79c753f0..0533d81eb 100644 --- a/src/libcharon/plugins/android_dns/Makefile.in +++ b/src/libcharon/plugins/android_dns/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/android_dns/android_dns_handler.c b/src/libcharon/plugins/android_dns/android_dns_handler.c index 160a145d3..68bbaecb2 100644 --- a/src/libcharon/plugins/android_dns/android_dns_handler.c +++ b/src/libcharon/plugins/android_dns/android_dns_handler.c @@ -182,12 +182,15 @@ METHOD(attribute_handler_t, release, void, } METHOD(enumerator_t, enumerate_dns, bool, - enumerator_t *this, configuration_attribute_type_t *type, chunk_t *data) + enumerator_t *this, va_list args) { + configuration_attribute_type_t *type; + chunk_t *data; + + VA_ARGS_VGET(args, type, data); *type = INTERNAL_IP4_DNS; *data = chunk_empty; - /* stop enumeration */ - this->enumerate = (void*)return_false; + this->venumerate = return_false; return TRUE; } @@ -198,7 +201,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *, enumerator_t *enumerator; INIT(enumerator, - .enumerate = (void*)_enumerate_dns, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_dns, .destroy = (void*)free, ); return enumerator; diff --git a/src/libcharon/plugins/android_log/Makefile.am b/src/libcharon/plugins/android_log/Makefile.am index 9f82f6e60..4f062ee65 100644 --- a/src/libcharon/plugins/android_log/Makefile.am +++ b/src/libcharon/plugins/android_log/Makefile.am @@ -16,3 +16,4 @@ libstrongswan_android_log_la_SOURCES = \ android_log_logger.c android_log_logger.h libstrongswan_android_log_la_LDFLAGS = -module -avoid-version +libstrongswan_android_log_la_LIBADD = -llog diff --git a/src/libcharon/plugins/android_log/Makefile.in b/src/libcharon/plugins/android_log/Makefile.in index 65cdcff94..bc402ef69 100644 --- a/src/libcharon/plugins/android_log/Makefile.in +++ b/src/libcharon/plugins/android_log/Makefile.in @@ -136,7 +136,7 @@ am__uninstall_files_from_dir = { \ } am__installdirs = "$(DESTDIR)$(plugindir)" LTLIBRARIES = $(noinst_LTLIBRARIES) $(plugin_LTLIBRARIES) -libstrongswan_android_log_la_LIBADD = +libstrongswan_android_log_la_DEPENDENCIES = am_libstrongswan_android_log_la_OBJECTS = android_log_plugin.lo \ android_log_logger.lo libstrongswan_android_log_la_OBJECTS = \ @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ @@ -458,6 +460,7 @@ libstrongswan_android_log_la_SOURCES = \ android_log_logger.c android_log_logger.h libstrongswan_android_log_la_LDFLAGS = -module -avoid-version +libstrongswan_android_log_la_LIBADD = -llog all: all-am .SUFFIXES: diff --git a/src/libcharon/plugins/attr/Makefile.in b/src/libcharon/plugins/attr/Makefile.in index 217a42ae6..9fe4d946f 100644 --- a/src/libcharon/plugins/attr/Makefile.in +++ b/src/libcharon/plugins/attr/Makefile.in @@ -355,6 +355,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -377,6 +378,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/attr/attr_provider.c b/src/libcharon/plugins/attr/attr_provider.c index f4c143641..3310f79fd 100644 --- a/src/libcharon/plugins/attr/attr_provider.c +++ b/src/libcharon/plugins/attr/attr_provider.c @@ -75,17 +75,23 @@ typedef struct { ike_version_t ike; } enumerator_data_t; -/** - * convert enumerator value from attribute_entry - */ -static bool attr_enum_filter(enumerator_data_t *data, attribute_entry_t **in, - configuration_attribute_type_t *type, void* none, chunk_t *value) +CALLBACK(attr_enum_filter, bool, + enumerator_data_t *data, enumerator_t *orig, va_list args) { - if ((*in)->ike == IKE_ANY || (*in)->ike == data->ike) + configuration_attribute_type_t *type; + attribute_entry_t *entry; + chunk_t *value; + + VA_ARGS_VGET(args, type, value); + + while (orig->enumerate(orig, &entry)) { - *type = (*in)->type; - *value = (*in)->value; - return TRUE; + if (entry->ike == IKE_ANY || entry->ike == data->ike) + { + *type = entry->type; + *value = entry->value; + return TRUE; + } } return FALSE; } @@ -112,7 +118,7 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, this->lock->read_lock(this->lock); return enumerator_create_filter( this->attributes->create_enumerator(this->attributes), - (void*)attr_enum_filter, data, attr_enum_destroy); + attr_enum_filter, data, attr_enum_destroy); } return enumerator_create_empty(); } diff --git a/src/libcharon/plugins/attr_sql/Makefile.in b/src/libcharon/plugins/attr_sql/Makefile.in index 668e23f07..b3ddf69b5 100644 --- a/src/libcharon/plugins/attr_sql/Makefile.in +++ b/src/libcharon/plugins/attr_sql/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/attr_sql/attr_sql_provider.c b/src/libcharon/plugins/attr_sql/attr_sql_provider.c index c2410705d..33d9f99fc 100644 --- a/src/libcharon/plugins/attr_sql/attr_sql_provider.c +++ b/src/libcharon/plugins/attr_sql/attr_sql_provider.c @@ -200,7 +200,6 @@ static host_t* get_lease(private_attr_sql_provider_t *this, char *name, "SELECT id, address FROM addresses " "WHERE pool = ? AND identity = 0 LIMIT 1", DB_UINT, pool, DB_UINT, DB_BLOB); - } if (!e || !e->enumerate(e, &id, &address)) @@ -447,7 +446,6 @@ METHOD(attr_sql_provider_t, destroy, void, attr_sql_provider_t *attr_sql_provider_create(database_t *db) { private_attr_sql_provider_t *this; - time_t now = time(NULL); INIT(this, .public = { @@ -460,19 +458,25 @@ attr_sql_provider_t *attr_sql_provider_create(database_t *db) }, .db = db, .history = lib->settings->get_bool(lib->settings, - "%s.plugins.attr-sql.lease_history", TRUE, lib->ns), + "%s.plugins.attr-sql.lease_history", TRUE, lib->ns), ); - /* close any "online" leases in the case we crashed */ - if (this->history) + if (lib->settings->get_bool(lib->settings, + "%s.plugins.attr-sql.crash_recovery", TRUE, lib->ns)) { - this->db->execute(this->db, NULL, + time_t now = time(NULL); + + /* close any "online" leases in the case we crashed */ + if (this->history) + { + this->db->execute(this->db, NULL, "INSERT INTO leases (address, identity, acquired, released)" " SELECT id, identity, acquired, ? FROM addresses " " WHERE released = 0", DB_UINT, now); - } - this->db->execute(this->db, NULL, + } + this->db->execute(this->db, NULL, "UPDATE addresses SET released = ? WHERE released = 0", DB_UINT, now); + } return &this->public; } diff --git a/src/libcharon/plugins/bypass_lan/Makefile.in b/src/libcharon/plugins/bypass_lan/Makefile.in index 9f1dc71c9..6c079481b 100644 --- a/src/libcharon/plugins/bypass_lan/Makefile.in +++ b/src/libcharon/plugins/bypass_lan/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/bypass_lan/bypass_lan_listener.c b/src/libcharon/plugins/bypass_lan/bypass_lan_listener.c index e690028f2..644cff029 100644 --- a/src/libcharon/plugins/bypass_lan/bypass_lan_listener.c +++ b/src/libcharon/plugins/bypass_lan/bypass_lan_listener.c @@ -110,15 +110,12 @@ static bool policy_equals(bypass_policy_t *a, bypass_policy_t *b) */ static bool consider_interface(private_bypass_lan_listener_t *this, char *iface) { - status_t expected; - if (!iface || !this->ifaces_filter) { return TRUE; } - expected = this->ifaces_exclude ? NOT_FOUND : SUCCESS; - return this->ifaces_filter->find_first(this->ifaces_filter, (void*)streq, - NULL, iface) == expected; + return this->ifaces_filter->find_first(this->ifaces_filter, + linked_list_match_str, NULL, iface) != this->ifaces_exclude; } /** diff --git a/src/libcharon/plugins/certexpire/Makefile.in b/src/libcharon/plugins/certexpire/Makefile.in index ffde2d7aa..acbd7a858 100644 --- a/src/libcharon/plugins/certexpire/Makefile.in +++ b/src/libcharon/plugins/certexpire/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/connmark/Makefile.in b/src/libcharon/plugins/connmark/Makefile.in index 140f1b6ad..55bc25a9f 100644 --- a/src/libcharon/plugins/connmark/Makefile.in +++ b/src/libcharon/plugins/connmark/Makefile.in @@ -359,6 +359,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -381,6 +382,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/coupling/Makefile.in b/src/libcharon/plugins/coupling/Makefile.in index 3910e4ea4..6d6fe25bb 100644 --- a/src/libcharon/plugins/coupling/Makefile.in +++ b/src/libcharon/plugins/coupling/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/dhcp/Makefile.in b/src/libcharon/plugins/dhcp/Makefile.in index 6033c6e12..d3f4ec8bc 100644 --- a/src/libcharon/plugins/dhcp/Makefile.in +++ b/src/libcharon/plugins/dhcp/Makefile.in @@ -356,6 +356,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -378,6 +379,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/dhcp/dhcp_provider.c b/src/libcharon/plugins/dhcp/dhcp_provider.c index f0681b1da..50ffbab9d 100644 --- a/src/libcharon/plugins/dhcp/dhcp_provider.c +++ b/src/libcharon/plugins/dhcp/dhcp_provider.c @@ -151,8 +151,7 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, identification_t *id; host_t *vip; - if (pools->find_first(pools, (linked_list_match_t)streq, - NULL, "dhcp") != SUCCESS) + if (!pools->find_first(pools, linked_list_match_str, NULL, "dhcp")) { return NULL; } diff --git a/src/libcharon/plugins/dhcp/dhcp_socket.c b/src/libcharon/plugins/dhcp/dhcp_socket.c index 807c68274..42f8f1ef9 100644 --- a/src/libcharon/plugins/dhcp/dhcp_socket.c +++ b/src/libcharon/plugins/dhcp/dhcp_socket.c @@ -382,8 +382,7 @@ METHOD(dhcp_socket_t, enroll, dhcp_transaction_t*, while (try <= DHCP_TRIES && discover(this, transaction)) { if (!this->condvar->timed_wait(this->condvar, this->mutex, 1000 * try) && - this->request->find_first(this->request, NULL, - (void**)&transaction) == SUCCESS) + this->request->find_first(this->request, NULL, (void**)&transaction)) { break; } diff --git a/src/libcharon/plugins/dhcp/dhcp_transaction.c b/src/libcharon/plugins/dhcp/dhcp_transaction.c index 3ee88a698..87711799c 100644 --- a/src/libcharon/plugins/dhcp/dhcp_transaction.c +++ b/src/libcharon/plugins/dhcp/dhcp_transaction.c @@ -114,16 +114,22 @@ METHOD(dhcp_transaction_t, add_attribute, void, this->attributes->insert_last(this->attributes, entry); } -/** - * Filter function to map entries to type/data - */ -static bool attribute_filter(void *null, attribute_entry_t **entry, - configuration_attribute_type_t *type, - void **dummy, chunk_t *data) +CALLBACK(attribute_filter, bool, + void *null, enumerator_t *orig, va_list args) { - *type = (*entry)->type; - *data = (*entry)->data; - return TRUE; + configuration_attribute_type_t *type; + attribute_entry_t *entry; + chunk_t *data; + + VA_ARGS_VGET(args, type, data); + + if (orig->enumerate(orig, &entry)) + { + *type = entry->type; + *data = entry->data; + return TRUE; + } + return FALSE; } METHOD(dhcp_transaction_t, create_attribute_enumerator, enumerator_t*, @@ -131,7 +137,7 @@ METHOD(dhcp_transaction_t, create_attribute_enumerator, enumerator_t*, { return enumerator_create_filter( this->attributes->create_enumerator(this->attributes), - (void*)attribute_filter, NULL, NULL); + attribute_filter, NULL, NULL); } /** diff --git a/src/libcharon/plugins/dnscert/Makefile.in b/src/libcharon/plugins/dnscert/Makefile.in index cd66af8c8..3687f0cb7 100644 --- a/src/libcharon/plugins/dnscert/Makefile.in +++ b/src/libcharon/plugins/dnscert/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/dnscert/dnscert_cred.c b/src/libcharon/plugins/dnscert/dnscert_cred.c index d32794c99..533bd5be4 100644 --- a/src/libcharon/plugins/dnscert/dnscert_cred.c +++ b/src/libcharon/plugins/dnscert/dnscert_cred.c @@ -75,12 +75,15 @@ typedef struct { } cert_enumerator_t; METHOD(enumerator_t, cert_enumerator_enumerate, bool, - cert_enumerator_t *this, certificate_t **cert) + cert_enumerator_t *this, va_list args) { + certificate_t **cert; dnscert_t *cur_crt; rr_t *cur_rr; chunk_t certificate; + VA_ARGS_VGET(args, cert); + /* Get the next supported CERT using the inner enumerator. */ while (this->inner->enumerate(this->inner, &cur_rr)) { @@ -175,7 +178,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_cert_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _cert_enumerator_enumerate, .destroy = _cert_enumerator_destroy, }, .inner = response->get_rr_set(response)->create_rr_enumerator( diff --git a/src/libcharon/plugins/duplicheck/Makefile.in b/src/libcharon/plugins/duplicheck/Makefile.in index e4b60e6ad..69959d30f 100644 --- a/src/libcharon/plugins/duplicheck/Makefile.in +++ b/src/libcharon/plugins/duplicheck/Makefile.in @@ -365,6 +365,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -387,6 +388,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/eap_aka/Makefile.in b/src/libcharon/plugins/eap_aka/Makefile.in index 20c0ddb8f..5fff12890 100644 --- a/src/libcharon/plugins/eap_aka/Makefile.in +++ b/src/libcharon/plugins/eap_aka/Makefile.in @@ -359,6 +359,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -381,6 +382,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in index f4fb8ec42..478225562 100644 --- a/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in +++ b/src/libcharon/plugins/eap_aka_3gpp2/Makefile.in @@ -360,6 +360,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -382,6 +383,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/eap_dynamic/Makefile.in b/src/libcharon/plugins/eap_dynamic/Makefile.in index 2dbc05f02..2591dee55 100644 --- a/src/libcharon/plugins/eap_dynamic/Makefile.in +++ b/src/libcharon/plugins/eap_dynamic/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/eap_dynamic/eap_dynamic.c b/src/libcharon/plugins/eap_dynamic/eap_dynamic.c index 83ccd3a8a..204fb317d 100644 --- a/src/libcharon/plugins/eap_dynamic/eap_dynamic.c +++ b/src/libcharon/plugins/eap_dynamic/eap_dynamic.c @@ -69,6 +69,15 @@ static bool entry_matches(eap_vendor_type_t *item, eap_vendor_type_t *other) return item->type == other->type && item->vendor == other->vendor; } +CALLBACK(entry_matches_cb, bool, + eap_vendor_type_t *item, va_list args) +{ + eap_vendor_type_t *other; + + VA_ARGS_VGET(args, other); + return entry_matches(item, other); +} + /** * Load the given EAP method */ @@ -121,8 +130,7 @@ static void select_method(private_eap_dynamic_t *this) { if (inner) { - if (inner->find_first(inner, (void*)entry_matches, - NULL, entry) != SUCCESS) + if (!inner->find_first(inner, entry_matches_cb, NULL, entry)) { if (entry->vendor) { diff --git a/src/libcharon/plugins/eap_gtc/Makefile.in b/src/libcharon/plugins/eap_gtc/Makefile.in index 01d509ebd..08d8ef8f6 100644 --- a/src/libcharon/plugins/eap_gtc/Makefile.in +++ b/src/libcharon/plugins/eap_gtc/Makefile.in @@ -357,6 +357,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -379,6 +380,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/eap_identity/Makefile.in b/src/libcharon/plugins/eap_identity/Makefile.in index cc1f21eed..4859833ba 100644 --- a/src/libcharon/plugins/eap_identity/Makefile.in +++ b/src/libcharon/plugins/eap_identity/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/eap_md5/Makefile.in b/src/libcharon/plugins/eap_md5/Makefile.in index 939bbf942..796d42f14 100644 --- a/src/libcharon/plugins/eap_md5/Makefile.in +++ b/src/libcharon/plugins/eap_md5/Makefile.in @@ -357,6 +357,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -379,6 +380,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/eap_mschapv2/Makefile.in b/src/libcharon/plugins/eap_mschapv2/Makefile.in index 1e1936c45..00a9f73da 100644 --- a/src/libcharon/plugins/eap_mschapv2/Makefile.in +++ b/src/libcharon/plugins/eap_mschapv2/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/eap_peap/Makefile.in b/src/libcharon/plugins/eap_peap/Makefile.in index b83a80f73..df3c2eae2 100644 --- a/src/libcharon/plugins/eap_peap/Makefile.in +++ b/src/libcharon/plugins/eap_peap/Makefile.in @@ -359,6 +359,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -381,6 +382,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/eap_radius/Makefile.in b/src/libcharon/plugins/eap_radius/Makefile.in index 29a2f3898..d8ebeb8b5 100644 --- a/src/libcharon/plugins/eap_radius/Makefile.in +++ b/src/libcharon/plugins/eap_radius/Makefile.in @@ -360,6 +360,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -382,6 +383,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/eap_radius/eap_radius_provider.c b/src/libcharon/plugins/eap_radius/eap_radius_provider.c index 9a87ad38d..58bbc2edd 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius_provider.c +++ b/src/libcharon/plugins/eap_radius/eap_radius_provider.c @@ -404,11 +404,13 @@ typedef struct { attr_t *current; } attribute_enumerator_t; - METHOD(enumerator_t, attribute_enumerate, bool, - attribute_enumerator_t *this, configuration_attribute_type_t *type, - chunk_t *data) + attribute_enumerator_t *this, va_list args) { + configuration_attribute_type_t *type; + chunk_t *data; + + VA_ARGS_VGET(args, type, data); if (this->current) { destroy_attr(this->current); @@ -446,7 +448,8 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_attribute_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _attribute_enumerate, .destroy = _attribute_destroy, }, .list = linked_list_create(), diff --git a/src/libcharon/plugins/eap_sim/Makefile.in b/src/libcharon/plugins/eap_sim/Makefile.in index b4abce9b3..6c2584ae4 100644 --- a/src/libcharon/plugins/eap_sim/Makefile.in +++ b/src/libcharon/plugins/eap_sim/Makefile.in @@ -359,6 +359,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -381,6 +382,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/eap_sim_file/Makefile.in b/src/libcharon/plugins/eap_sim_file/Makefile.in index 914c8c0be..b2473725a 100644 --- a/src/libcharon/plugins/eap_sim_file/Makefile.in +++ b/src/libcharon/plugins/eap_sim_file/Makefile.in @@ -360,6 +360,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -382,6 +383,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c b/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c index ec1686910..03a60cfb1 100644 --- a/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c +++ b/src/libcharon/plugins/eap_sim_file/eap_sim_file_triplets.c @@ -79,10 +79,8 @@ typedef struct { private_eap_sim_file_triplets_t *this; } triplet_enumerator_t; -/** - * destroy a triplet enumerator - */ -static void enumerator_destroy(triplet_enumerator_t *e) +METHOD(enumerator_t, enumerator_destroy, void, + triplet_enumerator_t *e) { if (e->current) { @@ -97,13 +95,14 @@ static void enumerator_destroy(triplet_enumerator_t *e) free(e); } -/** - * enumerate through triplets - */ -static bool enumerator_enumerate(triplet_enumerator_t *e, identification_t **imsi, - char **rand, char **sres, char **kc) +METHOD(enumerator_t, enumerator_enumerate, bool, + triplet_enumerator_t *e, va_list args) { + identification_t **imsi; triplet_t *triplet; + char **rand, **sres, **kc; + + VA_ARGS_VGET(args, imsi, rand, sres, kc); if (e->inner->enumerate(e->inner, &triplet)) { @@ -121,15 +120,18 @@ static bool enumerator_enumerate(triplet_enumerator_t *e, identification_t **ims METHOD(eap_sim_file_triplets_t, create_enumerator, enumerator_t*, private_eap_sim_file_triplets_t *this) { - triplet_enumerator_t *enumerator = malloc_thing(triplet_enumerator_t); + triplet_enumerator_t *enumerator; this->mutex->lock(this->mutex); - enumerator->public.enumerate = (void*)enumerator_enumerate; - enumerator->public.destroy = (void*)enumerator_destroy; - enumerator->inner = this->triplets->create_enumerator(this->triplets); - enumerator->current = NULL; - enumerator->this = this; - + INIT(enumerator, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerator_enumerate, + .destroy = _enumerator_destroy, + }, + .inner = this->triplets->create_enumerator(this->triplets), + .this = this, + ); return &enumerator->public; } diff --git a/src/libcharon/plugins/eap_sim_pcsc/Makefile.in b/src/libcharon/plugins/eap_sim_pcsc/Makefile.in index 48ef92136..88c31a95e 100644 --- a/src/libcharon/plugins/eap_sim_pcsc/Makefile.in +++ b/src/libcharon/plugins/eap_sim_pcsc/Makefile.in @@ -361,6 +361,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -383,6 +384,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in index 5f12e2e2e..62c8ca11e 100644 --- a/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in +++ b/src/libcharon/plugins/eap_simaka_pseudonym/Makefile.in @@ -361,6 +361,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -383,6 +384,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in index 45e2b7498..ef20102bb 100644 --- a/src/libcharon/plugins/eap_simaka_reauth/Makefile.in +++ b/src/libcharon/plugins/eap_simaka_reauth/Makefile.in @@ -360,6 +360,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -382,6 +383,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/eap_simaka_sql/Makefile.in b/src/libcharon/plugins/eap_simaka_sql/Makefile.in index 8c134cff9..c9af52fa9 100644 --- a/src/libcharon/plugins/eap_simaka_sql/Makefile.in +++ b/src/libcharon/plugins/eap_simaka_sql/Makefile.in @@ -359,6 +359,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -381,6 +382,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.c b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.c index 90627b52e..0f59c5b78 100644 --- a/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.c +++ b/src/libcharon/plugins/eap_simaka_sql/eap_simaka_sql_card.c @@ -2,6 +2,9 @@ * Copyright (C) 2010 Martin Willi * Copyright (C) 2010 revosec AG * + * Copyright (C) 2017 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 @@ -54,7 +57,7 @@ METHOD(simaka_card_t, get_triplet, bool, snprintf(buf, sizeof(buf), "%Y", id); query = this->db->query(this->db, "select sres, kc from triplets where rand = ? and id = ? " - "order by use limit 1", + "order by used limit 1", DB_BLOB, chunk_create(rand, SIM_RAND_LEN), DB_TEXT, buf, DB_BLOB, DB_BLOB); if (query) @@ -82,7 +85,7 @@ METHOD(simaka_card_t, get_triplet, bool, else { this->db->execute(this->db, NULL, - "update triplets set use = ? where id = ? and rand = ?", + "update triplets set used = ? where id = ? and rand = ?", DB_UINT, time(NULL), DB_TEXT, buf, DB_BLOB, chunk_create(rand, SIM_RAND_LEN)); } @@ -102,7 +105,7 @@ METHOD(simaka_card_t, get_quintuplet, status_t, snprintf(buf, sizeof(buf), "%Y", id); query = this->db->query(this->db, "select ck, ik, res from quintuplets " - "where rand = ? and autn = ? and id = ? order by use limit 1", + "where rand = ? and autn = ? and id = ? order by used limit 1", DB_BLOB, chunk_create(rand, AKA_RAND_LEN), DB_BLOB, chunk_create(autn, AKA_AUTN_LEN), DB_TEXT, buf, DB_BLOB, DB_BLOB, DB_BLOB); @@ -134,7 +137,7 @@ METHOD(simaka_card_t, get_quintuplet, status_t, else { this->db->execute(this->db, NULL, - "update quintuplets set use = ? where id = ? and rand = ?", + "update quintuplets set used = ? where id = ? and rand = ?", DB_UINT, time(NULL), DB_TEXT, buf, DB_BLOB, chunk_create(rand, AKA_RAND_LEN)); } diff --git a/src/libcharon/plugins/eap_tls/Makefile.in b/src/libcharon/plugins/eap_tls/Makefile.in index a9a2dede9..dfe6d8b03 100644 --- a/src/libcharon/plugins/eap_tls/Makefile.in +++ b/src/libcharon/plugins/eap_tls/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/eap_tnc/Makefile.in b/src/libcharon/plugins/eap_tnc/Makefile.in index cda1728c0..902d79d76 100644 --- a/src/libcharon/plugins/eap_tnc/Makefile.in +++ b/src/libcharon/plugins/eap_tnc/Makefile.in @@ -359,6 +359,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -381,6 +382,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/eap_ttls/Makefile.in b/src/libcharon/plugins/eap_ttls/Makefile.in index a72b00576..53fb187fd 100644 --- a/src/libcharon/plugins/eap_ttls/Makefile.in +++ b/src/libcharon/plugins/eap_ttls/Makefile.in @@ -360,6 +360,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -382,6 +383,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/error_notify/Makefile.in b/src/libcharon/plugins/error_notify/Makefile.in index 33862f01a..1514f4011 100644 --- a/src/libcharon/plugins/error_notify/Makefile.in +++ b/src/libcharon/plugins/error_notify/Makefile.in @@ -366,6 +366,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -388,6 +389,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/ext_auth/Makefile.in b/src/libcharon/plugins/ext_auth/Makefile.in index de83d83d5..c3a18191f 100644 --- a/src/libcharon/plugins/ext_auth/Makefile.in +++ b/src/libcharon/plugins/ext_auth/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/farp/Makefile.in b/src/libcharon/plugins/farp/Makefile.in index daee657e7..3de99da38 100644 --- a/src/libcharon/plugins/farp/Makefile.in +++ b/src/libcharon/plugins/farp/Makefile.in @@ -356,6 +356,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -378,6 +379,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/forecast/Makefile.in b/src/libcharon/plugins/forecast/Makefile.in index 5254bca04..5263ccd43 100644 --- a/src/libcharon/plugins/forecast/Makefile.in +++ b/src/libcharon/plugins/forecast/Makefile.in @@ -359,6 +359,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -381,6 +382,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/forecast/forecast_listener.c b/src/libcharon/plugins/forecast/forecast_listener.c index 2024c2682..4585731de 100644 --- a/src/libcharon/plugins/forecast/forecast_listener.c +++ b/src/libcharon/plugins/forecast/forecast_listener.c @@ -613,17 +613,23 @@ METHOD(listener_t, ike_update, bool, return TRUE; } -/** - * Filter to map entries to ts/mark - */ -static bool ts_filter(entry_t *entry, traffic_selector_t **ts, - traffic_selector_t **out, void *dummy, uint32_t *mark, - void *dummy2, bool *reinject) +CALLBACK(ts_filter, bool, + entry_t *entry, enumerator_t *orig, va_list args) { - *out = *ts; - *mark = entry->mark; - *reinject = entry->reinject; - return TRUE; + traffic_selector_t *ts, **out; + uint32_t *mark; + bool *reinject; + + VA_ARGS_VGET(args, out, mark, reinject); + + if (orig->enumerate(orig, &ts)) + { + *out = ts; + *mark = entry->mark; + *reinject = entry->reinject; + return TRUE; + } + return FALSE; } /** @@ -632,7 +638,7 @@ static bool ts_filter(entry_t *entry, traffic_selector_t **ts, static enumerator_t* create_inner_local(entry_t *entry, rwlock_t *lock) { return enumerator_create_filter(array_create_enumerator(entry->lts), - (void*)ts_filter, entry, NULL); + ts_filter, entry, NULL); } /** @@ -641,7 +647,7 @@ static enumerator_t* create_inner_local(entry_t *entry, rwlock_t *lock) static enumerator_t* create_inner_remote(entry_t *entry, rwlock_t *lock) { return enumerator_create_filter(array_create_enumerator(entry->rts), - (void*)ts_filter, entry, NULL); + ts_filter, entry, NULL); } METHOD(forecast_listener_t, create_enumerator, enumerator_t*, diff --git a/src/libcharon/plugins/ha/Makefile.in b/src/libcharon/plugins/ha/Makefile.in index dd2a7a94c..d82bdd28e 100644 --- a/src/libcharon/plugins/ha/Makefile.in +++ b/src/libcharon/plugins/ha/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/ha/ha_dispatcher.c b/src/libcharon/plugins/ha/ha_dispatcher.c index ee66b8442..7d22257c6 100644 --- a/src/libcharon/plugins/ha/ha_dispatcher.c +++ b/src/libcharon/plugins/ha/ha_dispatcher.c @@ -818,14 +818,14 @@ static void process_child_add(private_ha_dispatcher_t *this, } enumerator->destroy(enumerator); + child_sa->set_policies(child_sa, local_ts, remote_ts); + if (initiator) { if (child_sa->install(child_sa, encr_r, integ_r, inbound_spi, - inbound_cpi, initiator, TRUE, TRUE, - local_ts, remote_ts) != SUCCESS || + inbound_cpi, initiator, TRUE, TRUE) != SUCCESS || child_sa->install(child_sa, encr_i, integ_i, outbound_spi, - outbound_cpi, initiator, FALSE, TRUE, - local_ts, remote_ts) != SUCCESS) + outbound_cpi, initiator, FALSE, TRUE) != SUCCESS) { failed = TRUE; } @@ -833,11 +833,9 @@ static void process_child_add(private_ha_dispatcher_t *this, else { if (child_sa->install(child_sa, encr_i, integ_i, inbound_spi, - inbound_cpi, initiator, TRUE, TRUE, - local_ts, remote_ts) != SUCCESS || + inbound_cpi, initiator, TRUE, TRUE) != SUCCESS || child_sa->install(child_sa, encr_r, integ_r, outbound_spi, - outbound_cpi, initiator, FALSE, TRUE, - local_ts, remote_ts) != SUCCESS) + outbound_cpi, initiator, FALSE, TRUE) != SUCCESS) { failed = TRUE; } @@ -868,7 +866,7 @@ static void process_child_add(private_ha_dispatcher_t *this, child_sa->get_unique_id(child_sa), local_ts, remote_ts, seg_i, this->segments->is_active(this->segments, seg_i) ? "*" : "", seg_o, this->segments->is_active(this->segments, seg_o) ? "*" : ""); - child_sa->add_policies(child_sa, local_ts, remote_ts); + child_sa->install_policies(child_sa); local_ts->destroy_offset(local_ts, offsetof(traffic_selector_t, destroy)); remote_ts->destroy_offset(remote_ts, offsetof(traffic_selector_t, destroy)); diff --git a/src/libcharon/plugins/ha/ha_message.c b/src/libcharon/plugins/ha/ha_message.c index 42dfaf0e2..5f73b7156 100644 --- a/src/libcharon/plugins/ha/ha_message.c +++ b/src/libcharon/plugins/ha/ha_message.c @@ -331,10 +331,12 @@ typedef struct { } attribute_enumerator_t; METHOD(enumerator_t, attribute_enumerate, bool, - attribute_enumerator_t *this, ha_message_attribute_t *attr_out, - ha_message_value_t *value) + attribute_enumerator_t *this, va_list args) { - ha_message_attribute_t attr; + ha_message_attribute_t attr, *attr_out; + ha_message_value_t *value; + + VA_ARGS_VGET(args, attr_out, value); if (this->cleanup) { @@ -602,7 +604,8 @@ METHOD(ha_message_t, create_attribute_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_attribute_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _attribute_enumerate, .destroy = _enum_destroy, }, .buf = chunk_skip(this->buf, 2), diff --git a/src/libcharon/plugins/ha/ha_tunnel.c b/src/libcharon/plugins/ha/ha_tunnel.c index a0e514614..1a6108ed9 100644 --- a/src/libcharon/plugins/ha/ha_tunnel.c +++ b/src/libcharon/plugins/ha/ha_tunnel.c @@ -111,8 +111,12 @@ typedef struct { } shared_enum_t; METHOD(enumerator_t, shared_enumerate, bool, - shared_enum_t *this, shared_key_t **key, id_match_t *me, id_match_t *other) + shared_enum_t *this, va_list args) { + shared_key_t **key; + id_match_t *me, *other; + + VA_ARGS_VGET(args, key, me, other); if (this->key) { if (me) @@ -151,7 +155,8 @@ METHOD(ha_creds_t, create_shared_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_shared_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _shared_enumerate, .destroy = (void*)free, }, .key = this->key, diff --git a/src/libcharon/plugins/ipseckey/Makefile.in b/src/libcharon/plugins/ipseckey/Makefile.in index 025a1a25e..02243e47c 100644 --- a/src/libcharon/plugins/ipseckey/Makefile.in +++ b/src/libcharon/plugins/ipseckey/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/ipseckey/ipseckey_cred.c b/src/libcharon/plugins/ipseckey/ipseckey_cred.c index ff50d8a17..b3ac2b328 100644 --- a/src/libcharon/plugins/ipseckey/ipseckey_cred.c +++ b/src/libcharon/plugins/ipseckey/ipseckey_cred.c @@ -62,13 +62,16 @@ typedef struct { } cert_enumerator_t; METHOD(enumerator_t, cert_enumerator_enumerate, bool, - cert_enumerator_t *this, certificate_t **cert) + cert_enumerator_t *this, va_list args) { + certificate_t **cert; ipseckey_t *cur_ipseckey; public_key_t *public; rr_t *cur_rr; chunk_t key; + VA_ARGS_VGET(args, cert); + /* Get the next supported IPSECKEY using the inner enumerator. */ while (this->inner->enumerate(this->inner, &cur_rr)) { @@ -211,7 +214,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_cert_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _cert_enumerator_enumerate, .destroy = _cert_enumerator_destroy, }, .inner = rrset->create_rr_enumerator(rrset), diff --git a/src/libcharon/plugins/kernel_iph/Makefile.in b/src/libcharon/plugins/kernel_iph/Makefile.in index fb8e42ee6..d9c172c1d 100644 --- a/src/libcharon/plugins/kernel_iph/Makefile.in +++ b/src/libcharon/plugins/kernel_iph/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/kernel_iph/kernel_iph_net.c b/src/libcharon/plugins/kernel_iph/kernel_iph_net.c index efeb98045..18a87b707 100644 --- a/src/libcharon/plugins/kernel_iph/kernel_iph_net.c +++ b/src/libcharon/plugins/kernel_iph/kernel_iph_net.c @@ -466,9 +466,12 @@ typedef struct { } addr_enumerator_t; METHOD(enumerator_t, addr_enumerate, bool, - addr_enumerator_t *this, host_t **host) + addr_enumerator_t *this, va_list args) { iface_t *entry; + host_t **host; + + VA_ARGS_VGET(args, host); while (TRUE) { @@ -523,7 +526,8 @@ METHOD(kernel_net_t, create_address_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_addr_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _addr_enumerate, .destroy = _addr_destroy, }, .which = which, diff --git a/src/libcharon/plugins/kernel_libipsec/Makefile.in b/src/libcharon/plugins/kernel_libipsec/Makefile.in index 4d5e46033..9f1a490cf 100644 --- a/src/libcharon/plugins/kernel_libipsec/Makefile.in +++ b/src/libcharon/plugins/kernel_libipsec/Makefile.in @@ -360,6 +360,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -382,6 +383,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c index 77e37e249..d4832e233 100644 --- a/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c +++ b/src/libcharon/plugins/kernel_libipsec/kernel_libipsec_ipsec.c @@ -84,12 +84,12 @@ static void exclude_route_destroy(exclude_route_t *this) free(this); } -/** - * Find an exclude route entry by destination address - */ -static bool exclude_route_match(exclude_route_t *current, - host_t *dst) +CALLBACK(exclude_route_match, bool, + exclude_route_t *current, va_list args) { + host_t *dst; + + VA_ARGS_VGET(args, dst); return dst->ip_equals(dst, current->dst); } @@ -204,12 +204,12 @@ static void policy_entry_destroy(policy_entry_t *this) free(this); } -/** - * Compare two policy_entry_t objects - */ -static inline bool policy_entry_equals(policy_entry_t *a, - policy_entry_t *b) +CALLBACK(policy_entry_equals, bool, + policy_entry_t *a, va_list args) { + policy_entry_t *b; + + VA_ARGS_VGET(args, b); return a->direction == b->direction && a->src.proto == b->src.proto && a->dst.proto == b->dst.proto && @@ -297,9 +297,8 @@ static void add_exclude_route(private_kernel_libipsec_ipsec_t *this, exclude_route_t *exclude; host_t *gtw; - if (this->excludes->find_first(this->excludes, - (linked_list_match_t)exclude_route_match, - (void**)&exclude, dst) == SUCCESS) + if (this->excludes->find_first(this->excludes, exclude_route_match, + (void**)&exclude, dst)) { route->exclude = exclude; exclude->refs++; @@ -524,9 +523,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t, policy = create_policy_entry(id->src_ts, id->dst_ts, id->dir); this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, - (linked_list_match_t)policy_entry_equals, - (void**)&found, policy) == SUCCESS) + if (this->policies->find_first(this->policies, policy_entry_equals, + (void**)&found, policy)) { policy_entry_destroy(policy); policy = found; @@ -567,9 +565,8 @@ METHOD(kernel_ipsec_t, del_policy, status_t, policy = create_policy_entry(id->src_ts, id->dst_ts, id->dir); this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, - (linked_list_match_t)policy_entry_equals, - (void**)&found, policy) != SUCCESS) + if (!this->policies->find_first(this->policies, policy_entry_equals, + (void**)&found, policy)) { policy_entry_destroy(policy); this->mutex->unlock(this->mutex); diff --git a/src/libcharon/plugins/kernel_netlink/Makefile.in b/src/libcharon/plugins/kernel_netlink/Makefile.in index 26a7090b3..7f25c5202 100644 --- a/src/libcharon/plugins/kernel_netlink/Makefile.in +++ b/src/libcharon/plugins/kernel_netlink/Makefile.in @@ -397,6 +397,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -419,6 +420,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c index becf6b5dc..c411b829d 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -78,9 +78,6 @@ /** Base priority for installed policies */ #define PRIO_BASE 200000 -/** Default lifetime of an acquire XFRM state (in seconds) */ -#define DEFAULT_ACQUIRE_LIFETIME 165 - /** * Map the limit for bytes and packets to XFRM_INF by default */ @@ -545,10 +542,10 @@ static policy_sa_t *policy_sa_create(private_kernel_netlink_ipsec_t *this, /** * Destroy a policy_sa(_in)_t object */ -static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t *dir, +static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t dir, private_kernel_netlink_ipsec_t *this) { - if (*dir == POLICY_OUT) + if (dir == POLICY_OUT) { policy_sa_out_t *out = (policy_sa_out_t*)policy; out->src_ts->destroy(out->src_ts); @@ -558,6 +555,16 @@ static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t *dir, free(policy); } +CALLBACK(policy_sa_destroy_cb, void, + policy_sa_t *policy, va_list args) +{ + private_kernel_netlink_ipsec_t *this; + policy_dir_t dir; + + VA_ARGS_VGET(args, dir, this); + policy_sa_destroy(policy, dir, this); +} + typedef struct policy_entry_t policy_entry_t; /** @@ -602,9 +609,8 @@ static void policy_entry_destroy(private_kernel_netlink_ipsec_t *this, } if (policy->used_by) { - policy->used_by->invoke_function(policy->used_by, - (linked_list_invoke_t)policy_sa_destroy, - &policy->direction, this); + policy->used_by->invoke_function(policy->used_by, policy_sa_destroy_cb, + policy->direction, this); policy->used_by->destroy(policy->used_by); } free(policy); @@ -1639,12 +1645,46 @@ METHOD(kernel_ipsec_t, add_sa, status_t, data->replay_window); sa->replay_window = data->replay_window; } + if (data->hw_offload) + { + host_t *local = data->inbound ? id->dst : id->src; + char *ifname; + + if (charon->kernel->get_interface(charon->kernel, local, &ifname)) + { + struct xfrm_user_offload *offload; + + offload = netlink_reserve(hdr, sizeof(request), + XFRMA_OFFLOAD_DEV, sizeof(*offload)); + if (!offload) + { + free(ifname); + goto failed; + } + offload->ifindex = if_nametoindex(ifname); + if (local->get_family(local) == AF_INET6) + { + offload->flags |= XFRM_OFFLOAD_IPV6; + } + offload->flags |= data->inbound ? XFRM_OFFLOAD_INBOUND : 0; + free(ifname); + } + } } - if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS) + status = this->socket_xfrm->send_ack(this->socket_xfrm, hdr); + if (status == NOT_FOUND && data->update) { - DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x%s", ntohl(id->spi), - markstr); + DBG1(DBG_KNL, "allocated SPI not found anymore, try to add SAD entry"); + hdr->nlmsg_type = XFRM_MSG_NEWSA; + status = this->socket_xfrm->send_ack(this->socket_xfrm, hdr); + } + + if (status != SUCCESS) + { + DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x%s (%N)", ntohl(id->spi), + markstr, status_names, status); + status = FAILED; goto failed; } @@ -1919,13 +1959,13 @@ METHOD(kernel_ipsec_t, update_sa, status_t, kernel_ipsec_update_sa_t *data) { netlink_buf_t request; - struct nlmsghdr *hdr, *out = NULL; + struct nlmsghdr *hdr, *out_hdr = NULL, *out = NULL; struct xfrm_usersa_id *sa_id; - struct xfrm_usersa_info *out_sa = NULL, *sa; + struct xfrm_usersa_info *sa; size_t len; struct rtattr *rta; size_t rtasize; - struct xfrm_encap_tmpl* tmpl = NULL; + struct xfrm_encap_tmpl* encap = NULL; struct xfrm_replay_state *replay = NULL; struct xfrm_replay_state_esn *replay_esn = NULL; struct xfrm_lifetime_cur *lifetime = NULL; @@ -1983,7 +2023,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t, { case XFRM_MSG_NEWSA: { - out_sa = NLMSG_DATA(hdr); + out_hdr = hdr; break; } case NLMSG_ERROR: @@ -2002,7 +2042,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t, break; } } - if (out_sa == NULL) + if (!out_hdr) { DBG1(DBG_KNL, "unable to update SAD entry with SPI %.8x%s", ntohl(id->spi), markstr); @@ -2029,7 +2069,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t, hdr->nlmsg_type = XFRM_MSG_NEWSA; hdr->nlmsg_len = NLMSG_LENGTH(sizeof(struct xfrm_usersa_info)); sa = NLMSG_DATA(hdr); - memcpy(sa, NLMSG_DATA(out), sizeof(struct xfrm_usersa_info)); + memcpy(sa, NLMSG_DATA(out_hdr), sizeof(struct xfrm_usersa_info)); sa->family = data->new_dst->get_family(data->new_dst); if (!id->src->ip_equals(id->src, data->new_src)) @@ -2041,8 +2081,8 @@ METHOD(kernel_ipsec_t, update_sa, status_t, host2xfrm(data->new_dst, &sa->id.daddr); } - rta = XFRM_RTA(out, struct xfrm_usersa_info); - rtasize = XFRM_PAYLOAD(out, struct xfrm_usersa_info); + rta = XFRM_RTA(out_hdr, struct xfrm_usersa_info); + rtasize = XFRM_PAYLOAD(out_hdr, struct xfrm_usersa_info); while (RTA_OK(rta, rtasize)) { /* copy all attributes, but not XFRMA_ENCAP if we are disabling it */ @@ -2050,9 +2090,34 @@ METHOD(kernel_ipsec_t, update_sa, status_t, { if (rta->rta_type == XFRMA_ENCAP) { /* update encap tmpl */ - tmpl = RTA_DATA(rta); - tmpl->encap_sport = ntohs(data->new_src->get_port(data->new_src)); - tmpl->encap_dport = ntohs(data->new_dst->get_port(data->new_dst)); + encap = RTA_DATA(rta); + encap->encap_sport = ntohs(data->new_src->get_port(data->new_src)); + encap->encap_dport = ntohs(data->new_dst->get_port(data->new_dst)); + } + if (rta->rta_type == XFRMA_OFFLOAD_DEV) + { /* update offload device */ + struct xfrm_user_offload *offload; + host_t *local; + char *ifname; + + offload = RTA_DATA(rta); + local = offload->flags & XFRM_OFFLOAD_INBOUND ? data->new_dst + : data->new_src; + + if (charon->kernel->get_interface(charon->kernel, local, + &ifname)) + { + offload->ifindex = if_nametoindex(ifname); + if (local->get_family(local) == AF_INET6) + { + offload->flags |= XFRM_OFFLOAD_IPV6; + } + else + { + offload->flags &= ~XFRM_OFFLOAD_IPV6; + } + free(ifname); + } } netlink_add_attribute(hdr, rta->rta_type, chunk_create(RTA_DATA(rta), RTA_PAYLOAD(rta)), @@ -2061,17 +2126,18 @@ METHOD(kernel_ipsec_t, update_sa, status_t, rta = RTA_NEXT(rta, rtasize); } - if (tmpl == NULL && data->new_encap) + if (encap == NULL && data->new_encap) { /* add tmpl if we are enabling it */ - tmpl = netlink_reserve(hdr, sizeof(request), XFRMA_ENCAP, sizeof(*tmpl)); - if (!tmpl) + encap = netlink_reserve(hdr, sizeof(request), XFRMA_ENCAP, + sizeof(*encap)); + if (!encap) { goto failed; } - tmpl->encap_type = UDP_ENCAP_ESPINUDP; - tmpl->encap_sport = ntohs(data->new_src->get_port(data->new_src)); - tmpl->encap_dport = ntohs(data->new_dst->get_port(data->new_dst)); - memset(&tmpl->encap_oa, 0, sizeof (xfrm_address_t)); + encap->encap_type = UDP_ENCAP_ESPINUDP; + encap->encap_sport = ntohs(data->new_src->get_port(data->new_src)); + encap->encap_dport = ntohs(data->new_dst->get_port(data->new_dst)); + memset(&encap->encap_oa, 0, sizeof (xfrm_address_t)); } if (replay_esn) @@ -2711,7 +2777,7 @@ METHOD(kernel_ipsec_t, del_policy, status_t, ipsec_sa_equals(mapping->sa, &assigned_sa)) { current->used_by->remove_at(current->used_by, enumerator); - policy_sa_destroy(mapping, &id->dir, this); + policy_sa_destroy(mapping, id->dir, this); break; } if (is_installed) @@ -3171,7 +3237,6 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create() { private_kernel_netlink_ipsec_t *this; bool register_for_events = TRUE; - FILE *f; INIT(this, .public = { @@ -3216,15 +3281,6 @@ kernel_netlink_ipsec_t *kernel_netlink_ipsec_create() register_for_events = FALSE; } - f = fopen("/proc/sys/net/core/xfrm_acq_expires", "w"); - if (f) - { - fprintf(f, "%u", lib->settings->get_int(lib->settings, - "%s.plugins.kernel-netlink.xfrm_acq_expires", - DEFAULT_ACQUIRE_LIFETIME, lib->ns)); - fclose(f); - } - this->socket_xfrm = netlink_socket_create(NETLINK_XFRM, xfrm_msg_names, lib->settings->get_bool(lib->settings, "%s.plugins.kernel-netlink.parallel_xfrm", FALSE, lib->ns)); diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c index 2dc76d941..0dd3e30cb 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c @@ -163,19 +163,21 @@ static void iface_entry_destroy(iface_entry_t *this) free(this); } -/** - * find an interface entry by index - */ -static bool iface_entry_by_index(iface_entry_t *this, int *ifindex) +CALLBACK(iface_entry_by_index, bool, + iface_entry_t *this, va_list args) { - return this->ifindex == *ifindex; + int ifindex; + + VA_ARGS_VGET(args, ifindex); + return this->ifindex == ifindex; } -/** - * find an interface entry by name - */ -static bool iface_entry_by_name(iface_entry_t *this, char *ifname) +CALLBACK(iface_entry_by_name, bool, + iface_entry_t *this, va_list args) { + char *ifname; + + VA_ARGS_VGET(args, ifname); return streq(this->ifname, ifname); } @@ -1112,8 +1114,8 @@ static bool is_interface_up_and_usable(private_kernel_netlink_net_t *this, { iface_entry_t *iface; - if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_index, - (void**)&iface, &index) == SUCCESS) + if (this->ifaces->find_first(this->ifaces, iface_entry_by_index, + (void**)&iface, index)) { return iface_entry_up_and_usable(iface); } @@ -1125,9 +1127,13 @@ static bool is_interface_up_and_usable(private_kernel_netlink_net_t *this, * * this->lock must be locked when calling this function */ -static void addr_entry_unregister(addr_entry_t *addr, iface_entry_t *iface, - private_kernel_netlink_net_t *this) +CALLBACK(addr_entry_unregister, void, + addr_entry_t *addr, va_list args) { + private_kernel_netlink_net_t *this; + iface_entry_t *iface; + + VA_ARGS_VGET(args, iface, this); if (addr->refcount) { addr_map_entry_remove(this->vips, addr, iface); @@ -1171,9 +1177,8 @@ static void process_link(private_kernel_netlink_net_t *this, { case RTM_NEWLINK: { - if (this->ifaces->find_first(this->ifaces, - (void*)iface_entry_by_index, (void**)&entry, - &msg->ifi_index) != SUCCESS) + if (!this->ifaces->find_first(this->ifaces, iface_entry_by_index, + (void**)&entry, msg->ifi_index)) { INIT(entry, .ifindex = msg->ifi_index, @@ -1217,7 +1222,7 @@ static void process_link(private_kernel_netlink_net_t *this, * another interface? */ this->ifaces->remove_at(this->ifaces, enumerator); current->addrs->invoke_function(current->addrs, - (void*)addr_entry_unregister, current, this); + addr_entry_unregister, current, this); iface_entry_destroy(current); break; } @@ -1288,8 +1293,8 @@ static void process_addr(private_kernel_netlink_net_t *this, } this->lock->write_lock(this->lock); - if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_index, - (void**)&iface, &msg->ifa_index) == SUCCESS) + if (this->ifaces->find_first(this->ifaces, iface_entry_by_index, + (void**)&iface, msg->ifa_index)) { addr_map_entry_t *entry, lookup = { .ip = host, @@ -1518,35 +1523,39 @@ typedef struct { kernel_address_type_t which; } address_enumerator_t; -/** - * cleanup function for address enumerator - */ -static void address_enumerator_destroy(address_enumerator_t *data) +CALLBACK(address_enumerator_destroy, void, + address_enumerator_t *data) { data->this->lock->unlock(data->this->lock); free(data); } -/** - * filter for addresses - */ -static bool filter_addresses(address_enumerator_t *data, - addr_entry_t** in, host_t** out) +CALLBACK(filter_addresses, bool, + address_enumerator_t *data, enumerator_t *orig, va_list args) { - if (!(data->which & ADDR_TYPE_VIRTUAL) && (*in)->refcount) - { /* skip virtual interfaces added by us */ - return FALSE; - } - if (!(data->which & ADDR_TYPE_REGULAR) && !(*in)->refcount) - { /* address is regular, but not requested */ - return FALSE; - } - if ((*in)->scope >= RT_SCOPE_LINK) - { /* skip addresses with a unusable scope */ - return FALSE; + addr_entry_t *addr; + host_t **out; + + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, &addr)) + { + if (!(data->which & ADDR_TYPE_VIRTUAL) && addr->refcount) + { /* skip virtual interfaces added by us */ + continue; + } + if (!(data->which & ADDR_TYPE_REGULAR) && !addr->refcount) + { /* address is regular, but not requested */ + continue; + } + if (addr->scope >= RT_SCOPE_LINK) + { /* skip addresses with a unusable scope */ + continue; + } + *out = addr->ip; + return TRUE; } - *out = (*in)->ip; - return TRUE; + return FALSE; } /** @@ -1556,30 +1565,35 @@ static enumerator_t *create_iface_enumerator(iface_entry_t *iface, address_enumerator_t *data) { return enumerator_create_filter( - iface->addrs->create_enumerator(iface->addrs), - (void*)filter_addresses, data, NULL); + iface->addrs->create_enumerator(iface->addrs), + filter_addresses, data, NULL); } -/** - * filter for interfaces - */ -static bool filter_interfaces(address_enumerator_t *data, iface_entry_t** in, - iface_entry_t** out) +CALLBACK(filter_interfaces, bool, + address_enumerator_t *data, enumerator_t *orig, va_list args) { - if (!(data->which & ADDR_TYPE_IGNORED) && !(*in)->usable) - { /* skip interfaces excluded by config */ - return FALSE; - } - if (!(data->which & ADDR_TYPE_LOOPBACK) && ((*in)->flags & IFF_LOOPBACK)) - { /* ignore loopback devices */ - return FALSE; - } - if (!(data->which & ADDR_TYPE_DOWN) && !((*in)->flags & IFF_UP)) - { /* skip interfaces not up */ - return FALSE; + iface_entry_t *iface, **out; + + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, &iface)) + { + if (!(data->which & ADDR_TYPE_IGNORED) && !iface->usable) + { /* skip interfaces excluded by config */ + continue; + } + if (!(data->which & ADDR_TYPE_LOOPBACK) && (iface->flags & IFF_LOOPBACK)) + { /* ignore loopback devices */ + continue; + } + if (!(data->which & ADDR_TYPE_DOWN) && !(iface->flags & IFF_UP)) + { /* skip interfaces not up */ + continue; + } + *out = iface; + return TRUE; } - *out = *in; - return TRUE; + return FALSE; } METHOD(kernel_net_t, create_address_enumerator, enumerator_t*, @@ -1596,9 +1610,9 @@ METHOD(kernel_net_t, create_address_enumerator, enumerator_t*, return enumerator_create_nested( enumerator_create_filter( this->ifaces->create_enumerator(this->ifaces), - (void*)filter_interfaces, data, NULL), + filter_interfaces, data, NULL), (void*)create_iface_enumerator, data, - (void*)address_enumerator_destroy); + address_enumerator_destroy); } METHOD(kernel_net_t, get_interface_name, bool, @@ -1661,8 +1675,8 @@ static int get_interface_index(private_kernel_netlink_net_t *this, char* name) DBG2(DBG_KNL, "getting iface index for %s", name); this->lock->read_lock(this->lock); - if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_name, - (void**)&iface, name) == SUCCESS) + if (this->ifaces->find_first(this->ifaces, iface_entry_by_name, + (void**)&iface, name)) { ifindex = iface->ifindex; } @@ -1687,8 +1701,8 @@ static char *get_interface_name_by_index(private_kernel_netlink_net_t *this, DBG2(DBG_KNL, "getting iface name for index %d", index); this->lock->read_lock(this->lock); - if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_index, - (void**)&iface, &index) == SUCCESS) + if (this->ifaces->find_first(this->ifaces, iface_entry_by_index, + (void**)&iface, index)) { name = strdup(iface->ifname); } @@ -1928,7 +1942,7 @@ static host_t *get_route(private_kernel_netlink_net_t *this, host_t *dest, table = (uintptr_t)route->table; if (this->rt_exclude->find_first(this->rt_exclude, NULL, - (void**)&table) == SUCCESS) + (void**)&table)) { /* route is from an excluded routing table */ continue; } @@ -2165,8 +2179,14 @@ METHOD(enumerator_t, destroy_subnet_enumerator, void, } METHOD(enumerator_t, enumerate_subnets, bool, - subnet_enumerator_t *this, host_t **net, uint8_t *mask, char **ifname) + subnet_enumerator_t *this, va_list args) { + host_t **net; + uint8_t *mask; + char **ifname; + + VA_ARGS_VGET(args, net, mask, ifname); + if (!this->current) { this->current = this->msg; @@ -2270,7 +2290,8 @@ METHOD(kernel_net_t, create_local_subnet_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_enumerate_subnets, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_subnets, .destroy = _destroy_subnet_enumerator, }, .private = this, @@ -2380,11 +2401,11 @@ METHOD(kernel_net_t, add_ip, status_t, } /* try to find the target interface, either by config or via src ip */ if (!this->install_virtual_ip_on || - this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_name, - (void**)&iface, this->install_virtual_ip_on) != SUCCESS) + !this->ifaces->find_first(this->ifaces, iface_entry_by_name, + (void**)&iface, this->install_virtual_ip_on)) { - if (this->ifaces->find_first(this->ifaces, (void*)iface_entry_by_name, - (void**)&iface, iface_name) != SUCCESS) + if (!this->ifaces->find_first(this->ifaces, iface_entry_by_name, + (void**)&iface, iface_name)) { /* if we don't find the requested interface we just use the first */ this->ifaces->get_first(this->ifaces, (void**)&iface); } diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.c index 8bafc3c55..58350028f 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_plugin.c @@ -19,6 +19,8 @@ #include "kernel_netlink_ipsec.h" #include "kernel_netlink_net.h" +#include <sa/task_manager.h> + typedef struct private_kernel_netlink_plugin_t private_kernel_netlink_plugin_t; /** @@ -50,6 +52,24 @@ METHOD(plugin_t, get_features, int, return countof(f); } +METHOD(plugin_t, reload, bool, + private_kernel_netlink_plugin_t *this) +{ + u_int timeout; + FILE *f; + + f = fopen("/proc/sys/net/core/xfrm_acq_expires", "w"); + if (f) + { + timeout = lib->settings->get_int(lib->settings, + "%s.plugins.kernel-netlink.xfrm_acq_expires", + task_manager_total_retransmit_timeout(), lib->ns); + fprintf(f, "%u", timeout); + fclose(f); + } + return TRUE; +} + METHOD(plugin_t, destroy, void, private_kernel_netlink_plugin_t *this) { @@ -76,10 +96,13 @@ plugin_t *kernel_netlink_plugin_create() .plugin = { .get_name = _get_name, .get_features = _get_features, + .reload = _reload, .destroy = _destroy, }, }, ); + reload(this); + return &this->public.plugin; } diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c index da54031a1..cf85cb0a6 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_shared.c @@ -333,7 +333,8 @@ static status_t send_once(private_netlink_socket_t *this, struct nlmsghdr *in, while (!entry->complete) { if (this->parallel && - lib->watcher->get_state(lib->watcher) != WATCHER_STOPPED) + lib->watcher->get_state(lib->watcher) != WATCHER_STOPPED && + lib->processor->get_total_threads(lib->processor)) { if (this->timeout) { diff --git a/src/libcharon/plugins/kernel_pfkey/Makefile.in b/src/libcharon/plugins/kernel_pfkey/Makefile.in index b138a9603..b27408a3f 100644 --- a/src/libcharon/plugins/kernel_pfkey/Makefile.in +++ b/src/libcharon/plugins/kernel_pfkey/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c index 17878147b..fd1adb2ae 100644 --- a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c +++ b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c @@ -464,10 +464,10 @@ static policy_sa_t *policy_sa_create(private_kernel_pfkey_ipsec_t *this, /** * Destroy a policy_sa(_in)_t object */ -static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t *dir, +static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t dir, private_kernel_pfkey_ipsec_t *this) { - if (*dir == POLICY_OUT) + if (dir == POLICY_OUT) { policy_sa_out_t *out = (policy_sa_out_t*)policy; out->src_ts->destroy(out->src_ts); @@ -477,6 +477,16 @@ static void policy_sa_destroy(policy_sa_t *policy, policy_dir_t *dir, free(policy); } +CALLBACK(policy_sa_destroy_cb, void, + policy_sa_t *policy, va_list args) +{ + private_kernel_pfkey_ipsec_t *this; + policy_dir_t dir; + + VA_ARGS_VGET(args, dir, this); + policy_sa_destroy(policy, dir, this); +} + typedef struct policy_entry_t policy_entry_t; /** @@ -557,9 +567,8 @@ static void policy_entry_destroy(policy_entry_t *policy, } if (policy->used_by) { - policy->used_by->invoke_function(policy->used_by, - (linked_list_invoke_t)policy_sa_destroy, - &policy->direction, this); + policy->used_by->invoke_function(policy->used_by, policy_sa_destroy_cb, + policy->direction, this); policy->used_by->destroy(policy->used_by); } DESTROY_IF(policy->src.net); @@ -567,12 +576,21 @@ static void policy_entry_destroy(policy_entry_t *policy, free(policy); } -/** - * compares two policy_entry_t - */ -static inline bool policy_entry_equals(policy_entry_t *current, - policy_entry_t *policy) +CALLBACK(policy_entry_destroy_cb, void, + policy_entry_t *policy, va_list args) { + private_kernel_pfkey_ipsec_t *this; + + VA_ARGS_VGET(args, this); + policy_entry_destroy(policy, this); +} + +CALLBACK(policy_entry_equals, bool, + policy_entry_t *current, va_list args) +{ + policy_entry_t *policy; + + VA_ARGS_VGET(args, policy); return current->direction == policy->direction && current->src.proto == policy->src.proto && current->dst.proto == policy->dst.proto && @@ -582,13 +600,13 @@ static inline bool policy_entry_equals(policy_entry_t *current, current->dst.net->equals(current->dst.net, policy->dst.net); } -/** - * compare the given kernel index with that of a policy - */ -static inline bool policy_entry_match_byindex(policy_entry_t *current, - uint32_t *index) +CALLBACK(policy_entry_match_byindex, bool, + policy_entry_t *current, va_list args) { - return current->index == *index; + uint32_t index; + + VA_ARGS_VGET(args, index); + return current->index == index; } /** @@ -999,24 +1017,6 @@ static void add_addr_ext(struct sadb_msg *msg, host_t *host, uint16_t type, PFKEY_EXT_ADD(msg, addr); } -/** - * adds an empty address extension to the given sadb_msg - */ -static void add_anyaddr_ext(struct sadb_msg *msg, int family, uint8_t type) -{ - socklen_t len = (family == AF_INET) ? sizeof(struct sockaddr_in) : - sizeof(struct sockaddr_in6); - struct sadb_address *addr = (struct sadb_address*)PFKEY_EXT_ADD_NEXT(msg); - addr->sadb_address_exttype = type; - sockaddr_t *saddr = (sockaddr_t*)(addr + 1); - saddr->sa_family = family; -#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - saddr->sa_len = len; -#endif - addr->sadb_address_len = PFKEY_LEN(sizeof(*addr) + len); - PFKEY_EXT_ADD(msg, addr); -} - #ifdef HAVE_NATT /** * add udp encap extensions to a sadb_msg @@ -1279,9 +1279,8 @@ static void process_acquire(private_kernel_pfkey_ipsec_t *this, index = response.x_policy->sadb_x_policy_id; this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, - (linked_list_match_t)policy_entry_match_byindex, - (void**)&policy, &index) == SUCCESS && + if (this->policies->find_first(this->policies, policy_entry_match_byindex, + (void**)&policy, index) && policy->used_by->get_first(policy->used_by, (void**)&sa) == SUCCESS) { reqid = sa->sa->cfg.reqid; @@ -1854,6 +1853,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t, pfkey_msg_t response; size_t len; +#ifndef SADB_X_EXT_NEW_ADDRESS_SRC /* we can't update the SA if any of the ip addresses have changed. * that's because we can't use SADB_UPDATE and by deleting and readding the * SA the sequence numbers would get lost */ @@ -1864,6 +1864,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t, "changes are not supported", ntohl(id->spi)); return NOT_SUPPORTED; } +#endif /*SADB_X_EXT_NEW_ADDRESS_SRC*/ /* if IPComp is used, we first update the IPComp SA */ if (data->cpi) @@ -1900,9 +1901,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t, sa->sadb_sa_state = SADB_SASTATE_MATURE; PFKEY_EXT_ADD(msg, sa); - /* the kernel wants a SADB_EXT_ADDRESS_SRC to be present even though - * it is not used for anything. */ - add_anyaddr_ext(msg, id->dst->get_family(id->dst), SADB_EXT_ADDRESS_SRC); + add_addr_ext(msg, id->src, SADB_EXT_ADDRESS_SRC, 0, 0, FALSE); add_addr_ext(msg, id->dst, SADB_EXT_ADDRESS_DST, 0, 0, FALSE); if (pfkey_send(this, msg, &out, &len) != SUCCESS) @@ -1944,7 +1943,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t, sa_2 = (struct sadb_sa_2*)PFKEY_EXT_ADD_NEXT(msg); sa_2->sa.sadb_sa_len = PFKEY_LEN(sizeof(struct sadb_sa_2)); memcpy(&sa_2->sa, response.sa, sizeof(struct sadb_sa)); - if (data->encap) + if (data->new_encap) { sa_2->sadb_sa_natt_port = data->new_dst->get_port(data->new_dst); sa_2->sa.sadb_sa_flags |= SADB_X_EXT_NATT; @@ -1978,6 +1977,19 @@ METHOD(kernel_ipsec_t, update_sa, status_t, } #endif /*HAVE_NATT*/ +#ifdef SADB_X_EXT_NEW_ADDRESS_SRC + if (!id->src->ip_equals(id->src, data->new_src)) + { + add_addr_ext(msg, data->new_src, SADB_X_EXT_NEW_ADDRESS_SRC, 0, 0, + FALSE); + } + if (!id->dst->ip_equals(id->dst, data->new_dst)) + { + add_addr_ext(msg, data->new_dst, SADB_X_EXT_NEW_ADDRESS_DST, 0, 0, + FALSE); + } +#endif /*SADB_X_EXT_NEW_ADDRESS_SRC*/ + free(out); if (pfkey_send(this, msg, &out, &len) != SUCCESS) @@ -2559,8 +2571,7 @@ static status_t add_policy_internal(private_kernel_pfkey_ipsec_t *this, /* we try to find the policy again and update the kernel index */ this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, NULL, - (void**)&policy) != SUCCESS) + if (!this->policies->find_first(this->policies, NULL, (void**)&policy)) { DBG2(DBG_KNL, "unable to update index, the policy is already gone, " "ignoring"); @@ -2611,9 +2622,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t, /* find a matching policy */ this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, - (linked_list_match_t)policy_entry_equals, - (void**)&found, policy) == SUCCESS) + if (this->policies->find_first(this->policies, policy_entry_equals, + (void**)&found, policy)) { /* use existing policy */ DBG2(DBG_KNL, "policy %R === %R %N already exists, increasing " "refcount", id->src_ts, id->dst_ts, policy_dir_names, id->dir); @@ -2706,9 +2716,8 @@ METHOD(kernel_ipsec_t, query_policy, status_t, /* find a matching policy */ this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, - (linked_list_match_t)policy_entry_equals, - (void**)&found, policy) != SUCCESS) + if (!this->policies->find_first(this->policies, policy_entry_equals, + (void**)&found, policy)) { DBG1(DBG_KNL, "querying policy %R === %R %N failed, not found", id->src_ts, id->dst_ts, policy_dir_names, id->dir); @@ -2819,9 +2828,8 @@ METHOD(kernel_ipsec_t, del_policy, status_t, /* find a matching policy */ this->mutex->lock(this->mutex); - if (this->policies->find_first(this->policies, - (linked_list_match_t)policy_entry_equals, - (void**)&found, policy) != SUCCESS) + if (!this->policies->find_first(this->policies, policy_entry_equals, + (void**)&found, policy)) { DBG1(DBG_KNL, "deleting policy %R === %R %N failed, not found", id->src_ts, id->dst_ts, policy_dir_names, id->dir); @@ -2865,7 +2873,7 @@ METHOD(kernel_ipsec_t, del_policy, status_t, if (policy->used_by->get_count(policy->used_by) > 0) { /* policy is used by more SAs, keep in kernel */ DBG2(DBG_KNL, "policy still used by another CHILD_SA, not removed"); - policy_sa_destroy(mapping, &id->dir, this); + policy_sa_destroy(mapping, id->dir, this); if (!is_installed) { /* no need to update as the policy was not installed for this SA */ @@ -2920,7 +2928,7 @@ METHOD(kernel_ipsec_t, del_policy, status_t, } this->policies->remove(this->policies, found, NULL); - policy_sa_destroy(mapping, &id->dir, this); + policy_sa_destroy(mapping, id->dir, this); policy_entry_destroy(policy, this); this->mutex->unlock(this->mutex); @@ -3093,8 +3101,7 @@ METHOD(kernel_ipsec_t, destroy, void, lib->watcher->remove(lib->watcher, this->socket_events); close(this->socket_events); } - this->policies->invoke_function(this->policies, - (linked_list_invoke_t)policy_entry_destroy, + this->policies->invoke_function(this->policies, policy_entry_destroy_cb, this); this->policies->destroy(this->policies); this->excludes->destroy(this->excludes); diff --git a/src/libcharon/plugins/kernel_pfroute/Makefile.in b/src/libcharon/plugins/kernel_pfroute/Makefile.in index 1e4b3e207..e7005bbff 100644 --- a/src/libcharon/plugins/kernel_pfroute/Makefile.in +++ b/src/libcharon/plugins/kernel_pfroute/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c index efcf1c2a7..6d06ee179 100644 --- a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c +++ b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c @@ -601,9 +601,12 @@ typedef struct { } rt_enumerator_t; METHOD(enumerator_t, rt_enumerate, bool, - rt_enumerator_t *this, int *xtype, struct sockaddr **addr) + rt_enumerator_t *this, va_list args) { - int i, type; + struct sockaddr **addr; + int i, type, *xtype; + + VA_ARGS_VGET(args, xtype, addr); if (this->remaining < sizeof(this->addr->sa_len) || this->remaining < this->addr->sa_len) @@ -637,7 +640,8 @@ static enumerator_t *create_rt_enumerator(int types, int remaining, INIT(this, .public = { - .enumerate = (void*)_rt_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _rt_enumerate, .destroy = (void*)free, }, .types = types, @@ -1050,41 +1054,45 @@ typedef struct { kernel_address_type_t which; } address_enumerator_t; -/** - * cleanup function for address enumerator - */ -static void address_enumerator_destroy(address_enumerator_t *data) +CALLBACK(address_enumerator_destroy, void, + address_enumerator_t *data) { data->this->lock->unlock(data->this->lock); free(data); } -/** - * filter for addresses - */ -static bool filter_addresses(address_enumerator_t *data, - addr_entry_t** in, host_t** out) +CALLBACK(filter_addresses, bool, + address_enumerator_t *data, enumerator_t *orig, va_list args) { - host_t *ip; - if (!(data->which & ADDR_TYPE_VIRTUAL) && (*in)->virtual) - { /* skip virtual interfaces added by us */ - return FALSE; - } - if (!(data->which & ADDR_TYPE_REGULAR) && !(*in)->virtual) - { /* address is regular, but not requested */ - return FALSE; - } - ip = (*in)->ip; - if (ip->get_family(ip) == AF_INET6) + addr_entry_t *addr; + host_t *ip, **out; + struct sockaddr_in6 *sin6; + + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, &addr)) { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ip->get_sockaddr(ip); - if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) - { /* skip addresses with a unusable scope */ - return FALSE; + if (!(data->which & ADDR_TYPE_VIRTUAL) && addr->virtual) + { /* skip virtual interfaces added by us */ + continue; } + if (!(data->which & ADDR_TYPE_REGULAR) && !addr->virtual) + { /* address is regular, but not requested */ + continue; + } + ip = addr->ip; + if (ip->get_family(ip) == AF_INET6) + { + sin6 = (struct sockaddr_in6 *)ip->get_sockaddr(ip); + if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) + { /* skip addresses with a unusable scope */ + continue; + } + } + *out = ip; + return TRUE; } - *out = ip; - return TRUE; + return FALSE; } /** @@ -1094,29 +1102,34 @@ static enumerator_t *create_iface_enumerator(iface_entry_t *iface, address_enumerator_t *data) { return enumerator_create_filter(iface->addrs->create_enumerator(iface->addrs), - (void*)filter_addresses, data, NULL); + filter_addresses, data, NULL); } -/** - * filter for interfaces - */ -static bool filter_interfaces(address_enumerator_t *data, iface_entry_t** in, - iface_entry_t** out) +CALLBACK(filter_interfaces, bool, + address_enumerator_t *data, enumerator_t *orig, va_list args) { - if (!(data->which & ADDR_TYPE_IGNORED) && !(*in)->usable) - { /* skip interfaces excluded by config */ - return FALSE; - } - if (!(data->which & ADDR_TYPE_LOOPBACK) && ((*in)->flags & IFF_LOOPBACK)) - { /* ignore loopback devices */ - return FALSE; - } - if (!(data->which & ADDR_TYPE_DOWN) && !((*in)->flags & IFF_UP)) - { /* skip interfaces not up */ - return FALSE; + iface_entry_t *iface, **out; + + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, &iface)) + { + if (!(data->which & ADDR_TYPE_IGNORED) && !iface->usable) + { /* skip interfaces excluded by config */ + continue; + } + if (!(data->which & ADDR_TYPE_LOOPBACK) && (iface->flags & IFF_LOOPBACK)) + { /* ignore loopback devices */ + continue; + } + if (!(data->which & ADDR_TYPE_DOWN) && !(iface->flags & IFF_UP)) + { /* skip interfaces not up */ + continue; + } + *out = iface; + return TRUE; } - *out = *in; - return TRUE; + return FALSE; } METHOD(kernel_net_t, create_address_enumerator, enumerator_t*, @@ -1133,9 +1146,9 @@ METHOD(kernel_net_t, create_address_enumerator, enumerator_t*, return enumerator_create_nested( enumerator_create_filter( this->ifaces->create_enumerator(this->ifaces), - (void*)filter_interfaces, data, NULL), + filter_interfaces, data, NULL), (void*)create_iface_enumerator, data, - (void*)address_enumerator_destroy); + address_enumerator_destroy); } METHOD(kernel_net_t, get_features, kernel_feature_t, @@ -1789,13 +1802,18 @@ METHOD(enumerator_t, destroy_subnet_enumerator, void, } METHOD(enumerator_t, enumerate_subnets, bool, - subnet_enumerator_t *this, host_t **net, uint8_t *mask, char **ifname) + subnet_enumerator_t *this, va_list args) { enumerator_t *enumerator; + host_t **net; struct rt_msghdr *rtm; struct sockaddr *addr; + uint8_t *mask; + char **ifname; int type; + VA_ARGS_VGET(args, net, mask, ifname); + if (!this->current) { this->current = this->buf; @@ -1888,7 +1906,8 @@ METHOD(kernel_net_t, create_local_subnet_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_enumerate_subnets, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_subnets, .destroy = _destroy_subnet_enumerator, }, .buf = buf, diff --git a/src/libcharon/plugins/kernel_wfp/Makefile.in b/src/libcharon/plugins/kernel_wfp/Makefile.in index a3368d56f..ffdae84c0 100644 --- a/src/libcharon/plugins/kernel_wfp/Makefile.in +++ b/src/libcharon/plugins/kernel_wfp/Makefile.in @@ -366,6 +366,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -388,6 +389,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/led/Makefile.in b/src/libcharon/plugins/led/Makefile.in index f16304dbc..7f820292d 100644 --- a/src/libcharon/plugins/led/Makefile.in +++ b/src/libcharon/plugins/led/Makefile.in @@ -355,6 +355,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -377,6 +378,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/load_tester/Makefile.in b/src/libcharon/plugins/load_tester/Makefile.in index c6e17fb83..c55e3578c 100644 --- a/src/libcharon/plugins/load_tester/Makefile.in +++ b/src/libcharon/plugins/load_tester/Makefile.in @@ -368,6 +368,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -390,6 +391,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/load_tester/load_tester_creds.c b/src/libcharon/plugins/load_tester/load_tester_creds.c index 2f482962a..2cedd130e 100644 --- a/src/libcharon/plugins/load_tester/load_tester_creds.c +++ b/src/libcharon/plugins/load_tester/load_tester_creds.c @@ -395,22 +395,28 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, return NULL; } -/** - * Filter function for shared keys, returning ID matches - */ -static bool shared_filter(void *null, shared_key_t **in, shared_key_t **out, - void **un1, id_match_t *me, void **un2, id_match_t *other) +CALLBACK(shared_filter, bool, + void *null, enumerator_t *orig, va_list args) { - *out = *in; - if (me) - { - *me = ID_MATCH_ANY; - } - if (other) + shared_key_t *key, **out; + id_match_t *me, *other; + + VA_ARGS_VGET(args, out, me, other); + + if (orig->enumerate(orig, &key)) { - *other = ID_MATCH_ANY; + *out = key; + if (me) + { + *me = ID_MATCH_ANY; + } + if (other) + { + *other = ID_MATCH_ANY; + } + return TRUE; } - return TRUE; + return FALSE; } METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, @@ -431,7 +437,7 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, return NULL; } return enumerator_create_filter(enumerator_create_single(shared, NULL), - (void*)shared_filter, NULL, NULL); + shared_filter, NULL, NULL); } METHOD(load_tester_creds_t, destroy, void, diff --git a/src/libcharon/plugins/lookip/Makefile.in b/src/libcharon/plugins/lookip/Makefile.in index 919060469..ba86d3788 100644 --- a/src/libcharon/plugins/lookip/Makefile.in +++ b/src/libcharon/plugins/lookip/Makefile.in @@ -364,6 +364,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -386,6 +387,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/medcli/Makefile.in b/src/libcharon/plugins/medcli/Makefile.in index 4db68a3fc..e2d63be1c 100644 --- a/src/libcharon/plugins/medcli/Makefile.in +++ b/src/libcharon/plugins/medcli/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/medcli/medcli_config.c b/src/libcharon/plugins/medcli/medcli_config.c index 78159c845..f34990176 100644 --- a/src/libcharon/plugins/medcli/medcli_config.c +++ b/src/libcharon/plugins/medcli/medcli_config.c @@ -223,10 +223,11 @@ typedef struct { } peer_enumerator_t; METHOD(enumerator_t, peer_enumerator_enumerate, bool, - peer_enumerator_t *this, peer_cfg_t **cfg) + peer_enumerator_t *this, va_list args) { char *name, *local_net, *remote_net; chunk_t me, other; + peer_cfg_t **cfg; child_cfg_t *child_cfg; auth_cfg_t *auth; peer_cfg_create_t peer = { @@ -249,6 +250,8 @@ METHOD(enumerator_t, peer_enumerator_enumerate, bool, .mode = MODE_TUNNEL, }; + VA_ARGS_VGET(args, cfg); + DESTROY_IF(this->current); if (!this->inner->enumerate(this->inner, &name, &me, &other, &local_net, &remote_net)) @@ -295,7 +298,8 @@ METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_peer_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _peer_enumerator_enumerate, .destroy = _peer_enumerator_destroy, }, .ike = this->ike, diff --git a/src/libcharon/plugins/medcli/medcli_creds.c b/src/libcharon/plugins/medcli/medcli_creds.c index 677229b9f..528fc004d 100644 --- a/src/libcharon/plugins/medcli/medcli_creds.c +++ b/src/libcharon/plugins/medcli/medcli_creds.c @@ -50,10 +50,13 @@ typedef struct { } private_enumerator_t; METHOD(enumerator_t, private_enumerator_enumerate, bool, - private_enumerator_t *this, private_key_t **key) + private_enumerator_t *this, va_list args) { + private_key_t **key; chunk_t chunk; + VA_ARGS_VGET(args, key); + DESTROY_IF(this->current); while (this->inner->enumerate(this->inner, &chunk)) { @@ -92,7 +95,8 @@ METHOD(credential_set_t, create_private_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_private_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _private_enumerator_enumerate, .destroy = _private_enumerator_destroy, }, ); @@ -123,11 +127,14 @@ typedef struct { } cert_enumerator_t; METHOD(enumerator_t, cert_enumerator_enumerate, bool, - cert_enumerator_t *this, certificate_t **cert) + cert_enumerator_t *this, va_list args) { + certificate_t **cert; public_key_t *public; chunk_t chunk; + VA_ARGS_VGET(args, cert); + DESTROY_IF(this->current); while (this->inner->enumerate(this->inner, &chunk)) { @@ -180,7 +187,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_cert_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _cert_enumerator_enumerate, .destroy = _cert_enumerator_destroy, }, .type = key, diff --git a/src/libcharon/plugins/medcli/medcli_creds.h b/src/libcharon/plugins/medcli/medcli_creds.h index 4b5402653..ec17955a2 100644 --- a/src/libcharon/plugins/medcli/medcli_creds.h +++ b/src/libcharon/plugins/medcli/medcli_creds.h @@ -37,7 +37,7 @@ struct medcli_creds_t { credential_set_t set; /** - * Destroy the credentials databse. + * Destroy the credentials database. */ void (*destroy)(medcli_creds_t *this); }; diff --git a/src/libcharon/plugins/medcli/medcli_listener.h b/src/libcharon/plugins/medcli/medcli_listener.h index 4768beccd..860dcdc60 100644 --- a/src/libcharon/plugins/medcli/medcli_listener.h +++ b/src/libcharon/plugins/medcli/medcli_listener.h @@ -37,7 +37,7 @@ struct medcli_listener_t { listener_t listener; /** - * Destroy the credentials databse. + * Destroy the credentials database. */ void (*destroy)(medcli_listener_t *this); }; diff --git a/src/libcharon/plugins/medsrv/Makefile.in b/src/libcharon/plugins/medsrv/Makefile.in index ceb06deb1..10b48daa3 100644 --- a/src/libcharon/plugins/medsrv/Makefile.in +++ b/src/libcharon/plugins/medsrv/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/medsrv/medsrv_creds.c b/src/libcharon/plugins/medsrv/medsrv_creds.c index 0d99c4f77..16d4bd7f3 100644 --- a/src/libcharon/plugins/medsrv/medsrv_creds.c +++ b/src/libcharon/plugins/medsrv/medsrv_creds.c @@ -52,12 +52,14 @@ typedef struct { } cert_enumerator_t; METHOD(enumerator_t, cert_enumerator_enumerate, bool, - cert_enumerator_t *this, certificate_t **cert) + cert_enumerator_t *this, va_list args) { - certificate_t *trusted; + certificate_t *trusted, **cert; public_key_t *public; chunk_t chunk; + VA_ARGS_VGET(args, cert); + DESTROY_IF(this->current); while (this->inner->enumerate(this->inner, &chunk)) { @@ -110,7 +112,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_cert_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _cert_enumerator_enumerate, .destroy = _cert_enumerator_destroy, }, .type = key, diff --git a/src/libcharon/plugins/medsrv/medsrv_creds.h b/src/libcharon/plugins/medsrv/medsrv_creds.h index 2079601af..08ecaa3f2 100644 --- a/src/libcharon/plugins/medsrv/medsrv_creds.h +++ b/src/libcharon/plugins/medsrv/medsrv_creds.h @@ -37,7 +37,7 @@ struct medsrv_creds_t { credential_set_t set; /** - * Destroy the credentials databse. + * Destroy the credentials database. */ void (*destroy)(medsrv_creds_t *this); }; diff --git a/src/libcharon/plugins/osx_attr/Makefile.in b/src/libcharon/plugins/osx_attr/Makefile.in index ab9ece561..8e0b10eb0 100644 --- a/src/libcharon/plugins/osx_attr/Makefile.in +++ b/src/libcharon/plugins/osx_attr/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/osx_attr/osx_attr_handler.c b/src/libcharon/plugins/osx_attr/osx_attr_handler.c index 6baf76d35..e7a627b93 100644 --- a/src/libcharon/plugins/osx_attr/osx_attr_handler.c +++ b/src/libcharon/plugins/osx_attr/osx_attr_handler.c @@ -218,12 +218,15 @@ METHOD(attribute_handler_t, release, void, } METHOD(enumerator_t, enumerate_dns, bool, - enumerator_t *this, configuration_attribute_type_t *type, chunk_t *data) + enumerator_t *this, va_list args) { + configuration_attribute_type_t *type; + chunk_t *data; + + VA_ARGS_VGET(args, type, data); *type = INTERNAL_IP4_DNS; *data = chunk_empty; - /* stop enumeration */ - this->enumerate = (void*)return_false; + this->venumerate = (void*)return_false; return TRUE; } @@ -234,7 +237,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *, enumerator_t *enumerator; INIT(enumerator, - .enumerate = (void*)_enumerate_dns, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_dns, .destroy = (void*)free, ); return enumerator; diff --git a/src/libcharon/plugins/p_cscf/Makefile.in b/src/libcharon/plugins/p_cscf/Makefile.in index 7b3cb2fa4..954a43dc8 100644 --- a/src/libcharon/plugins/p_cscf/Makefile.in +++ b/src/libcharon/plugins/p_cscf/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/p_cscf/p_cscf_handler.c b/src/libcharon/plugins/p_cscf/p_cscf_handler.c index 76633845e..cdf266054 100644 --- a/src/libcharon/plugins/p_cscf/p_cscf_handler.c +++ b/src/libcharon/plugins/p_cscf/p_cscf_handler.c @@ -83,9 +83,12 @@ typedef struct { } attr_enumerator_t; METHOD(enumerator_t, enumerate_attrs, bool, - attr_enumerator_t *this, configuration_attribute_type_t *type, - chunk_t *data) + attr_enumerator_t *this, va_list args) { + configuration_attribute_type_t *type; + chunk_t *data; + + VA_ARGS_VGET(args, type, data); if (this->request_ipv4) { *type = P_CSCF_IP4_ADDRESS; @@ -103,12 +106,13 @@ METHOD(enumerator_t, enumerate_attrs, bool, return FALSE; } -/** - * Check if the given host has a matching address family - */ -static bool is_family(host_t *host, int *family) +CALLBACK(is_family, bool, + host_t *host, va_list args) { - return host->get_family(host) == *family; + int family; + + VA_ARGS_VGET(args, family); + return host->get_family(host) == family; } /** @@ -116,7 +120,7 @@ static bool is_family(host_t *host, int *family) */ static bool has_host_family(linked_list_t *list, int family) { - return list->find_first(list, (void*)is_family, NULL, &family) == SUCCESS; + return list->find_first(list, is_family, NULL, family); } METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *, @@ -132,7 +136,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *, INIT(enumerator, .public = { - .enumerate = (void*)_enumerate_attrs, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_attrs, .destroy = (void*)free, }, ); diff --git a/src/libcharon/plugins/radattr/Makefile.in b/src/libcharon/plugins/radattr/Makefile.in index 1fe3033dc..add1f547f 100644 --- a/src/libcharon/plugins/radattr/Makefile.in +++ b/src/libcharon/plugins/radattr/Makefile.in @@ -359,6 +359,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -381,6 +382,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/resolve/Makefile.in b/src/libcharon/plugins/resolve/Makefile.in index f8b62edf2..5e166f28f 100644 --- a/src/libcharon/plugins/resolve/Makefile.in +++ b/src/libcharon/plugins/resolve/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/resolve/resolve_handler.c b/src/libcharon/plugins/resolve/resolve_handler.c index 9077b51d4..05b865464 100644 --- a/src/libcharon/plugins/resolve/resolve_handler.c +++ b/src/libcharon/plugins/resolve/resolve_handler.c @@ -391,10 +391,13 @@ typedef struct { bool v6; } attribute_enumerator_t; -static bool attribute_enumerate(attribute_enumerator_t *this, - configuration_attribute_type_t *type, - chunk_t *data) +METHOD(enumerator_t, attribute_enumerate, bool, + attribute_enumerator_t *this, va_list args) { + configuration_attribute_type_t *type; + chunk_t *data; + + VA_ARGS_VGET(args, type, data); if (this->v4) { *type = INTERNAL_IP4_DNS; @@ -443,7 +446,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)attribute_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _attribute_enumerate, .destroy = (void*)free, }, .v4 = has_host_family(vips, AF_INET), diff --git a/src/libcharon/plugins/smp/Makefile.in b/src/libcharon/plugins/smp/Makefile.in index bf0791c42..9aac31894 100644 --- a/src/libcharon/plugins/smp/Makefile.in +++ b/src/libcharon/plugins/smp/Makefile.in @@ -356,6 +356,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -378,6 +379,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/socket_default/Makefile.in b/src/libcharon/plugins/socket_default/Makefile.in index f66ae1679..b87afa4a6 100644 --- a/src/libcharon/plugins/socket_default/Makefile.in +++ b/src/libcharon/plugins/socket_default/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/socket_default/socket_default_socket.c b/src/libcharon/plugins/socket_default/socket_default_socket.c index ba22b0c2b..109b3fe9b 100644 --- a/src/libcharon/plugins/socket_default/socket_default_socket.c +++ b/src/libcharon/plugins/socket_default/socket_default_socket.c @@ -142,6 +142,11 @@ struct private_socket_default_socket_t { bool set_source; /** + * TRUE to force sending source interface on outbound packetrs + */ + bool set_sourceif; + + /** * A counter to implement round-robin selection of read sockets */ u_int rr_counter; @@ -362,12 +367,33 @@ static ssize_t send_msg_generic(int skt, struct msghdr *msg) return sendmsg(skt, msg, 0); } +#if defined(IP_PKTINFO) || defined(HAVE_IN6_PKTINFO) + +/** + * Find the interface index a source address is installed on + */ +static int find_srcif(host_t *src) +{ + char *ifname; + int idx = 0; + + if (charon->kernel->get_interface(charon->kernel, src, &ifname)) + { + idx = if_nametoindex(ifname); + free(ifname); + } + return idx; +} + +#endif /* IP_PKTINFO || HAVE_IN6_PKTINFO */ + /** * Send a message with the IPv4 source address set, if possible. */ #ifdef IP_PKTINFO -static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src) +static ssize_t send_msg_v4(private_socket_default_socket_t *this, int skt, + struct msghdr *msg, host_t *src) { char buf[CMSG_SPACE(sizeof(struct in_pktinfo))] = {}; struct cmsghdr *cmsg; @@ -383,6 +409,10 @@ static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src) cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); pktinfo = (struct in_pktinfo*)CMSG_DATA(cmsg); + if (this->set_sourceif) + { + pktinfo->ipi_ifindex = find_srcif(src); + } addr = &pktinfo->ipi_spec_dst; sin = (struct sockaddr_in*)src->get_sockaddr(src); @@ -392,7 +422,8 @@ static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src) #elif defined(IP_SENDSRCADDR) -static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src) +static ssize_t send_msg_v4(private_socket_default_socket_t *this, int skt, + struct msghdr *msg, host_t *src) { char buf[CMSG_SPACE(sizeof(struct in_addr))] = {}; struct cmsghdr *cmsg; @@ -415,7 +446,8 @@ static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src) #else /* IP_PKTINFO || IP_RECVDSTADDR */ -static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src) +static ssize_t send_msg_v4(private_socket_default_socket_t *this, + int skt, struct msghdr *msg, host_t *src) { return send_msg_generic(skt, msg); } @@ -427,7 +459,8 @@ static ssize_t send_msg_v4(int skt, struct msghdr *msg, host_t *src) */ #ifdef HAVE_IN6_PKTINFO -static ssize_t send_msg_v6(int skt, struct msghdr *msg, host_t *src) +static ssize_t send_msg_v6(private_socket_default_socket_t *this, int skt, + struct msghdr *msg, host_t *src) { char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))] = {}; struct cmsghdr *cmsg; @@ -441,6 +474,10 @@ static ssize_t send_msg_v6(int skt, struct msghdr *msg, host_t *src) cmsg->cmsg_type = IPV6_PKTINFO; cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); pktinfo = (struct in6_pktinfo*)CMSG_DATA(cmsg); + if (this->set_sourceif) + { + pktinfo->ipi6_ifindex = find_srcif(src); + } sin = (struct sockaddr_in6*)src->get_sockaddr(src); memcpy(&pktinfo->ipi6_addr, &sin->sin6_addr, sizeof(struct in6_addr)); return send_msg_generic(skt, msg); @@ -448,7 +485,8 @@ static ssize_t send_msg_v6(int skt, struct msghdr *msg, host_t *src) #else /* HAVE_IN6_PKTINFO */ -static ssize_t send_msg_v6(int skt, struct msghdr *msg, host_t *src) +static ssize_t send_msg_v6(private_socket_default_socket_t *this, + int skt, struct msghdr *msg, host_t *src) { return send_msg_generic(skt, msg); } @@ -564,11 +602,11 @@ METHOD(socket_t, sender, status_t, { if (family == AF_INET) { - bytes_sent = send_msg_v4(skt, &msg, src); + bytes_sent = send_msg_v4(this, skt, &msg, src); } else { - bytes_sent = send_msg_v6(skt, &msg, src); + bytes_sent = send_msg_v6(this, skt, &msg, src); } } else @@ -831,6 +869,9 @@ socket_default_socket_t *socket_default_socket_create() .set_source = lib->settings->get_bool(lib->settings, "%s.plugins.socket-default.set_source", TRUE, lib->ns), + .set_sourceif = lib->settings->get_bool(lib->settings, + "%s.plugins.socket-default.set_sourceif", FALSE, + lib->ns), ); if (this->port && this->port == this->natt) diff --git a/src/libcharon/plugins/socket_dynamic/Makefile.in b/src/libcharon/plugins/socket_dynamic/Makefile.in index 3d07b5407..595651f21 100644 --- a/src/libcharon/plugins/socket_dynamic/Makefile.in +++ b/src/libcharon/plugins/socket_dynamic/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/socket_win/Makefile.in b/src/libcharon/plugins/socket_win/Makefile.in index 692489845..8f1e43926 100644 --- a/src/libcharon/plugins/socket_win/Makefile.in +++ b/src/libcharon/plugins/socket_win/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/sql/Makefile.in b/src/libcharon/plugins/sql/Makefile.in index 581225b55..5c146190d 100644 --- a/src/libcharon/plugins/sql/Makefile.in +++ b/src/libcharon/plugins/sql/Makefile.in @@ -356,6 +356,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -378,6 +379,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/sql/sql_config.c b/src/libcharon/plugins/sql/sql_config.c index 88cac7f26..00ed693eb 100644 --- a/src/libcharon/plugins/sql/sql_config.c +++ b/src/libcharon/plugins/sql/sql_config.c @@ -173,7 +173,8 @@ static child_cfg_t *build_child_cfg(private_sql_config_t *this, enumerator_t *e) child_cfg_create_t child = { .mode = mode, .reqid = reqid, - .ipcomp = ipcomp, + .options = (ipcomp ? OPT_IPCOMP : 0) | + (hostaccess ? OPT_HOSTACCESS : 0), .lifetime = { .time = { .life = lifetime, .rekey = rekeytime, .jitter = jitter @@ -183,7 +184,6 @@ static child_cfg_t *build_child_cfg(private_sql_config_t *this, enumerator_t *e) .dpd_action = dpd, .close_action = close, .updown = updown, - .hostaccess = hostaccess, }; child_cfg = child_cfg_create(name, &child); add_esp_proposals(this, child_cfg, id); @@ -504,11 +504,12 @@ typedef struct { ike_cfg_t *current; } ike_enumerator_t; -/** - * Implementation of ike_enumerator_t.public.enumerate - */ -static bool ike_enumerator_enumerate(ike_enumerator_t *this, ike_cfg_t **cfg) +METHOD(enumerator_t, ike_enumerator_enumerate, bool, + ike_enumerator_t *this, va_list args) { + ike_cfg_t **cfg; + + VA_ARGS_VGET(args, cfg); DESTROY_IF(this->current); this->current = build_ike_cfg(this->this, this->inner, this->me, this->other); if (this->current) @@ -519,10 +520,8 @@ static bool ike_enumerator_enumerate(ike_enumerator_t *this, ike_cfg_t **cfg) return FALSE; } -/** - * Implementation of ike_enumerator_t.public.destroy - */ -static void ike_enumerator_destroy(ike_enumerator_t *this) +METHOD(enumerator_t, ike_enumerator_destroy, void, + ike_enumerator_t *this) { DESTROY_IF(this->current); this->inner->destroy(this->inner); @@ -532,19 +531,22 @@ static void ike_enumerator_destroy(ike_enumerator_t *this) METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, private_sql_config_t *this, host_t *me, host_t *other) { - ike_enumerator_t *e = malloc_thing(ike_enumerator_t); - - e->this = this; - e->me = me; - e->other = other; - e->current = NULL; - e->public.enumerate = (void*)ike_enumerator_enumerate; - e->public.destroy = (void*)ike_enumerator_destroy; + ike_enumerator_t *e; + INIT(e, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _ike_enumerator_enumerate, + .destroy = _ike_enumerator_destroy, + }, + .this = this, + .me = me, + .other = other, + ); e->inner = this->db->query(this->db, - "SELECT id, certreq, force_encap, local, remote " - "FROM ike_configs", - DB_INT, DB_INT, DB_INT, DB_TEXT, DB_TEXT); + "SELECT id, certreq, force_encap, local, remote " + "FROM ike_configs", + DB_INT, DB_INT, DB_INT, DB_TEXT, DB_TEXT); if (!e->inner) { free(e); @@ -569,11 +571,12 @@ typedef struct { peer_cfg_t *current; } peer_enumerator_t; -/** - * Implementation of peer_enumerator_t.public.enumerate - */ -static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg) +METHOD(enumerator_t, peer_enumerator_enumerate, bool, + peer_enumerator_t *this, va_list args) { + peer_cfg_t **cfg; + + VA_ARGS_VGET(args, cfg); DESTROY_IF(this->current); this->current = build_peer_cfg(this->this, this->inner, this->me, this->other); if (this->current) @@ -584,10 +587,8 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg) return FALSE; } -/** - * Implementation of peer_enumerator_t.public.destroy - */ -static void peer_enumerator_destroy(peer_enumerator_t *this) +METHOD(enumerator_t, peer_enumerator_destroy, void, + peer_enumerator_t *this) { DESTROY_IF(this->current); this->inner->destroy(this->inner); @@ -597,14 +598,18 @@ static void peer_enumerator_destroy(peer_enumerator_t *this) METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*, private_sql_config_t *this, identification_t *me, identification_t *other) { - peer_enumerator_t *e = malloc_thing(peer_enumerator_t); - - e->this = this; - e->me = me; - e->other = other; - e->current = NULL; - e->public.enumerate = (void*)peer_enumerator_enumerate; - e->public.destroy = (void*)peer_enumerator_destroy; + peer_enumerator_t *e; + + INIT(e, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _peer_enumerator_enumerate, + .destroy = _peer_enumerator_destroy, + }, + .this = this, + .me = me, + .other = other, + ); /* TODO: only get configs whose IDs match exactly or contain wildcards */ e->inner = this->db->query(this->db, diff --git a/src/libcharon/plugins/sql/sql_cred.c b/src/libcharon/plugins/sql/sql_cred.c index 117eec921..3317de6c8 100644 --- a/src/libcharon/plugins/sql/sql_cred.c +++ b/src/libcharon/plugins/sql/sql_cred.c @@ -52,11 +52,14 @@ typedef struct { } private_enumerator_t; METHOD(enumerator_t, private_enumerator_enumerate, bool, - private_enumerator_t *this, private_key_t **key) + private_enumerator_t *this, va_list args) { + private_key_t **key; chunk_t blob; int type; + VA_ARGS_VGET(args, key); + DESTROY_IF(this->current); while (this->inner->enumerate(this->inner, &type, &blob)) { @@ -88,7 +91,8 @@ METHOD(credential_set_t, create_private_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_private_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _private_enumerator_enumerate, .destroy = _private_enumerator_destroy, }, ); @@ -132,11 +136,14 @@ typedef struct { } cert_enumerator_t; METHOD(enumerator_t, cert_enumerator_enumerate, bool, - cert_enumerator_t *this, certificate_t **cert) + cert_enumerator_t *this, va_list args) { + certificate_t **cert; chunk_t blob; int type; + VA_ARGS_VGET(args, cert); + DESTROY_IF(this->current); while (this->inner->enumerate(this->inner, &type, &blob)) { @@ -169,7 +176,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_cert_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _cert_enumerator_enumerate, .destroy = _cert_enumerator_destroy, }, ); @@ -221,12 +229,15 @@ typedef struct { } shared_enumerator_t; METHOD(enumerator_t, shared_enumerator_enumerate, bool, - shared_enumerator_t *this, shared_key_t **shared, - id_match_t *me, id_match_t *other) + shared_enumerator_t *this, va_list args) { + shared_key_t **shared; + id_match_t *me, *other; chunk_t blob; int type; + VA_ARGS_VGET(args, shared, me, other); + DESTROY_IF(this->current); while (this->inner->enumerate(this->inner, &type, &blob)) { @@ -265,7 +276,8 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_shared_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _shared_enumerator_enumerate, .destroy = _shared_enumerator_destroy, }, .me = me, @@ -340,9 +352,11 @@ typedef enum { } cdp_type_t; METHOD(enumerator_t, cdp_enumerator_enumerate, bool, - cdp_enumerator_t *this, char **uri) + cdp_enumerator_t *this, va_list args) { - char *text; + char *text, **uri; + + VA_ARGS_VGET(args, uri); free(this->current); while (this->inner->enumerate(this->inner, &text)) @@ -384,7 +398,8 @@ METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*, } INIT(e, .public = { - .enumerate = (void*)_cdp_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _cdp_enumerator_enumerate, .destroy = _cdp_enumerator_destroy, }, ); diff --git a/src/libcharon/plugins/stroke/Makefile.in b/src/libcharon/plugins/stroke/Makefile.in index 50a6d5953..0af607fd7 100644 --- a/src/libcharon/plugins/stroke/Makefile.in +++ b/src/libcharon/plugins/stroke/Makefile.in @@ -360,6 +360,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -382,6 +383,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/stroke/stroke_attribute.c b/src/libcharon/plugins/stroke/stroke_attribute.c index cd1b4d093..7835031c2 100644 --- a/src/libcharon/plugins/stroke/stroke_attribute.c +++ b/src/libcharon/plugins/stroke/stroke_attribute.c @@ -178,28 +178,32 @@ METHOD(attribute_provider_t, release_address, bool, return found; } -/** - * Filter function to convert host to DNS configuration attributes - */ -static bool attr_filter(void *lock, host_t **in, - configuration_attribute_type_t *type, - void *dummy, chunk_t *data) +CALLBACK(attr_filter, bool, + void *lock, enumerator_t *orig, va_list args) { - host_t *host = *in; + configuration_attribute_type_t *type; + chunk_t *data; + host_t *host; - switch (host->get_family(host)) + VA_ARGS_VGET(args, type, data); + + while (orig->enumerate(orig, &host)) { - case AF_INET: - *type = INTERNAL_IP4_DNS; - break; - case AF_INET6: - *type = INTERNAL_IP6_DNS; - break; - default: - return FALSE; + switch (host->get_family(host)) + { + case AF_INET: + *type = INTERNAL_IP4_DNS; + break; + case AF_INET6: + *type = INTERNAL_IP6_DNS; + break; + default: + continue; + } + *data = host->get_address(host); + return TRUE; } - *data = host->get_address(host); - return TRUE; + return FALSE; } METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, @@ -223,7 +227,7 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, enumerator->destroy(enumerator); return enumerator_create_filter( attr->dns->create_enumerator(attr->dns), - (void*)attr_filter, this->lock, + attr_filter, this->lock, (void*)this->lock->unlock); } } @@ -338,24 +342,28 @@ METHOD(stroke_attribute_t, del_dns, void, this->lock->unlock(this->lock); } -/** - * Pool enumerator filter function, converts pool_t to name, size, ... - */ -static bool pool_filter(void *lock, mem_pool_t **poolp, const char **name, - void *d1, u_int *size, void *d2, u_int *online, - void *d3, u_int *offline) +CALLBACK(pool_filter, bool, + void *lock, enumerator_t *orig, va_list args) { - mem_pool_t *pool = *poolp; + mem_pool_t *pool; + const char **name; + u_int *size, *online, *offline; - if (pool->get_size(pool) == 0) + VA_ARGS_VGET(args, name, size, online, offline); + + while (orig->enumerate(orig, &pool)) { - return FALSE; + if (pool->get_size(pool) == 0) + { + continue; + } + *name = pool->get_name(pool); + *size = pool->get_size(pool); + *online = pool->get_online(pool); + *offline = pool->get_offline(pool); + return TRUE; } - *name = pool->get_name(pool); - *size = pool->get_size(pool); - *online = pool->get_online(pool); - *offline = pool->get_offline(pool); - return TRUE; + return FALSE; } METHOD(stroke_attribute_t, create_pool_enumerator, enumerator_t*, @@ -363,7 +371,7 @@ METHOD(stroke_attribute_t, create_pool_enumerator, enumerator_t*, { this->lock->read_lock(this->lock); return enumerator_create_filter(this->pools->create_enumerator(this->pools), - (void*)pool_filter, + pool_filter, this->lock, (void*)this->lock->unlock); } diff --git a/src/libcharon/plugins/stroke/stroke_ca.c b/src/libcharon/plugins/stroke/stroke_ca.c index 13ed41e0e..4593e9bdc 100644 --- a/src/libcharon/plugins/stroke/stroke_ca.c +++ b/src/libcharon/plugins/stroke/stroke_ca.c @@ -171,26 +171,30 @@ typedef struct { identification_t *id; } cert_data_t; -/** - * destroy cert_data - */ -static void cert_data_destroy(cert_data_t *data) +CALLBACK(cert_data_destroy, void, + cert_data_t *data) { data->this->lock->unlock(data->this->lock); free(data); } -/** - * filter function for certs enumerator - */ -static bool certs_filter(cert_data_t *data, ca_cert_t **in, - certificate_t **out) +CALLBACK(certs_filter, bool, + cert_data_t *data, enumerator_t *orig, va_list args) { + ca_cert_t *cacert; public_key_t *public; - certificate_t *cert = (*in)->cert; + certificate_t **out; + + VA_ARGS_VGET(args, out); - if (data->cert == CERT_ANY || data->cert == cert->get_type(cert)) + while (orig->enumerate(orig, &cacert)) { + certificate_t *cert = cacert->cert; + + if (data->cert != CERT_ANY && data->cert != cert->get_type(cert)) + { + continue; + } public = cert->get_public_key(cert); if (public) { @@ -208,9 +212,9 @@ static bool certs_filter(cert_data_t *data, ca_cert_t **in, } else if (data->key != KEY_ANY) { - return FALSE; + continue; } - if (data->id == NULL || cert->has_subject(cert, data->id)) + if (!data->id || cert->has_subject(cert, data->id)) { *out = cert; return TRUE; @@ -235,8 +239,8 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, this->lock->read_lock(this->lock); enumerator = this->certs->create_enumerator(this->certs); - return enumerator_create_filter(enumerator, (void*)certs_filter, data, - (void*)cert_data_destroy); + return enumerator_create_filter(enumerator, certs_filter, data, + cert_data_destroy); } /** @@ -354,11 +358,12 @@ METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*, data, (void*)cdp_data_destroy); } -/** - * Compare the given certificate to the ca_cert_t items in the list - */ -static bool match_cert(ca_cert_t *item, certificate_t *cert) +CALLBACK(match_cert, bool, + ca_cert_t *item, va_list args) { + certificate_t *cert; + + VA_ARGS_VGET(args, cert); return cert->equals(cert, item->cert); } @@ -405,8 +410,7 @@ static certificate_t *add_cert_internal(private_stroke_ca_t *this, { ca_cert_t *found; - if (this->certs->find_first(this->certs, (linked_list_match_t)match_cert, - (void**)&found, cert) == SUCCESS) + if (this->certs->find_first(this->certs, match_cert, (void**)&found, cert)) { cert->destroy(cert); cert = found->cert->get_ref(found->cert); @@ -511,8 +515,7 @@ METHOD(stroke_ca_t, get_cert_ref, certificate_t*, ca_cert_t *found; this->lock->read_lock(this->lock); - if (this->certs->find_first(this->certs, (linked_list_match_t)match_cert, - (void**)&found, cert) == SUCCESS) + if (this->certs->find_first(this->certs, match_cert, (void**)&found, cert)) { cert->destroy(cert); cert = found->cert->get_ref(found->cert); diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c index bbdc2116d..00f74831c 100644 --- a/src/libcharon/plugins/stroke/stroke_config.c +++ b/src/libcharon/plugins/stroke/stroke_config.c @@ -68,13 +68,20 @@ METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*, (void*)this->mutex->unlock, this->mutex); } -/** - * filter function for ike configs - */ -static bool ike_filter(void *data, peer_cfg_t **in, ike_cfg_t **out) +CALLBACK(ike_filter, bool, + void *data, enumerator_t *orig, va_list args) { - *out = (*in)->get_ike_cfg(*in); - return TRUE; + peer_cfg_t *cfg; + ike_cfg_t **out; + + VA_ARGS_VGET(args, out); + + if (orig->enumerate(orig, &cfg)) + { + *out = cfg->get_ike_cfg(cfg); + return TRUE; + } + return FALSE; } METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, @@ -82,7 +89,7 @@ METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, { this->mutex->lock(this->mutex); return enumerator_create_filter(this->list->create_enumerator(this->list), - (void*)ike_filter, this->mutex, + ike_filter, this->mutex, (void*)this->mutex->unlock); } @@ -1071,15 +1078,16 @@ static child_cfg_t *build_child_cfg(private_stroke_config_t *this, }, .reqid = msg->add_conn.reqid, .mode = msg->add_conn.mode, - .proxy_mode = msg->add_conn.proxy_mode, - .ipcomp = msg->add_conn.ipcomp, + .options = (msg->add_conn.proxy_mode ? OPT_PROXY_MODE : 0) | + (msg->add_conn.ipcomp ? OPT_IPCOMP : 0) | + (msg->add_conn.me.hostaccess ? OPT_HOSTACCESS : 0) | + (msg->add_conn.install_policy ? 0 : OPT_NO_POLICIES) | + (msg->add_conn.sha256_96 ? OPT_SHA256_96 : 0), .tfc = msg->add_conn.tfc, .inactivity = msg->add_conn.inactivity, .dpd_action = map_action(msg->add_conn.dpd.action), .close_action = map_action(msg->add_conn.close_action), .updown = msg->add_conn.me.updown, - .hostaccess = msg->add_conn.me.hostaccess, - .suppress_policies = !msg->add_conn.install_policy, }; child_cfg = child_cfg_create(msg->add_conn.name, &child); diff --git a/src/libcharon/plugins/stroke/stroke_handler.c b/src/libcharon/plugins/stroke/stroke_handler.c index d0cc9afab..19d5a62a1 100644 --- a/src/libcharon/plugins/stroke/stroke_handler.c +++ b/src/libcharon/plugins/stroke/stroke_handler.c @@ -62,35 +62,39 @@ static void attributes_destroy(attributes_t *this) free(this); } -/** - * Filter function to convert host to DNS configuration attributes - */ -static bool attr_filter(void *lock, host_t **in, - configuration_attribute_type_t *type, - void *dummy, chunk_t *data) +CALLBACK(attr_filter, bool, + void *lock, enumerator_t *orig, va_list args) { - host_t *host = *in; + configuration_attribute_type_t *type; + chunk_t *data; + host_t *host; - switch (host->get_family(host)) - { - case AF_INET: - *type = INTERNAL_IP4_DNS; - break; - case AF_INET6: - *type = INTERNAL_IP6_DNS; - break; - default: - return FALSE; - } - if (host->is_anyaddr(host)) - { - *data = chunk_empty; - } - else + VA_ARGS_VGET(args, type, data); + + while (orig->enumerate(orig, &host)) { - *data = host->get_address(host); + switch (host->get_family(host)) + { + case AF_INET: + *type = INTERNAL_IP4_DNS; + break; + case AF_INET6: + *type = INTERNAL_IP6_DNS; + break; + default: + continue; + } + if (host->is_anyaddr(host)) + { + *data = chunk_empty; + } + else + { + *data = host->get_address(host); + } + return TRUE; } - return TRUE; + return FALSE; } METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, @@ -114,7 +118,7 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t*, enumerator->destroy(enumerator); return enumerator_create_filter( attr->dns->create_enumerator(attr->dns), - (void*)attr_filter, this->lock, + attr_filter, this->lock, (void*)this->lock->unlock); } } diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c index 92e368669..22992599d 100644 --- a/src/libcharon/plugins/stroke/stroke_list.c +++ b/src/libcharon/plugins/stroke/stroke_list.c @@ -218,7 +218,7 @@ static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa), child_sa_state_names, child_sa->get_state(child_sa), ipsec_mode_names, child_sa->get_mode(child_sa), - config->use_proxy_mode(config) ? "_PROXY" : "", + config->has_option(config, OPT_PROXY_MODE) ? "_PROXY" : "", child_sa->get_reqid(child_sa)); if (child_sa->get_state(child_sa) == CHILD_INSTALLED) @@ -958,8 +958,7 @@ static void list_plugins(FILE *out) { case FEATURE_PROVIDE: fp = &features[i]; - loaded = list->find_first(list, NULL, - (void**)&fp) == SUCCESS; + loaded = list->find_first(list, NULL, (void**)&fp); fprintf(out, " %s%s\n", str, loaded ? "" : " (not loaded)"); break; diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c index 46de90ca6..65d345db3 100644 --- a/src/libcharon/plugins/stroke/stroke_socket.c +++ b/src/libcharon/plugins/stroke/stroke_socket.c @@ -216,6 +216,7 @@ static void stroke_add_conn(private_stroke_socket_t *this, stroke_msg_t *msg) DBG_OPT(" dpdtimeout=%d", msg->add_conn.dpd.timeout); DBG_OPT(" dpdaction=%d", msg->add_conn.dpd.action); DBG_OPT(" closeaction=%d", msg->add_conn.close_action); + DBG_OPT(" sha256_96=%s", msg->add_conn.sha256_96 ? "yes" : "no"); DBG_OPT(" mediation=%s", msg->add_conn.ikeme.mediation ? "yes" : "no"); DBG_OPT(" mediated_by=%s", msg->add_conn.ikeme.mediated_by); DBG_OPT(" me_peerid=%s", msg->add_conn.ikeme.peerid); diff --git a/src/libcharon/plugins/systime_fix/Makefile.in b/src/libcharon/plugins/systime_fix/Makefile.in index 78fd6e8d1..327443020 100644 --- a/src/libcharon/plugins/systime_fix/Makefile.in +++ b/src/libcharon/plugins/systime_fix/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/tnc_ifmap/Makefile.in b/src/libcharon/plugins/tnc_ifmap/Makefile.in index 7ec4eaad1..438001baf 100644 --- a/src/libcharon/plugins/tnc_ifmap/Makefile.in +++ b/src/libcharon/plugins/tnc_ifmap/Makefile.in @@ -361,6 +361,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -383,6 +384,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap_msg.c b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap_msg.c index b86288683..db19bd575 100644 --- a/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap_msg.c +++ b/src/libcharon/plugins/tnc_ifmap/tnc_ifmap_soap_msg.c @@ -55,7 +55,7 @@ struct private_tnc_ifmap_soap_msg_t { static xmlNodePtr find_child(xmlNodePtr parent, const xmlChar* name) { xmlNodePtr child; - + child = parent->xmlChildrenNode; while (child) { @@ -80,7 +80,7 @@ METHOD(tnc_ifmap_soap_msg_t, post, bool, xmlChar *xml_str, *errorCode, *errorString; int xml_len, len, written; chunk_t xml, http; - char buf[4096]; + char buf[4096] = { 0 }; status_t status; DBG2(DBG_TNC, "sending ifmap %s", request->name); @@ -131,7 +131,8 @@ METHOD(tnc_ifmap_soap_msg_t, post, bool, xml = chunk_empty; do { - len = this->tls->read(this->tls, buf, sizeof(buf), TRUE); + /* reduce size so the buffer is null-terminated */ + len = this->tls->read(this->tls, buf, sizeof(buf)-1, TRUE); if (len <= 0) { return FALSE; @@ -150,7 +151,7 @@ METHOD(tnc_ifmap_soap_msg_t, post, bool, DBG3(DBG_TNC, "parsing XML message %B", &xml); this->doc = xmlParseMemory(xml.ptr, xml.len); free(xml.ptr); - + if (!this->doc) { DBG1(DBG_TNC, "failed to parse XML message"); diff --git a/src/libcharon/plugins/tnc_pdp/Makefile.in b/src/libcharon/plugins/tnc_pdp/Makefile.in index 215e3b38e..abc77433a 100644 --- a/src/libcharon/plugins/tnc_pdp/Makefile.in +++ b/src/libcharon/plugins/tnc_pdp/Makefile.in @@ -362,6 +362,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -384,6 +385,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/uci/Makefile.in b/src/libcharon/plugins/uci/Makefile.in index 64b4bca24..46f4e4f85 100644 --- a/src/libcharon/plugins/uci/Makefile.in +++ b/src/libcharon/plugins/uci/Makefile.in @@ -356,6 +356,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -378,6 +379,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/uci/uci_config.c b/src/libcharon/plugins/uci/uci_config.c index e0578fe9b..dcd4ae348 100644 --- a/src/libcharon/plugins/uci/uci_config.c +++ b/src/libcharon/plugins/uci/uci_config.c @@ -118,11 +118,12 @@ static u_int create_rekey(char *string) } METHOD(enumerator_t, peer_enumerator_enumerate, bool, - peer_enumerator_t *this, peer_cfg_t **cfg) + peer_enumerator_t *this, va_list args) { char *name, *ike_proposal, *esp_proposal, *ike_rekey, *esp_rekey; char *local_id, *local_addr, *local_net; char *remote_id, *remote_addr, *remote_net; + peer_cfg_t **cfg; child_cfg_t *child_cfg; ike_cfg_t *ike_cfg; auth_cfg_t *auth; @@ -145,6 +146,8 @@ METHOD(enumerator_t, peer_enumerator_enumerate, bool, .mode = MODE_TUNNEL, }; + VA_ARGS_VGET(args, cfg); + /* defaults */ name = "unnamed"; local_id = NULL; @@ -212,7 +215,8 @@ METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_peer_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _peer_enumerator_enumerate, .destroy = _peer_enumerator_destroy, }, .inner = this->parser->create_section_enumerator(this->parser, @@ -241,10 +245,13 @@ typedef struct { } ike_enumerator_t; METHOD(enumerator_t, ike_enumerator_enumerate, bool, - ike_enumerator_t *this, ike_cfg_t **cfg) + ike_enumerator_t *this, va_list args) { + ike_cfg_t **cfg; char *local_addr, *remote_addr, *ike_proposal; + VA_ARGS_VGET(args, cfg); + /* defaults */ local_addr = "0.0.0.0"; remote_addr = "0.0.0.0"; @@ -282,7 +289,8 @@ METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_ike_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _ike_enumerator_enumerate, .destroy = _ike_enumerator_destroy, }, .inner = this->parser->create_section_enumerator(this->parser, diff --git a/src/libcharon/plugins/uci/uci_creds.c b/src/libcharon/plugins/uci/uci_creds.c index f5d5ace70..404a3e39f 100644 --- a/src/libcharon/plugins/uci/uci_creds.c +++ b/src/libcharon/plugins/uci/uci_creds.c @@ -52,12 +52,15 @@ typedef struct { } shared_enumerator_t; METHOD(enumerator_t, shared_enumerator_enumerate, bool, - shared_enumerator_t *this, shared_key_t **key, id_match_t *me, - id_match_t *other) + shared_enumerator_t *this, va_list args) { + shared_key_t **key; + id_match_t *me, *other; char *local_id, *remote_id, *psk; identification_t *local, *remote; + VA_ARGS_VGET(args, key, me, other); + while (TRUE) { /* defaults */ @@ -126,7 +129,8 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_shared_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _shared_enumerator_enumerate, .destroy = _shared_enumerator_destroy, }, .me = me, diff --git a/src/libcharon/plugins/uci/uci_parser.c b/src/libcharon/plugins/uci/uci_parser.c index 2429e9e44..e847dd393 100644 --- a/src/libcharon/plugins/uci/uci_parser.c +++ b/src/libcharon/plugins/uci/uci_parser.c @@ -58,11 +58,10 @@ typedef struct { } section_enumerator_t; METHOD(enumerator_t, section_enumerator_enumerate, bool, - section_enumerator_t *this, ...) + section_enumerator_t *this, va_list args) { struct uci_element *element; char **value; - va_list args; int i; if (&this->current->list == this->list) @@ -70,8 +69,6 @@ METHOD(enumerator_t, section_enumerator_enumerate, bool, return FALSE; } - va_start(args, this); - value = va_arg(args, char**); if (value) { @@ -96,7 +93,6 @@ METHOD(enumerator_t, section_enumerator_enumerate, bool, *value = uci_to_option(element)->value; } } - va_end(args); this->current = list_to_element(this->current->list.next); return TRUE; @@ -124,7 +120,13 @@ METHOD(uci_parser_t, create_section_enumerator, enumerator_t*, i++; } va_end(args); - e = malloc(sizeof(section_enumerator_t) + sizeof(char*) * i); + INIT_EXTRA(e, sizeof(char*) * i, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _section_enumerator_enumerate, + .destroy = _section_enumerator_destroy, + }, + ); i = 0; va_start(args, this); do @@ -134,9 +136,6 @@ METHOD(uci_parser_t, create_section_enumerator, enumerator_t*, while (e->keywords[i++]); va_end(args); - e->public.enumerate = (void*)_section_enumerator_enumerate; - e->public.destroy = _section_enumerator_destroy; - /* load uci context */ e->ctx = uci_alloc_context(); if (uci_load(e->ctx, this->package, &e->package) != UCI_OK) diff --git a/src/libcharon/plugins/unity/Makefile.in b/src/libcharon/plugins/unity/Makefile.in index 6811eb737..245bbd471 100644 --- a/src/libcharon/plugins/unity/Makefile.in +++ b/src/libcharon/plugins/unity/Makefile.in @@ -357,6 +357,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -379,6 +380,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/unity/unity_handler.c b/src/libcharon/plugins/unity/unity_handler.c index 25e0756b7..4a1478c6d 100644 --- a/src/libcharon/plugins/unity/unity_handler.c +++ b/src/libcharon/plugins/unity/unity_handler.c @@ -368,9 +368,12 @@ typedef struct { } attribute_enumerator_t; METHOD(enumerator_t, enumerate_attributes, bool, - attribute_enumerator_t *this, configuration_attribute_type_t *type, - chunk_t *data) + attribute_enumerator_t *this, va_list args) { + configuration_attribute_type_t *type; + chunk_t *data; + + VA_ARGS_VGET(args, type, data); if (this->i < countof(attributes)) { *type = attributes[this->i++]; @@ -393,7 +396,8 @@ METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *, } INIT(enumerator, .public = { - .enumerate = (void*)_enumerate_attributes, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_attributes, .destroy = (void*)free, }, ); @@ -407,24 +411,27 @@ typedef struct { ike_sa_id_t *id; } include_filter_t; -/** - * Include enumerator filter function - */ -static bool include_filter(include_filter_t *data, - entry_t **entry, traffic_selector_t **ts) +CALLBACK(include_filter, bool, + include_filter_t *data, enumerator_t *orig, va_list args) { - if (data->id->equals(data->id, (*entry)->id)) + entry_t *entry; + traffic_selector_t **ts; + + VA_ARGS_VGET(args, ts); + + while (orig->enumerate(orig, &entry)) { - *ts = (*entry)->ts; - return TRUE; + if (data->id->equals(data->id, entry->id)) + { + *ts = entry->ts; + return TRUE; + } } return FALSE; } -/** - * Destroy include filter data, unlock mutex - */ -static void destroy_filter(include_filter_t *data) +CALLBACK(destroy_filter, void, + include_filter_t *data) { data->mutex->unlock(data->mutex); free(data); @@ -442,7 +449,7 @@ METHOD(unity_handler_t, create_include_enumerator, enumerator_t*, data->mutex->lock(data->mutex); return enumerator_create_filter( this->include->create_enumerator(this->include), - (void*)include_filter, data, (void*)destroy_filter); + include_filter, data, destroy_filter); } METHOD(unity_handler_t, destroy, void, diff --git a/src/libcharon/plugins/unity/unity_provider.c b/src/libcharon/plugins/unity/unity_provider.c index 07f5f9b61..b6a55648e 100644 --- a/src/libcharon/plugins/unity/unity_provider.c +++ b/src/libcharon/plugins/unity/unity_provider.c @@ -77,12 +77,15 @@ static void append_ts(bio_writer_t *writer, traffic_selector_t *ts) } METHOD(enumerator_t, attribute_enumerate, bool, - attribute_enumerator_t *this, configuration_attribute_type_t *type, - chunk_t *attr) + attribute_enumerator_t *this, va_list args) { + configuration_attribute_type_t *type; + chunk_t *attr; traffic_selector_t *ts; bio_writer_t *writer; + VA_ARGS_VGET(args, type, attr); + if (this->list->get_count(this->list) == 0) { return FALSE; @@ -183,7 +186,8 @@ METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, INIT(attr_enum, .public = { - .enumerate = (void*)_attribute_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _attribute_enumerate, .destroy = _attribute_destroy, }, .list = list, diff --git a/src/libcharon/plugins/updown/Makefile.in b/src/libcharon/plugins/updown/Makefile.in index 1a44e5566..ef0f33ce3 100644 --- a/src/libcharon/plugins/updown/Makefile.in +++ b/src/libcharon/plugins/updown/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/updown/updown_listener.c b/src/libcharon/plugins/updown/updown_listener.c index 6a1581c85..bbefd6a02 100644 --- a/src/libcharon/plugins/updown/updown_listener.c +++ b/src/libcharon/plugins/updown/updown_listener.c @@ -366,7 +366,7 @@ static void invoke_once(private_updown_listener_t *this, ike_sa_t *ike_sa, push_env(envp, countof(envp), "PLUTO_IPCOMP=1"); } push_dns_env(this, ike_sa, envp, countof(envp)); - if (config->get_hostaccess(config)) + if (config->has_option(config, OPT_HOSTACCESS)) { push_env(envp, countof(envp), "PLUTO_HOST_ACCESS=1"); } diff --git a/src/libcharon/plugins/vici/Makefile.in b/src/libcharon/plugins/vici/Makefile.in index cdefbff79..fd2b89849 100644 --- a/src/libcharon/plugins/vici/Makefile.in +++ b/src/libcharon/plugins/vici/Makefile.in @@ -454,6 +454,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -476,6 +477,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/vici/README.md b/src/libcharon/plugins/vici/README.md index 9bda949d0..f47f80cad 100644 --- a/src/libcharon/plugins/vici/README.md +++ b/src/libcharon/plugins/vici/README.md @@ -480,11 +480,12 @@ Load a certificate into the daemon. Load a private key into the daemon. { - type = <private key type, RSA|ECDSA> + type = <private key type, rsa|ecdsa|bliss|any> data = <PEM or DER encoded key data> } => { success = <yes or no> errmsg = <error string on failure> + id = <hex-encoded SHA-1 key identifier of the public key on success> } ### unload-key() ### diff --git a/src/libcharon/plugins/vici/perl/Makefile.in b/src/libcharon/plugins/vici/perl/Makefile.in index 385aa9775..0e9626aa3 100644 --- a/src/libcharon/plugins/vici/perl/Makefile.in +++ b/src/libcharon/plugins/vici/perl/Makefile.in @@ -272,6 +272,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -294,6 +295,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/vici/python/Makefile.in b/src/libcharon/plugins/vici/python/Makefile.in index f783d7068..7d5383290 100644 --- a/src/libcharon/plugins/vici/python/Makefile.in +++ b/src/libcharon/plugins/vici/python/Makefile.in @@ -294,6 +294,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -316,6 +317,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/vici/python/vici/protocol.py b/src/libcharon/plugins/vici/python/vici/protocol.py index 919231d43..370229463 100644 --- a/src/libcharon/plugins/vici/python/vici/protocol.py +++ b/src/libcharon/plugins/vici/python/vici/protocol.py @@ -62,7 +62,7 @@ class Packet(object): @classmethod def _named_request(cls, request_type, request, message=None): - requestdata = request.encode("UTF-8") + request = request.encode("UTF-8") payload = struct.pack("!BB", request_type, len(request)) + request if message is not None: return payload + message diff --git a/src/libcharon/plugins/vici/ruby/Makefile.in b/src/libcharon/plugins/vici/ruby/Makefile.in index 125f44ee1..5691a74d1 100644 --- a/src/libcharon/plugins/vici/ruby/Makefile.in +++ b/src/libcharon/plugins/vici/ruby/Makefile.in @@ -272,6 +272,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -294,6 +295,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ @@ -468,8 +470,8 @@ distclean-generic: maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -@RUBY_GEMS_INSTALL_FALSE@install-data-local: @RUBY_GEMS_INSTALL_FALSE@uninstall-local: +@RUBY_GEMS_INSTALL_FALSE@install-data-local: clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am diff --git a/src/libcharon/plugins/vici/suites/test_message.c b/src/libcharon/plugins/vici/suites/test_message.c index 045e34fff..73bba239b 100644 --- a/src/libcharon/plugins/vici/suites/test_message.c +++ b/src/libcharon/plugins/vici/suites/test_message.c @@ -122,9 +122,14 @@ typedef struct { endecode_test_t *next; } endecode_enum_t; -static bool endecode_enumerate(endecode_enum_t *this, vici_type_t *type, - char **name, chunk_t *data) +METHOD(enumerator_t, endecode_enumerate, bool, + endecode_enum_t *this, va_list args) { + vici_type_t *type; + chunk_t *data; + char **name; + + VA_ARGS_VGET(args, type, name, data); if (this->next) { *type = this->next->type; @@ -149,7 +154,8 @@ static enumerator_t *endecode_create_enumerator(endecode_test_t *test) INIT(enumerator, .public = { - .enumerate = (void*)endecode_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _endecode_enumerate, .destroy = (void*)free, }, .next = test, diff --git a/src/libcharon/plugins/vici/vici_attribute.c b/src/libcharon/plugins/vici/vici_attribute.c index 4e1fa9708..ab765fa14 100644 --- a/src/libcharon/plugins/vici/vici_attribute.c +++ b/src/libcharon/plugins/vici/vici_attribute.c @@ -184,16 +184,22 @@ METHOD(attribute_provider_t, release_address, bool, return found; } -/** - * Filter mapping attribute_t to enumerated type/value arguments - */ -static bool attr_filter(void *data, attribute_t **attr, - configuration_attribute_type_t *type, - void *in, chunk_t *value) +CALLBACK(attr_filter, bool, + void *data, enumerator_t *orig, va_list args) { - *type = (*attr)->type; - *value = (*attr)->value; - return TRUE; + attribute_t *attr; + configuration_attribute_type_t *type; + chunk_t *value; + + VA_ARGS_VGET(args, type, value); + + if (orig->enumerate(orig, &attr)) + { + *type = attr->type; + *value = attr->value; + return TRUE; + } + return FALSE; } /** @@ -203,7 +209,7 @@ CALLBACK(create_nested, enumerator_t*, pool_t *pool, void *this) { return enumerator_create_filter(array_create_enumerator(pool->attrs), - (void*)attr_filter, NULL, NULL); + attr_filter, NULL, NULL); } /** diff --git a/src/libcharon/plugins/vici/vici_config.c b/src/libcharon/plugins/vici/vici_config.c index 12497ec5e..0c355e3a0 100644 --- a/src/libcharon/plugins/vici/vici_config.c +++ b/src/libcharon/plugins/vici/vici_config.c @@ -141,13 +141,20 @@ METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*, (void*)this->lock->unlock, this->lock); } -/** - * Enumerator filter function for ike configs - */ -static bool ike_filter(void *data, peer_cfg_t **in, ike_cfg_t **out) +CALLBACK(ike_filter, bool, + void *data, enumerator_t *orig, va_list args) { - *out = (*in)->get_ike_cfg(*in); - return TRUE; + peer_cfg_t *cfg; + ike_cfg_t **out; + + VA_ARGS_VGET(args, out); + + if (orig->enumerate(orig, &cfg)) + { + *out = cfg->get_ike_cfg(cfg); + return TRUE; + } + return FALSE; } METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, @@ -155,7 +162,7 @@ METHOD(backend_t, create_ike_cfg_enumerator, enumerator_t*, { this->lock->read_lock(this->lock); return enumerator_create_filter(this->conns->create_enumerator(this->conns), - (void*)ike_filter, this->lock, + ike_filter, this->lock, (void*)this->lock->unlock); } @@ -478,7 +485,6 @@ typedef struct { linked_list_t *remote_ts; uint32_t replay_window; bool policies; - bool policies_fwd_out; child_cfg_create_t cfg; } child_data_t; @@ -500,12 +506,12 @@ static void log_child_data(child_data_t *data, char *name) DBG2(DBG_CFG, " life_packets = %llu", cfg->lifetime.packets.life); DBG2(DBG_CFG, " rand_packets = %llu", cfg->lifetime.packets.jitter); DBG2(DBG_CFG, " updown = %s", cfg->updown); - DBG2(DBG_CFG, " hostaccess = %u", cfg->hostaccess); - DBG2(DBG_CFG, " ipcomp = %u", cfg->ipcomp); + DBG2(DBG_CFG, " hostaccess = %u", cfg->options & OPT_HOSTACCESS); + DBG2(DBG_CFG, " ipcomp = %u", cfg->options & OPT_IPCOMP); DBG2(DBG_CFG, " mode = %N%s", ipsec_mode_names, cfg->mode, - cfg->proxy_mode ? "_PROXY" : ""); + cfg->options & OPT_PROXY_MODE ? "_PROXY" : ""); DBG2(DBG_CFG, " policies = %u", data->policies); - DBG2(DBG_CFG, " policies_fwd_out = %u", data->policies_fwd_out); + DBG2(DBG_CFG, " policies_fwd_out = %u", cfg->options & OPT_FWD_OUT_POLICIES); if (data->replay_window != REPLAY_UNDEFINED) { DBG2(DBG_CFG, " replay_window = %u", data->replay_window); @@ -525,6 +531,8 @@ static void log_child_data(child_data_t *data, char *name) DBG2(DBG_CFG, " proposals = %#P", data->proposals); DBG2(DBG_CFG, " local_ts = %#R", data->local_ts); DBG2(DBG_CFG, " remote_ts = %#R", data->remote_ts); + DBG2(DBG_CFG, " hw_offload = %u", cfg->options & OPT_HW_OFFLOAD); + DBG2(DBG_CFG, " sha256_96 = %u", cfg->options & OPT_SHA256_96); } /** @@ -827,13 +835,80 @@ CALLBACK(parse_mode, bool, if (parse_map(map, countof(map), &d, v)) { cfg->mode = d; - cfg->proxy_mode = (d == MODE_TRANSPORT) && (v.len > 9); + if ((d == MODE_TRANSPORT) && (v.len > 9)) + { + cfg->options |= OPT_PROXY_MODE; + } return TRUE; } return FALSE; } /** + * Enable a child_cfg_option_t + */ +static bool parse_option(child_cfg_option_t *out, child_cfg_option_t opt, + chunk_t v) +{ + bool val; + + if (parse_bool(&val, v)) + { + if (val) + { + *out |= opt; + } + return TRUE; + } + return FALSE; +} + +/** + * Parse OPT_HOSTACCESS option + */ +CALLBACK(parse_opt_haccess, bool, + child_cfg_option_t *out, chunk_t v) +{ + return parse_option(out, OPT_HOSTACCESS, v); +} + +/** + * Parse OPT_FWD_OUT_POLICIES option + */ +CALLBACK(parse_opt_fwd_out, bool, + child_cfg_option_t *out, chunk_t v) +{ + return parse_option(out, OPT_FWD_OUT_POLICIES, v); +} + +/** + * Parse OPT_FWD_OUT_POLICIES option + */ +CALLBACK(parse_opt_ipcomp, bool, + child_cfg_option_t *out, chunk_t v) +{ + return parse_option(out, OPT_IPCOMP, v); +} + +/** + * Parse OPT_HW_OFFLOAD option + */ +CALLBACK(parse_opt_hw_offl, bool, + child_cfg_option_t *out, chunk_t v) +{ + return parse_option(out, OPT_HW_OFFLOAD, v); +} + +/** + * Parse OPT_SHA256_96 option + */ +CALLBACK(parse_opt_sha256_96, bool, + child_cfg_option_t *out, chunk_t v) +{ + return parse_option(out, OPT_SHA256_96, v); +} + +/** * Parse an action_t */ CALLBACK(parse_action, bool, @@ -1336,6 +1411,7 @@ CALLBACK(parse_frag, bool, { enum_map_t map[] = { { "yes", FRAGMENTATION_YES }, + { "accept", FRAGMENTATION_ACCEPT }, { "no", FRAGMENTATION_NO }, { "force", FRAGMENTATION_FORCE }, }; @@ -1465,10 +1541,10 @@ CALLBACK(child_kv, bool, { parse_rule_t rules[] = { { "updown", parse_string, &child->cfg.updown }, - { "hostaccess", parse_bool, &child->cfg.hostaccess }, + { "hostaccess", parse_opt_haccess, &child->cfg.options }, { "mode", parse_mode, &child->cfg }, { "policies", parse_bool, &child->policies }, - { "policies_fwd_out", parse_bool, &child->policies_fwd_out }, + { "policies_fwd_out", parse_opt_fwd_out, &child->cfg.options }, { "replay_window", parse_uint32, &child->replay_window }, { "rekey_time", parse_time, &child->cfg.lifetime.time.rekey }, { "life_time", parse_time, &child->cfg.lifetime.time.life }, @@ -1482,7 +1558,7 @@ CALLBACK(child_kv, bool, { "dpd_action", parse_action, &child->cfg.dpd_action }, { "start_action", parse_action, &child->cfg.start_action }, { "close_action", parse_action, &child->cfg.close_action }, - { "ipcomp", parse_bool, &child->cfg.ipcomp }, + { "ipcomp", parse_opt_ipcomp, &child->cfg.options }, { "inactivity", parse_time, &child->cfg.inactivity }, { "reqid", parse_uint32, &child->cfg.reqid }, { "mark_in", parse_mark, &child->cfg.mark_in }, @@ -1490,6 +1566,8 @@ CALLBACK(child_kv, bool, { "tfc_padding", parse_tfc, &child->cfg.tfc }, { "priority", parse_uint32, &child->cfg.priority }, { "interface", parse_string, &child->cfg.interface }, + { "hw_offload", parse_opt_hw_offl, &child->cfg.options }, + { "sha256_96", parse_opt_sha256_96,&child->cfg.options }, }; return parse_rules(rules, countof(rules), name, value, @@ -1755,8 +1833,7 @@ CALLBACK(children_sn, bool, child.proposals->insert_last(child.proposals, proposal); } } - child.cfg.suppress_policies = !child.policies; - child.cfg.fwd_out_policies = child.policies_fwd_out; + child.cfg.options |= child.policies ? 0 : OPT_NO_POLICIES; check_lifetimes(&child.cfg.lifetime); diff --git a/src/libcharon/plugins/vici/vici_cred.c b/src/libcharon/plugins/vici/vici_cred.c index 6c7c194c2..5d8bf2f05 100644 --- a/src/libcharon/plugins/vici/vici_cred.c +++ b/src/libcharon/plugins/vici/vici_cred.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2015-2016 Andreas Steffen - * Copyright (C) 2016 Tobias Brunner + * Copyright (C) 2016-2017 Tobias Brunner * HSR Hochschule fuer Technik Rapperswil * * Copyright (C) 2014 Martin Willi @@ -206,9 +206,10 @@ CALLBACK(load_cert, vici_message_t*, CALLBACK(load_key, vici_message_t*, private_vici_cred_t *this, char *name, u_int id, vici_message_t *message) { + vici_builder_t *builder; key_type_t type; private_key_t *key; - chunk_t data; + chunk_t data, fp; char *str; str = message->get_str(message, NULL, "type"); @@ -248,12 +249,19 @@ CALLBACK(load_key, vici_message_t*, return create_reply("parsing %N private key failed", key_type_names, type); } + if (!key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fp)) + { + return create_reply("failed to get key id"); + } DBG1(DBG_CFG, "loaded %N private key", key_type_names, type); + builder = vici_builder_create(); + builder->add_kv(builder, "success", "yes"); + builder->add_kv(builder, "id", "%+B", &fp); this->creds->add_key(this->creds, key); - return create_reply(NULL); + return builder->finalize(builder); } CALLBACK(unload_key, vici_message_t*, diff --git a/src/libcharon/plugins/vici/vici_message.c b/src/libcharon/plugins/vici/vici_message.c index 58b896773..91d344994 100644 --- a/src/libcharon/plugins/vici/vici_message.c +++ b/src/libcharon/plugins/vici/vici_message.c @@ -135,11 +135,16 @@ typedef struct { } parse_enumerator_t; METHOD(enumerator_t, parse_enumerate, bool, - parse_enumerator_t *this, vici_type_t *out, char **name, chunk_t *value) + parse_enumerator_t *this, va_list args) { + vici_type_t *out; + chunk_t *value; + char **name; uint8_t type; chunk_t data; + VA_ARGS_VGET(args, out, name, value); + if (!this->reader->remaining(this->reader) || !this->reader->read_uint8(this->reader, &type)) { @@ -218,7 +223,8 @@ METHOD(vici_message_t, create_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_parse_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _parse_enumerate, .destroy = _parse_destroy, }, .reader = bio_reader_create(this->encoding), diff --git a/src/libcharon/plugins/vici/vici_query.c b/src/libcharon/plugins/vici/vici_query.c index c0f4e2de9..2cc59591f 100644 --- a/src/libcharon/plugins/vici/vici_query.c +++ b/src/libcharon/plugins/vici/vici_query.c @@ -107,7 +107,7 @@ static void list_mode(vici_builder_t *b, child_sa_t *child, child_cfg_t *cfg) cfg = child->get_config(child); } mode = child ? child->get_mode(child) : cfg->get_mode(cfg); - if (mode == MODE_TRANSPORT && cfg->use_proxy_mode(cfg)) + if (mode == MODE_TRANSPORT && cfg->has_option(cfg, OPT_PROXY_MODE)) { /* only report this if the negotiated mode is actually TRANSPORT */ sub_mode = "_PROXY"; } diff --git a/src/libcharon/plugins/whitelist/Makefile.in b/src/libcharon/plugins/whitelist/Makefile.in index b85961387..0347c5f53 100644 --- a/src/libcharon/plugins/whitelist/Makefile.in +++ b/src/libcharon/plugins/whitelist/Makefile.in @@ -365,6 +365,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -387,6 +388,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/whitelist/whitelist_listener.c b/src/libcharon/plugins/whitelist/whitelist_listener.c index 7e5b2f4e0..136554674 100644 --- a/src/libcharon/plugins/whitelist/whitelist_listener.c +++ b/src/libcharon/plugins/whitelist/whitelist_listener.c @@ -119,14 +119,19 @@ METHOD(whitelist_listener_t, remove_, void, DESTROY_IF(id); } -/** - * Enumerator filter, from hashtable (key, value) to single identity - */ -static bool whitelist_filter(rwlock_t *lock, identification_t **key, - identification_t **id, identification_t **value) +CALLBACK(whitelist_filter, bool, + rwlock_t *lock, enumerator_t *orig, va_list args) { - *id = *value; - return TRUE; + identification_t *key, *value, **out; + + VA_ARGS_VGET(args, out); + + if (orig->enumerate(orig, &key, &value)) + { + *out = value; + return TRUE; + } + return FALSE; } METHOD(whitelist_listener_t, create_enumerator, enumerator_t*, @@ -134,7 +139,7 @@ METHOD(whitelist_listener_t, create_enumerator, enumerator_t*, { this->lock->read_lock(this->lock); return enumerator_create_filter(this->ids->create_enumerator(this->ids), - (void*)whitelist_filter, this->lock, + whitelist_filter, this->lock, (void*)this->lock->unlock); } diff --git a/src/libcharon/plugins/xauth_eap/Makefile.in b/src/libcharon/plugins/xauth_eap/Makefile.in index a6554d6a9..28158a373 100644 --- a/src/libcharon/plugins/xauth_eap/Makefile.in +++ b/src/libcharon/plugins/xauth_eap/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/xauth_generic/Makefile.in b/src/libcharon/plugins/xauth_generic/Makefile.in index 87d627bc3..1dc267545 100644 --- a/src/libcharon/plugins/xauth_generic/Makefile.in +++ b/src/libcharon/plugins/xauth_generic/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/xauth_noauth/Makefile.in b/src/libcharon/plugins/xauth_noauth/Makefile.in index 13fb71aef..a610bab2a 100644 --- a/src/libcharon/plugins/xauth_noauth/Makefile.in +++ b/src/libcharon/plugins/xauth_noauth/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/plugins/xauth_pam/Makefile.in b/src/libcharon/plugins/xauth_pam/Makefile.in index 821d46e6b..8c31f2472 100644 --- a/src/libcharon/plugins/xauth_pam/Makefile.in +++ b/src/libcharon/plugins/xauth_pam/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/processing/jobs/delete_child_sa_job.c b/src/libcharon/processing/jobs/delete_child_sa_job.c index 70dbc1b4a..048b879f1 100644 --- a/src/libcharon/processing/jobs/delete_child_sa_job.c +++ b/src/libcharon/processing/jobs/delete_child_sa_job.c @@ -1,6 +1,7 @@ /* + * Copyright (C) 2017 Tobias Brunner * Copyright (C) 2006 Martin Willi - * Hochschule fuer Technik Rapperswil + * 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 @@ -24,19 +25,19 @@ typedef struct private_delete_child_sa_job_t private_delete_child_sa_job_t; * Private data of an delete_child_sa_job_t object. */ struct private_delete_child_sa_job_t { - /** + /** * Public delete_child_sa_job_t interface. */ delete_child_sa_job_t public; /** - * protocol of the CHILD_SA (ESP/AH) + * Protocol of the CHILD_SA (ESP/AH) */ protocol_id_t protocol; /** - * inbound SPI of the CHILD_SA + * Inbound SPI of the CHILD_SA */ uint32_t spi; @@ -49,12 +50,17 @@ struct private_delete_child_sa_job_t { * Delete for an expired CHILD_SA */ bool expired; + + /** + * Unique ID of the CHILD_SA + */ + uint32_t id; }; METHOD(job_t, destroy, void, private_delete_child_sa_job_t *this) { - this->dst->destroy(this->dst); + DESTROY_IF(this->dst); free(this); } @@ -63,17 +69,37 @@ METHOD(job_t, execute, job_requeue_t, { ike_sa_t *ike_sa; - ike_sa = charon->child_sa_manager->checkout(charon->child_sa_manager, - this->protocol, this->spi, this->dst, NULL); - if (ike_sa == NULL) + if (this->id) { - DBG1(DBG_JOB, "CHILD_SA %N/0x%08x/%H not found for delete", - protocol_id_names, this->protocol, htonl(this->spi), this->dst); + child_sa_t *child_sa; + + ike_sa = charon->child_sa_manager->checkout_by_id( + charon->child_sa_manager, this->id, &child_sa); + if (!ike_sa) + { + DBG1(DBG_JOB, "CHILD_SA {%d} not found for delete", this->id); + } + else + { + this->spi = child_sa->get_spi(child_sa, TRUE); + this->protocol = child_sa->get_protocol(child_sa); + } } else { - ike_sa->delete_child_sa(ike_sa, this->protocol, this->spi, this->expired); + ike_sa = charon->child_sa_manager->checkout(charon->child_sa_manager, + this->protocol, this->spi, this->dst, NULL); + if (!ike_sa) + { + DBG1(DBG_JOB, "CHILD_SA %N/0x%08x/%H not found for delete", + protocol_id_names, this->protocol, htonl(this->spi), this->dst); + } + } + if (ike_sa) + { + ike_sa->delete_child_sa(ike_sa, this->protocol, this->spi, + this->expired); charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa); } return JOB_REQUEUE_NONE; @@ -109,3 +135,24 @@ delete_child_sa_job_t *delete_child_sa_job_create(protocol_id_t protocol, return &this->public; } + +/* + * Described in header + */ +delete_child_sa_job_t *delete_child_sa_job_create_id(uint32_t id) +{ + private_delete_child_sa_job_t *this; + + INIT(this, + .public = { + .job_interface = { + .execute = _execute, + .get_priority = _get_priority, + .destroy = _destroy, + }, + }, + .id = id, + ); + + return &this->public; +} diff --git a/src/libcharon/processing/jobs/delete_child_sa_job.h b/src/libcharon/processing/jobs/delete_child_sa_job.h index 349f5debb..b2d5a11f6 100644 --- a/src/libcharon/processing/jobs/delete_child_sa_job.h +++ b/src/libcharon/processing/jobs/delete_child_sa_job.h @@ -1,6 +1,7 @@ /* + * Copyright (C) 2017 Tobias Brunner * Copyright (C) 2006 Martin Willi - * Hochschule fuer Technik Rapperswil + * 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 @@ -42,7 +43,7 @@ struct delete_child_sa_job_t { }; /** - * Creates a job of type DELETE_CHILD_SA. + * Creates a job that deletes a CHILD_SA. * * @param protocol protocol of the CHILD_SA * @param spi security parameter index of the CHILD_SA @@ -53,4 +54,12 @@ struct delete_child_sa_job_t { delete_child_sa_job_t *delete_child_sa_job_create(protocol_id_t protocol, uint32_t spi, host_t *dst, bool expired); +/** + * Creates a job that deletes a CHILD_SA identified by its unique ID. + * + * @param id unique ID of the CHILD_SA + * @return delete_child_sa_job_t object + */ +delete_child_sa_job_t *delete_child_sa_job_create_id(uint32_t id); + #endif /** DELETE_CHILD_SA_JOB_H_ @}*/ diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c index b9dd59b07..3d9f6133b 100644 --- a/src/libcharon/sa/child_sa.c +++ b/src/libcharon/sa/child_sa.c @@ -1,6 +1,6 @@ /* + * Copyright (C) 2006-2017 Tobias Brunner * Copyright (C) 2016 Andreas Steffen - * Copyright (C) 2006-2016 Tobias Brunner * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2006 Daniel Roethlisberger * Copyright (C) 2005 Jan Hutter @@ -40,6 +40,12 @@ ENUM(child_sa_state_names, CHILD_CREATED, CHILD_DESTROYING, "DESTROYING", ); +ENUM(child_sa_outbound_state_names, CHILD_OUTBOUND_NONE, CHILD_OUTBOUND_INSTALLED, + "NONE", + "REGISTERED", + "INSTALLED", +); + typedef struct private_child_sa_t private_child_sa_t; /** @@ -92,6 +98,31 @@ struct private_child_sa_t { array_t *other_ts; /** + * Outbound encryption key cached during a rekeying + */ + chunk_t encr_r; + + /** + * Outbound integrity key cached during a rekeying + */ + chunk_t integ_r; + + /** + * Whether the outbound SA has only been registered yet during a rekeying + */ + child_sa_outbound_state_t outbound_state; + + /** + * Whether the peer supports TFCv3 + */ + bool tfcv3; + + /** + * The outbound SPI of the CHILD_SA that replaced this one during a rekeying + */ + uint32_t rekey_spi; + + /** * Protocol used to protect this SA, ESP|AH */ protocol_id_t protocol; @@ -265,6 +296,10 @@ METHOD(child_sa_t, get_config, child_cfg_t*, METHOD(child_sa_t, set_state, void, private_child_sa_t *this, child_sa_state_t state) { + DBG2(DBG_CHD, "CHILD_SA %s{%d} state change: %N => %N", + get_name(this), this->unique_id, + child_sa_state_names, this->state, + child_sa_state_names, state); charon->bus->child_state_change(charon->bus, &this->public, state); this->state = state; } @@ -275,6 +310,12 @@ METHOD(child_sa_t, get_state, child_sa_state_t, return this->state; } +METHOD(child_sa_t, get_outbound_state, child_sa_outbound_state_t, + private_child_sa_t *this) +{ + return this->outbound_state; +} + METHOD(child_sa_t, get_spi, uint32_t, private_child_sa_t *this, bool inbound) { @@ -394,10 +435,11 @@ struct policy_enumerator_t { }; METHOD(enumerator_t, policy_enumerate, bool, - policy_enumerator_t *this, traffic_selector_t **my_out, - traffic_selector_t **other_out) + policy_enumerator_t *this, va_list args) { - traffic_selector_t *other_ts; + traffic_selector_t *other_ts, **my_out, **other_out; + + VA_ARGS_VGET(args, my_out, other_out); while (this->ts || this->mine->enumerate(this->mine, &this->ts)) { @@ -446,7 +488,8 @@ METHOD(child_sa_t, create_policy_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_policy_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _policy_enumerate, .destroy = _policy_destroy, }, .mine = array_create_enumerator(this->my_ts), @@ -504,7 +547,7 @@ static status_t update_usebytes(private_child_sa_t *this, bool inbound) } else { - if (this->other_spi) + if (this->other_spi && this->outbound_state == CHILD_OUTBOUND_INSTALLED) { kernel_ipsec_sa_id_t id = { .src = this->my_addr, @@ -691,14 +734,16 @@ METHOD(child_sa_t, alloc_cpi, uint16_t, return 0; } -METHOD(child_sa_t, install, status_t, - private_child_sa_t *this, chunk_t encr, chunk_t integ, uint32_t spi, - uint16_t cpi, bool initiator, bool inbound, bool tfcv3, - linked_list_t *my_ts, linked_list_t *other_ts) +/** + * Install the given SA in the kernel + */ +static status_t install_internal(private_child_sa_t *this, chunk_t encr, + chunk_t integ, uint32_t spi, uint16_t cpi, bool initiator, bool inbound, + bool tfcv3) { uint16_t enc_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED, size; uint16_t esn = NO_EXT_SEQ_NUMBERS; - linked_list_t *src_ts = NULL, *dst_ts = NULL; + linked_list_t *my_ts, *other_ts, *src_ts, *dst_ts; time_t now; kernel_ipsec_sa_id_t id; kernel_ipsec_add_sa_t sa; @@ -708,6 +753,12 @@ METHOD(child_sa_t, install, status_t, status_t status; bool update = FALSE; + /* BEET requires the bound address from the traffic selectors */ + my_ts = linked_list_create_from_enumerator( + array_create_enumerator(this->my_ts)); + other_ts = linked_list_create_from_enumerator( + array_create_enumerator(this->other_ts)); + /* now we have to decide which spi to use. Use self allocated, if "in", * or the one in the proposal, if not "in" (others). Additionally, * source and dest host switch depending on the role */ @@ -721,6 +772,8 @@ METHOD(child_sa_t, install, status_t, } this->my_spi = spi; this->my_cpi = cpi; + dst_ts = my_ts; + src_ts = other_ts; } else { @@ -728,11 +781,14 @@ METHOD(child_sa_t, install, status_t, dst = this->other_addr; this->other_spi = spi; this->other_cpi = cpi; + src_ts = my_ts; + dst_ts = other_ts; if (tfcv3) { tfc = this->config->get_tfc(this->config); } + this->outbound_state = CHILD_OUTBOUND_INSTALLED; } DBG2(DBG_CHD, "adding %s %N SA", inbound ? "inbound" : "outbound", @@ -748,12 +804,22 @@ METHOD(child_sa_t, install, status_t, this->proposal->get_algorithm(this->proposal, EXTENDED_SEQUENCE_NUMBERS, &esn, NULL); + if (int_alg == AUTH_HMAC_SHA2_256_128 && + this->config->has_option(this->config, OPT_SHA256_96)) + { + DBG2(DBG_CHD, " using %N with 96-bit truncation", + integrity_algorithm_names, int_alg); + int_alg = AUTH_HMAC_SHA2_256_96; + } + if (!this->reqid_allocated && !this->static_reqid) { status = charon->kernel->alloc_reqid(charon->kernel, my_ts, other_ts, this->mark_in, this->mark_out, &this->reqid); if (status != SUCCESS) { + my_ts->destroy(my_ts); + other_ts->destroy(other_ts); return status; } this->reqid_allocated = TRUE; @@ -783,18 +849,6 @@ METHOD(child_sa_t, install, status_t, lifetime->time.rekey = 0; } - /* BEET requires the bound address from the traffic selectors */ - if (inbound) - { - dst_ts = my_ts; - src_ts = other_ts; - } - else - { - src_ts = my_ts; - dst_ts = other_ts; - } - id = (kernel_ipsec_sa_id_t){ .src = src, .dst = dst, @@ -818,6 +872,7 @@ METHOD(child_sa_t, install, status_t, .ipcomp = this->ipcomp, .cpi = cpi, .encap = this->encap, + .hw_offload = this->config->has_option(this->config, OPT_HW_OFFLOAD), .esn = esn, .initiator = initiator, .inbound = inbound, @@ -826,11 +881,21 @@ METHOD(child_sa_t, install, status_t, status = charon->kernel->add_sa(charon->kernel, &id, &sa); + my_ts->destroy(my_ts); + other_ts->destroy(other_ts); free(lifetime); return status; } +METHOD(child_sa_t, install, status_t, + private_child_sa_t *this, chunk_t encr, chunk_t integ, uint32_t spi, + uint16_t cpi, bool initiator, bool inbound, bool tfcv3) +{ + return install_internal(this, encr, integ, spi, cpi, initiator, inbound, + tfcv3); +} + /** * Check kernel interface if policy updates are required */ @@ -887,34 +952,21 @@ static void prepare_sa_cfg(private_child_sa_t *this, ipsec_sa_cfg_t *my_sa, } /** - * Install 3 policies: out, in and forward + * Install inbound policie(s): in, fwd */ -static status_t install_policies_internal(private_child_sa_t *this, +static status_t install_policies_inbound(private_child_sa_t *this, host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts, traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa, ipsec_sa_cfg_t *other_sa, policy_type_t type, policy_priority_t priority, uint32_t manual_prio) { - kernel_ipsec_policy_id_t out_id = { - .dir = POLICY_OUT, - .src_ts = my_ts, - .dst_ts = other_ts, - .mark = this->mark_out, - .interface = this->config->get_interface(this->config), - }, in_id = { + kernel_ipsec_policy_id_t in_id = { .dir = POLICY_IN, .src_ts = other_ts, .dst_ts = my_ts, .mark = this->mark_in, }; - kernel_ipsec_manage_policy_t out_policy = { - .type = type, - .prio = priority, - .manual_prio = manual_prio, - .src = my_addr, - .dst = other_addr, - .sa = other_sa, - }, in_policy = { + kernel_ipsec_manage_policy_t in_policy = { .type = type, .prio = priority, .manual_prio = manual_prio, @@ -924,13 +976,45 @@ static status_t install_policies_internal(private_child_sa_t *this, }; status_t status = SUCCESS; - status |= charon->kernel->add_policy(charon->kernel, &out_id, &out_policy); status |= charon->kernel->add_policy(charon->kernel, &in_id, &in_policy); if (this->mode != MODE_TRANSPORT) { in_id.dir = POLICY_FWD; status |= charon->kernel->add_policy(charon->kernel, &in_id, &in_policy); + } + return status; +} +/** + * Install outbound policie(s): out, [fwd] + */ +static status_t install_policies_outbound(private_child_sa_t *this, + host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts, + traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa, + ipsec_sa_cfg_t *other_sa, policy_type_t type, + policy_priority_t priority, uint32_t manual_prio) +{ + kernel_ipsec_policy_id_t out_id = { + .dir = POLICY_OUT, + .src_ts = my_ts, + .dst_ts = other_ts, + .mark = this->mark_out, + .interface = this->config->get_interface(this->config), + }; + kernel_ipsec_manage_policy_t out_policy = { + .type = type, + .prio = priority, + .manual_prio = manual_prio, + .src = my_addr, + .dst = other_addr, + .sa = other_sa, + }; + status_t status = SUCCESS; + + status |= charon->kernel->add_policy(charon->kernel, &out_id, &out_policy); + + if (this->mode != MODE_TRANSPORT && this->policies_fwd_out) + { /* install an "outbound" FWD policy in case there is a drop policy * matching outbound forwarded traffic, to allow another tunnel to use * the reversed subnets and do the same we don't set a reqid (this also @@ -939,52 +1023,56 @@ static status_t install_policies_internal(private_child_sa_t *this, * policies of two SAs we install them with reduced priority. As they * basically act as bypass policies for drop policies we use a higher * priority than is used for them. */ - if (this->policies_fwd_out) + out_id.dir = POLICY_FWD; + other_sa->reqid = 0; + if (priority == POLICY_PRIORITY_DEFAULT) { - out_id.dir = POLICY_FWD; - other_sa->reqid = 0; - if (priority == POLICY_PRIORITY_DEFAULT) - { - out_policy.prio = POLICY_PRIORITY_ROUTED; - } - status |= charon->kernel->add_policy(charon->kernel, &out_id, - &out_policy); - /* reset the reqid for any other further policies */ - other_sa->reqid = this->reqid; + out_policy.prio = POLICY_PRIORITY_ROUTED; } + status |= charon->kernel->add_policy(charon->kernel, &out_id, + &out_policy); + /* reset the reqid for any other further policies */ + other_sa->reqid = this->reqid; } return status; } /** - * Delete 3 policies: out, in and forward + * Install all policies */ -static void del_policies_internal(private_child_sa_t *this, +static status_t install_policies_internal(private_child_sa_t *this, + host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts, + traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa, + ipsec_sa_cfg_t *other_sa, policy_type_t type, + policy_priority_t priority, uint32_t manual_prio) +{ + status_t status = SUCCESS; + + status |= install_policies_inbound(this, my_addr, other_addr, my_ts, + other_ts, my_sa, other_sa, type, + priority, manual_prio); + status |= install_policies_outbound(this, my_addr, other_addr, my_ts, + other_ts, my_sa, other_sa, type, + priority, manual_prio); + return status; +} + +/** + * Delete inbound policies: in, fwd + */ +static void del_policies_inbound(private_child_sa_t *this, host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts, traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa, ipsec_sa_cfg_t *other_sa, policy_type_t type, policy_priority_t priority, uint32_t manual_prio) { - kernel_ipsec_policy_id_t out_id = { - .dir = POLICY_OUT, - .src_ts = my_ts, - .dst_ts = other_ts, - .mark = this->mark_out, - .interface = this->config->get_interface(this->config), - }, in_id = { + kernel_ipsec_policy_id_t in_id = { .dir = POLICY_IN, .src_ts = other_ts, .dst_ts = my_ts, .mark = this->mark_in, }; - kernel_ipsec_manage_policy_t out_policy = { - .type = type, - .prio = priority, - .manual_prio = manual_prio, - .src = my_addr, - .dst = other_addr, - .sa = other_sa, - }, in_policy = { + kernel_ipsec_manage_policy_t in_policy = { .type = type, .prio = priority, .manual_prio = manual_prio, @@ -993,49 +1081,83 @@ static void del_policies_internal(private_child_sa_t *this, .sa = my_sa, }; - charon->kernel->del_policy(charon->kernel, &out_id, &out_policy); charon->kernel->del_policy(charon->kernel, &in_id, &in_policy); + if (this->mode != MODE_TRANSPORT) { in_id.dir = POLICY_FWD; charon->kernel->del_policy(charon->kernel, &in_id, &in_policy); + } +} - if (this->policies_fwd_out) +/** + * Delete outbound policies: out, [fwd] + */ +static void del_policies_outbound(private_child_sa_t *this, + host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts, + traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa, + ipsec_sa_cfg_t *other_sa, policy_type_t type, + policy_priority_t priority, uint32_t manual_prio) +{ + kernel_ipsec_policy_id_t out_id = { + .dir = POLICY_OUT, + .src_ts = my_ts, + .dst_ts = other_ts, + .mark = this->mark_out, + .interface = this->config->get_interface(this->config), + }; + kernel_ipsec_manage_policy_t out_policy = { + .type = type, + .prio = priority, + .manual_prio = manual_prio, + .src = my_addr, + .dst = other_addr, + .sa = other_sa, + }; + + charon->kernel->del_policy(charon->kernel, &out_id, &out_policy); + + if (this->mode != MODE_TRANSPORT && this->policies_fwd_out) + { + out_id.dir = POLICY_FWD; + other_sa->reqid = 0; + if (priority == POLICY_PRIORITY_DEFAULT) { - out_id.dir = POLICY_FWD; - other_sa->reqid = 0; - if (priority == POLICY_PRIORITY_DEFAULT) - { - out_policy.prio = POLICY_PRIORITY_ROUTED; - } - charon->kernel->del_policy(charon->kernel, &out_id, &out_policy); - other_sa->reqid = this->reqid; + out_policy.prio = POLICY_PRIORITY_ROUTED; } + charon->kernel->del_policy(charon->kernel, &out_id, &out_policy); + other_sa->reqid = this->reqid; } } -METHOD(child_sa_t, add_policies, status_t, +/** + * Delete in- and outbound policies + */ +static void del_policies_internal(private_child_sa_t *this, + host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts, + traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa, + ipsec_sa_cfg_t *other_sa, policy_type_t type, + policy_priority_t priority, uint32_t manual_prio) +{ + del_policies_outbound(this, my_addr, other_addr, my_ts, other_ts, my_sa, + other_sa, type, priority, manual_prio); + del_policies_inbound(this, my_addr, other_addr, my_ts, other_ts, my_sa, + other_sa, type, priority, manual_prio); +} + +METHOD(child_sa_t, set_policies, void, private_child_sa_t *this, linked_list_t *my_ts_list, linked_list_t *other_ts_list) { enumerator_t *enumerator; traffic_selector_t *my_ts, *other_ts; - status_t status = SUCCESS; - if (!this->reqid_allocated && !this->static_reqid) + if (array_count(this->my_ts)) { - /* trap policy, get or confirm reqid */ - status = charon->kernel->alloc_reqid( - charon->kernel, my_ts_list, other_ts_list, - this->mark_in, this->mark_out, &this->reqid); - if (status != SUCCESS) - { - return status; - } - this->reqid_allocated = TRUE; + array_destroy_offset(this->my_ts, + offsetof(traffic_selector_t, destroy)); + this->my_ts = array_create(0, 0); } - - /* apply traffic selectors */ enumerator = my_ts_list->create_enumerator(my_ts_list); while (enumerator->enumerate(enumerator, &my_ts)) { @@ -1044,6 +1166,12 @@ METHOD(child_sa_t, add_policies, status_t, enumerator->destroy(enumerator); array_sort(this->my_ts, (void*)traffic_selector_cmp, NULL); + if (array_count(this->other_ts)) + { + array_destroy_offset(this->other_ts, + offsetof(traffic_selector_t, destroy)); + this->other_ts = array_create(0, 0); + } enumerator = other_ts_list->create_enumerator(other_ts_list); while (enumerator->enumerate(enumerator, &other_ts)) { @@ -1051,12 +1179,40 @@ METHOD(child_sa_t, add_policies, status_t, } enumerator->destroy(enumerator); array_sort(this->other_ts, (void*)traffic_selector_cmp, NULL); +} + +METHOD(child_sa_t, install_policies, status_t, + private_child_sa_t *this) +{ + enumerator_t *enumerator; + linked_list_t *my_ts_list, *other_ts_list; + traffic_selector_t *my_ts, *other_ts; + status_t status = SUCCESS; - if (this->config->install_policy(this->config)) + if (!this->reqid_allocated && !this->static_reqid) + { + my_ts_list = linked_list_create_from_enumerator( + array_create_enumerator(this->my_ts)); + other_ts_list = linked_list_create_from_enumerator( + array_create_enumerator(this->other_ts)); + status = charon->kernel->alloc_reqid( + charon->kernel, my_ts_list, other_ts_list, + this->mark_in, this->mark_out, &this->reqid); + my_ts_list->destroy(my_ts_list); + other_ts_list->destroy(other_ts_list); + if (status != SUCCESS) + { + return status; + } + this->reqid_allocated = TRUE; + } + + if (!this->config->has_option(this->config, OPT_NO_POLICIES)) { policy_priority_t priority; ipsec_sa_cfg_t my_sa, other_sa; uint32_t manual_prio; + bool install_outbound; prepare_sa_cfg(this, &my_sa, &other_sa); manual_prio = this->config->get_manual_prio(this->config); @@ -1066,6 +1222,7 @@ METHOD(child_sa_t, add_policies, status_t, this->trap = this->state == CHILD_CREATED; priority = this->trap ? POLICY_PRIORITY_ROUTED : POLICY_PRIORITY_DEFAULT; + install_outbound = this->outbound_state != CHILD_OUTBOUND_REGISTERED; /* enumerate pairs of traffic selectors */ enumerator = create_policy_enumerator(this); @@ -1074,20 +1231,27 @@ METHOD(child_sa_t, add_policies, status_t, /* install outbound drop policy to avoid packets leaving unencrypted * when updating policies */ if (priority == POLICY_PRIORITY_DEFAULT && manual_prio == 0 && - require_policy_update()) + require_policy_update() && install_outbound) { - status |= install_policies_internal(this, this->my_addr, + status |= install_policies_outbound(this, this->my_addr, this->other_addr, my_ts, other_ts, &my_sa, &other_sa, POLICY_DROP, POLICY_PRIORITY_FALLBACK, 0); } - /* install policies */ - status |= install_policies_internal(this, this->my_addr, + status |= install_policies_inbound(this, this->my_addr, this->other_addr, my_ts, other_ts, &my_sa, &other_sa, POLICY_IPSEC, priority, manual_prio); + if (install_outbound) + { + status |= install_policies_outbound(this, this->my_addr, + this->other_addr, my_ts, other_ts, + &my_sa, &other_sa, POLICY_IPSEC, + priority, manual_prio); + + } if (status != SUCCESS) { break; @@ -1103,13 +1267,150 @@ METHOD(child_sa_t, add_policies, status_t, return status; } -/** - * Callback to reinstall a virtual IP - */ -static void reinstall_vip(host_t *vip, host_t *me) +METHOD(child_sa_t, register_outbound, void, + private_child_sa_t *this, chunk_t encr, chunk_t integ, uint32_t spi, + uint16_t cpi, bool tfcv3) +{ + DBG2(DBG_CHD, "registering outbound %N SA", protocol_id_names, + this->protocol); + DBG2(DBG_CHD, " SPI 0x%.8x, src %H dst %H", ntohl(spi), this->my_addr, + this->other_addr); + + this->other_spi = spi; + this->other_cpi = cpi; + this->encr_r = chunk_clone(encr); + this->integ_r = chunk_clone(integ); + this->tfcv3 = tfcv3; + this->outbound_state = CHILD_OUTBOUND_REGISTERED; +} + +METHOD(child_sa_t, install_outbound, status_t, + private_child_sa_t *this) +{ + enumerator_t *enumerator; + traffic_selector_t *my_ts, *other_ts; + status_t status; + + status = install_internal(this, this->encr_r, this->integ_r, + this->other_spi, this->other_cpi, FALSE, FALSE, + this->tfcv3); + chunk_clear(&this->encr_r); + chunk_clear(&this->integ_r); + if (status != SUCCESS) + { + return status; + } + if (!this->config->has_option(this->config, OPT_NO_POLICIES)) + { + ipsec_sa_cfg_t my_sa, other_sa; + uint32_t manual_prio; + + prepare_sa_cfg(this, &my_sa, &other_sa); + manual_prio = this->config->get_manual_prio(this->config); + + enumerator = create_policy_enumerator(this); + while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) + { + /* install outbound drop policy to avoid packets leaving unencrypted + * when updating policies */ + if (manual_prio == 0 && require_policy_update()) + { + status |= install_policies_outbound(this, this->my_addr, + this->other_addr, my_ts, other_ts, + &my_sa, &other_sa, POLICY_DROP, + POLICY_PRIORITY_FALLBACK, 0); + } + status |= install_policies_outbound(this, this->my_addr, + this->other_addr, my_ts, other_ts, + &my_sa, &other_sa, POLICY_IPSEC, + POLICY_PRIORITY_DEFAULT, manual_prio); + if (status != SUCCESS) + { + break; + } + } + enumerator->destroy(enumerator); + } + return status; +} + +METHOD(child_sa_t, remove_outbound, void, + private_child_sa_t *this) +{ + enumerator_t *enumerator; + traffic_selector_t *my_ts, *other_ts; + + switch (this->outbound_state) + { + case CHILD_OUTBOUND_INSTALLED: + break; + case CHILD_OUTBOUND_REGISTERED: + chunk_clear(&this->encr_r); + chunk_clear(&this->integ_r); + this->outbound_state = CHILD_OUTBOUND_NONE; + /* fall-through */ + case CHILD_OUTBOUND_NONE: + return; + } + + if (!this->config->has_option(this->config, OPT_NO_POLICIES)) + { + ipsec_sa_cfg_t my_sa, other_sa; + uint32_t manual_prio; + + prepare_sa_cfg(this, &my_sa, &other_sa); + manual_prio = this->config->get_manual_prio(this->config); + + enumerator = create_policy_enumerator(this); + while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) + { + del_policies_outbound(this, this->my_addr, this->other_addr, + my_ts, other_ts, &my_sa, &other_sa, + POLICY_IPSEC, POLICY_PRIORITY_DEFAULT, + manual_prio); + if (manual_prio == 0 && require_policy_update()) + { + del_policies_outbound(this, this->my_addr, this->other_addr, + my_ts, other_ts, &my_sa, &other_sa, + POLICY_DROP, POLICY_PRIORITY_FALLBACK, 0); + } + } + enumerator->destroy(enumerator); + } + + kernel_ipsec_sa_id_t id = { + .src = this->my_addr, + .dst = this->other_addr, + .spi = this->other_spi, + .proto = proto_ike2ip(this->protocol), + .mark = this->mark_out, + }; + kernel_ipsec_del_sa_t sa = { + .cpi = this->other_cpi, + }; + charon->kernel->del_sa(charon->kernel, &id, &sa); + this->outbound_state = CHILD_OUTBOUND_NONE; +} + +METHOD(child_sa_t, set_rekey_spi, void, + private_child_sa_t *this, uint32_t spi) +{ + this->rekey_spi = spi; +} + +METHOD(child_sa_t, get_rekey_spi, uint32_t, + private_child_sa_t *this) { + return this->rekey_spi; +} + +CALLBACK(reinstall_vip, void, + host_t *vip, va_list args) +{ + host_t *me; char *iface; + VA_ARGS_VGET(args, me); if (charon->kernel->get_interface(charon->kernel, me, &iface)) { charon->kernel->del_ip(charon->kernel, vip, -1, TRUE); @@ -1134,8 +1435,9 @@ METHOD(child_sa_t, update, status_t, old = this->state; set_state(this, CHILD_UPDATING); - transport_proxy_mode = this->config->use_proxy_mode(this->config) && - this->mode == MODE_TRANSPORT; + transport_proxy_mode = this->mode == MODE_TRANSPORT && + this->config->has_option(this->config, + OPT_PROXY_MODE); if (!transport_proxy_mode) { @@ -1189,7 +1491,8 @@ METHOD(child_sa_t, update, status_t, } } - if (this->config->install_policy(this->config) && require_policy_update()) + if (!this->config->has_option(this->config, OPT_NO_POLICIES) && + require_policy_update()) { if (!me->ip_equals(me, this->my_addr) || !other->ip_equals(other, this->other_addr)) @@ -1229,7 +1532,7 @@ METHOD(child_sa_t, update, status_t, /* we reinstall the virtual IP to handle interface roaming * correctly */ - vips->invoke_function(vips, (void*)reinstall_vip, me); + vips->invoke_function(vips, reinstall_vip, me); /* reinstall updated policies */ install_policies_internal(this, me, other, my_ts, other_ts, @@ -1239,12 +1542,12 @@ METHOD(child_sa_t, update, status_t, /* update fallback policies after the new policy is in place */ if (manual_prio == 0) { - del_policies_internal(this, this->my_addr, this->other_addr, + del_policies_outbound(this, this->my_addr, this->other_addr, old_my_ts ?: my_ts, old_other_ts ?: other_ts, &my_sa, &other_sa, POLICY_DROP, POLICY_PRIORITY_FALLBACK, 0); - install_policies_internal(this, me, other, my_ts, other_ts, + install_policies_outbound(this, me, other, my_ts, other_ts, &my_sa, &other_sa, POLICY_DROP, POLICY_PRIORITY_FALLBACK, 0); } @@ -1287,25 +1590,35 @@ METHOD(child_sa_t, destroy, void, set_state(this, CHILD_DESTROYING); - if (this->config->install_policy(this->config)) + if (!this->config->has_option(this->config, OPT_NO_POLICIES)) { ipsec_sa_cfg_t my_sa, other_sa; uint32_t manual_prio; + bool del_outbound; prepare_sa_cfg(this, &my_sa, &other_sa); manual_prio = this->config->get_manual_prio(this->config); + del_outbound = this->trap || + this->outbound_state == CHILD_OUTBOUND_INSTALLED; /* delete all policies in the kernel */ enumerator = create_policy_enumerator(this); while (enumerator->enumerate(enumerator, &my_ts, &other_ts)) { - del_policies_internal(this, this->my_addr, this->other_addr, - my_ts, other_ts, &my_sa, &other_sa, - POLICY_IPSEC, priority, manual_prio); - if (priority == POLICY_PRIORITY_DEFAULT && manual_prio == 0 && - require_policy_update()) + if (del_outbound) { - del_policies_internal(this, this->my_addr, this->other_addr, + del_policies_outbound(this, this->my_addr, + this->other_addr, my_ts, other_ts, + &my_sa, &other_sa, POLICY_IPSEC, + priority, manual_prio); + } + del_policies_inbound(this, this->my_addr, this->other_addr, + my_ts, other_ts, &my_sa, &other_sa, + POLICY_IPSEC, priority, manual_prio); + if (!this->trap && manual_prio == 0 && require_policy_update() && + del_outbound) + { + del_policies_outbound(this, this->my_addr, this->other_addr, my_ts, other_ts, &my_sa, &other_sa, POLICY_DROP, POLICY_PRIORITY_FALLBACK, 0); } @@ -1327,7 +1640,7 @@ METHOD(child_sa_t, destroy, void, }; charon->kernel->del_sa(charon->kernel, &id, &sa); } - if (this->other_spi) + if (this->other_spi && this->outbound_state == CHILD_OUTBOUND_INSTALLED) { kernel_ipsec_sa_id_t id = { .src = this->my_addr, @@ -1357,6 +1670,8 @@ METHOD(child_sa_t, destroy, void, this->other_addr->destroy(this->other_addr); DESTROY_IF(this->proposal); this->config->destroy(this->config); + chunk_clear(&this->encr_r); + chunk_clear(&this->integ_r); free(this); } @@ -1414,6 +1729,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other, .get_config = _get_config, .get_state = _get_state, .set_state = _set_state, + .get_outbound_state = _get_outbound_state, .get_spi = _get_spi, .get_cpi = _get_cpi, .get_protocol = _get_protocol, @@ -1436,8 +1752,14 @@ child_sa_t * child_sa_create(host_t *me, host_t* other, .alloc_spi = _alloc_spi, .alloc_cpi = _alloc_cpi, .install = _install, + .register_outbound = _register_outbound, + .install_outbound = _install_outbound, + .remove_outbound = _remove_outbound, + .set_rekey_spi = _set_rekey_spi, + .get_rekey_spi = _get_rekey_spi, .update = _update, - .add_policies = _add_policies, + .set_policies = _set_policies, + .install_policies = _install_policies, .create_ts_enumerator = _create_ts_enumerator, .create_policy_enumerator = _create_policy_enumerator, .destroy = _destroy, @@ -1456,7 +1778,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other, .mark_in = config->get_mark(config, TRUE), .mark_out = config->get_mark(config, FALSE), .install_time = time_monotonic(NULL), - .policies_fwd_out = config->install_fwd_out_policy(config), + .policies_fwd_out = config->has_option(config, OPT_FWD_OUT_POLICIES), ); this->config = config; @@ -1509,7 +1831,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other, /* MIPv6 proxy transport mode sets SA endpoints to TS hosts */ if (config->get_mode(config) == MODE_TRANSPORT && - config->use_proxy_mode(config)) + config->has_option(config, OPT_PROXY_MODE)) { this->mode = MODE_TRANSPORT; diff --git a/src/libcharon/sa/child_sa.h b/src/libcharon/sa/child_sa.h index bc7df996a..b9a913da1 100644 --- a/src/libcharon/sa/child_sa.h +++ b/src/libcharon/sa/child_sa.h @@ -1,8 +1,8 @@ /* - * Copyright (C) 2006-2008 Tobias Brunner + * Copyright (C) 2006-2017 Tobias Brunner * Copyright (C) 2006-2008 Martin Willi * Copyright (C) 2006 Daniel Roethlisberger - * Hochschule fuer Technik Rapperswil + * 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 @@ -24,6 +24,7 @@ #define CHILD_SA_H_ typedef enum child_sa_state_t child_sa_state_t; +typedef enum child_sa_outbound_state_t child_sa_outbound_state_t; typedef struct child_sa_t child_sa_t; #include <library.h> @@ -53,7 +54,7 @@ enum child_sa_state_t { CHILD_INSTALLING, /** - * Installed an in-use CHILD_SA + * Installed both SAs of a CHILD_SA */ CHILD_INSTALLED, @@ -94,6 +95,32 @@ enum child_sa_state_t { extern enum_name_t *child_sa_state_names; /** + * States of the outbound SA of a CHILD_SA + */ +enum child_sa_outbound_state_t { + + /** + * Outbound SA is not installed + */ + CHILD_OUTBOUND_NONE, + + /** + * Data for the outbound SA has been registered, but not installed yet + */ + CHILD_OUTBOUND_REGISTERED, + + /** + * The outbound SA is currently installed + */ + CHILD_OUTBOUND_INSTALLED, +}; + +/** + * enum strings for child_sa_outbound_state_t. + */ +extern enum_name_t *child_sa_outbound_state_names; + +/** * Represents an IPsec SAs between two hosts. * * A child_sa_t contains two SAs. SAs for both @@ -152,7 +179,14 @@ struct child_sa_t { * * @return CHILD_SA state */ - child_sa_state_t (*get_state) (child_sa_t *this); + child_sa_state_t (*get_state)(child_sa_t *this); + + /** + * Get the state of the outbound SA. + * + * @return outbound SA state + */ + child_sa_outbound_state_t (*get_outbound_state)(child_sa_t *this); /** * Set the state of the CHILD_SA. @@ -347,6 +381,8 @@ struct child_sa_t { /** * Install an IPsec SA for one direction. * + * set_policies() should be called before calling this. + * * @param encr encryption key, if any * @param integ integrity key * @param spi SPI to use, allocated for inbound @@ -354,26 +390,84 @@ struct child_sa_t { * @param initiator TRUE if initiator of exchange resulting in this SA * @param inbound TRUE to install an inbound SA, FALSE for outbound * @param tfcv3 TRUE if peer supports ESPv3 TFC - * @param my_ts negotiated local traffic selector list - * @param other_ts negotiated remote traffic selector list * @return SUCCESS or FAILED */ status_t (*install)(child_sa_t *this, chunk_t encr, chunk_t integ, uint32_t spi, uint16_t cpi, - bool initiator, bool inbound, bool tfcv3, - linked_list_t *my_ts, linked_list_t *other_ts); + bool initiator, bool inbound, bool tfcv3); + + /** + * Register data for the installation of an outbound SA as responder during + * a rekeying. + * + * The SA is not installed until install_outbound() is called. + * + * @param encr encryption key, if any (cloned) + * @param integ integrity key (cloned) + * @param spi SPI to use, allocated for inbound + * @param cpi CPI to use, allocated for outbound + * @param tfcv3 TRUE if peer supports ESPv3 TFC + */ + void (*register_outbound)(child_sa_t *this, chunk_t encr, chunk_t integ, + uint32_t spi, uint16_t cpi, bool tfcv3); + + /** + * Install the outbound SA and the outbound policies as responder during a + * rekeying. + * + * @return SUCCESS or FAILED + */ + status_t (*install_outbound)(child_sa_t *this); + + /** + * Remove the outbound SA and the outbound policies after a rekeying. + */ + void (*remove_outbound)(child_sa_t *this); + /** - * Install the policies using some traffic selectors. + * Configure the policies using some traffic selectors. * * Supplied lists of traffic_selector_t's specify the policies * to use for this child sa. * - * @param my_ts traffic selectors for local site - * @param other_ts traffic selectors for remote site + * Install the policies by calling install_policies(). + * + * This should be called before calling install() so the traffic selectors + * may be passed to the kernel interface when installing the SAs. + * + * @param my_ts traffic selectors for local site (cloned) + * @param other_ts traffic selectors for remote site (cloned) + */ + void (*set_policies)(child_sa_t *this, linked_list_t *my_ts_list, + linked_list_t *other_ts_list); + + /** + * Install the configured policies. + * + * If register_outbound() was called previously this only installs the + * inbound and forward policies, the outbound policies are installed when + * install_outbound() is called. + * * @return SUCCESS or FAILED */ - status_t (*add_policies)(child_sa_t *this, linked_list_t *my_ts_list, - linked_list_t *other_ts_list); + status_t (*install_policies)(child_sa_t *this); + + /** + * Set the outbound SPI of the CHILD_SA that replaced this CHILD_SA during + * a rekeying. + * + * @param spi outbound SPI of the CHILD_SA that replaced this CHILD_SA + */ + void (*set_rekey_spi)(child_sa_t *this, uint32_t spi); + + /** + * Get the outbound SPI of the CHILD_SA that replaced this CHILD_SA during + * a rekeying. + * + * @return outbound SPI of the CHILD_SA that replaced this CHILD_SA + */ + uint32_t (*get_rekey_spi)(child_sa_t *this); + /** * Update hosts and ecapulation mode in the kernel SAs and policies. * diff --git a/src/libcharon/sa/eap/eap_manager.c b/src/libcharon/sa/eap/eap_manager.c index e4fcbc8f0..b2a57ccfb 100644 --- a/src/libcharon/sa/eap/eap_manager.c +++ b/src/libcharon/sa/eap/eap_manager.c @@ -105,31 +105,38 @@ METHOD(eap_manager_t, remove_method, void, this->lock->unlock(this->lock); } -/** - * filter the registered methods - */ -static bool filter_methods(uintptr_t role, eap_entry_t **entry, - eap_type_t *type, void *in, uint32_t *vendor) +CALLBACK(filter_methods, bool, + uintptr_t role, enumerator_t *orig, va_list args) { - if ((*entry)->role != (eap_role_t)role) - { - return FALSE; - } - if ((*entry)->vendor == 0 && - ((*entry)->type < 4 || (*entry)->type == EAP_EXPANDED || - (*entry)->type > EAP_EXPERIMENTAL)) - { /* filter invalid types */ - return FALSE; - } - if (type) - { - *type = (*entry)->type; - } - if (vendor) + eap_entry_t *entry; + eap_type_t *type; + uint32_t *vendor; + + VA_ARGS_VGET(args, type, vendor); + + while (orig->enumerate(orig, &entry)) { - *vendor = (*entry)->vendor; + if (entry->role != (eap_role_t)role) + { + continue; + } + if (entry->vendor == 0 && + (entry->type < 4 || entry->type == EAP_EXPANDED || + entry->type > EAP_EXPERIMENTAL)) + { /* filter invalid types */ + continue; + } + if (type) + { + *type = entry->type; + } + if (vendor) + { + *vendor = entry->vendor; + } + return TRUE; } - return TRUE; + return FALSE; } METHOD(eap_manager_t, create_enumerator, enumerator_t*, @@ -139,7 +146,7 @@ METHOD(eap_manager_t, create_enumerator, enumerator_t*, return enumerator_create_cleaner( enumerator_create_filter( this->methods->create_enumerator(this->methods), - (void*)filter_methods, (void*)(uintptr_t)role, NULL), + filter_methods, (void*)(uintptr_t)role, NULL), (void*)this->lock->unlock, this->lock); } diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index 76e10691f..045858792 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -1200,12 +1200,20 @@ METHOD(ike_sa_t, generate_message, status_t, return status; } -static bool filter_fragments(private_ike_sa_t *this, packet_t **fragment, - packet_t **packet) +CALLBACK(filter_fragments, bool, + private_ike_sa_t *this, enumerator_t *orig, va_list args) { - *packet = (*fragment)->clone(*fragment); - set_dscp(this, *packet); - return TRUE; + packet_t *fragment, **packet; + + VA_ARGS_VGET(args, packet); + + if (orig->enumerate(orig, &fragment)) + { + *packet = fragment->clone(fragment); + set_dscp(this, *packet); + return TRUE; + } + return FALSE; } METHOD(ike_sa_t, generate_message_fragmented, status_t, @@ -1265,7 +1273,7 @@ METHOD(ike_sa_t, generate_message_fragmented, status_t, { charon->bus->message(charon->bus, message, FALSE, FALSE); } - *packets = enumerator_create_filter(fragments, (void*)filter_fragments, + *packets = enumerator_create_filter(fragments, filter_fragments, this, NULL); } return status; @@ -1699,8 +1707,11 @@ typedef struct { } child_enumerator_t; METHOD(enumerator_t, child_enumerate, bool, - child_enumerator_t *this, child_sa_t **child_sa) + child_enumerator_t *this, va_list args) { + child_sa_t **child_sa; + + VA_ARGS_VGET(args, child_sa); if (this->inner->enumerate(this->inner, &this->current)) { *child_sa = this->current; @@ -1723,7 +1734,8 @@ METHOD(ike_sa_t, create_child_sa_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_child_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _child_enumerate, .destroy = _child_enumerator_destroy, }, .inner = array_create_enumerator(this->child_sas), @@ -2619,24 +2631,31 @@ METHOD(ike_sa_t, add_configuration_attribute, void, array_insert(this->attributes, ARRAY_TAIL, &entry); } -/** - * Enumerator filter for attributes - */ -static bool filter_attribute(void *null, attribute_entry_t **in, - configuration_attribute_type_t *type, void *in2, - chunk_t *data, void *in3, bool *handled) +CALLBACK(filter_attribute, bool, + void *null, enumerator_t *orig, va_list args) { - *type = (*in)->type; - *data = (*in)->data; - *handled = (*in)->handler != NULL; - return TRUE; + attribute_entry_t *entry; + configuration_attribute_type_t *type; + chunk_t *data; + bool *handled; + + VA_ARGS_VGET(args, type, data, handled); + + if (orig->enumerate(orig, &entry)) + { + *type = entry->type; + *data = entry->data; + *handled = entry->handler != NULL; + return TRUE; + } + return FALSE; } METHOD(ike_sa_t, create_attribute_enumerator, enumerator_t*, private_ike_sa_t *this) { return enumerator_create_filter(array_create_enumerator(this->attributes), - (void*)filter_attribute, NULL, NULL); + filter_attribute, NULL, NULL); } METHOD(ike_sa_t, create_task_enumerator, enumerator_t*, diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c index 6bd49a086..c0bfebb83 100644 --- a/src/libcharon/sa/ike_sa_manager.c +++ b/src/libcharon/sa/ike_sa_manager.c @@ -151,8 +151,10 @@ static entry_t *entry_create() /** * Function that matches entry_t objects by ike_sa_id_t. */ -static bool entry_match_by_id(entry_t *entry, ike_sa_id_t *id) +static bool entry_match_by_id(entry_t *entry, void *arg) { + ike_sa_id_t *id = arg; + if (id->equals(id, entry->ike_sa_id)) { return TRUE; @@ -172,7 +174,7 @@ static bool entry_match_by_id(entry_t *entry, ike_sa_id_t *id) /** * Function that matches entry_t objects by ike_sa_t pointers. */ -static bool entry_match_by_sa(entry_t *entry, ike_sa_t *ike_sa) +static bool entry_match_by_sa(entry_t *entry, void *ike_sa) { return entry->ike_sa == ike_sa; } @@ -276,9 +278,6 @@ typedef struct segment_t segment_t; struct segment_t { /** mutex to access a segment exclusively */ mutex_t *mutex; - - /** the number of entries in this segment */ - u_int count; }; typedef struct shareable_segment_t shareable_segment_t; @@ -371,6 +370,11 @@ struct private_ike_sa_manager_t { refcount_t half_open_count_responder; /** + * Total number of IKE_SAs registered with IKE_SA manager. + */ + refcount_t total_sa_count; + + /** * Hash table with connected_peers_t objects. */ table_item_t **connected_peers_table; @@ -511,8 +515,13 @@ struct private_enumerator_t { }; METHOD(enumerator_t, enumerate, bool, - private_enumerator_t *this, entry_t **entry, u_int *segment) + private_enumerator_t *this, va_list args) { + entry_t **entry; + u_int *segment; + + VA_ARGS_VGET(args, entry, segment); + if (this->entry) { this->entry->condvar->signal(this->entry->condvar); @@ -570,7 +579,8 @@ static enumerator_t* create_table_enumerator(private_ike_sa_manager_t *this) INIT(enumerator, .enumerator = { - .enumerate = (void*)_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate, .destroy = _enumerator_destroy, }, .manager = this, @@ -601,7 +611,7 @@ static u_int put_entry(private_ike_sa_manager_t *this, entry_t *entry) item->next = current; } this->ike_sa_table[row] = item; - this->segments[segment].count++; + ref_get(&this->total_sa_count); return segment; } @@ -612,10 +622,9 @@ static u_int put_entry(private_ike_sa_manager_t *this, entry_t *entry) static void remove_entry(private_ike_sa_manager_t *this, entry_t *entry) { table_item_t *item, *prev = NULL; - u_int row, segment; + u_int row; row = ike_sa_id_hash(entry->ike_sa_id) & this->table_mask; - segment = row & this->segment_mask; item = this->ike_sa_table[row]; while (item) { @@ -629,7 +638,7 @@ static void remove_entry(private_ike_sa_manager_t *this, entry_t *entry) { this->ike_sa_table[row] = item->next; } - this->segments[segment].count--; + ignore_result(ref_put(&this->total_sa_count)); free(item); break; } @@ -648,7 +657,7 @@ static void remove_entry_at(private_enumerator_t *this) { table_item_t *current = this->current; - this->manager->segments[this->segment].count--; + ignore_result(ref_put(&this->manager->total_sa_count)); this->current = this->prev; if (this->prev) @@ -670,7 +679,7 @@ static void remove_entry_at(private_enumerator_t *this) */ static status_t get_entry_by_match_function(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id, entry_t **entry, u_int *segment, - linked_list_match_t match, void *param) + bool (*match)(entry_t*,void*), void *param) { table_item_t *item; u_int row, seg; @@ -703,7 +712,7 @@ static status_t get_entry_by_id(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id, entry_t **entry, u_int *segment) { return get_entry_by_match_function(this, ike_sa_id, entry, segment, - (linked_list_match_t)entry_match_by_id, ike_sa_id); + entry_match_by_id, ike_sa_id); } /** @@ -714,7 +723,7 @@ static status_t get_entry_by_sa(private_ike_sa_manager_t *this, ike_sa_id_t *ike_sa_id, ike_sa_t *ike_sa, entry_t **entry, u_int *segment) { return get_entry_by_match_function(this, ike_sa_id, entry, segment, - (linked_list_match_t)entry_match_by_sa, ike_sa); + entry_match_by_sa, ike_sa); } /** @@ -851,6 +860,15 @@ static void remove_half_open(private_ike_sa_manager_t *this, entry_t *entry) lock->unlock(lock); } +CALLBACK(id_matches, bool, + ike_sa_id_t *a, va_list args) +{ + ike_sa_id_t *b; + + VA_ARGS_VGET(args, b); + return a->equals(a, b); +} + /** * Put an SA between two peers into the hash table. */ @@ -879,8 +897,7 @@ static void put_connected_peers(private_ike_sa_manager_t *this, entry_t *entry) entry->other_id, family)) { if (connected_peers->sas->find_first(connected_peers->sas, - (linked_list_match_t)entry->ike_sa_id->equals, - NULL, entry->ike_sa_id) == SUCCESS) + id_matches, NULL, entry->ike_sa_id)) { lock->unlock(lock); return; @@ -1555,42 +1572,52 @@ METHOD(ike_sa_manager_t, checkout_by_name, ike_sa_t*, return ike_sa; } -/** - * enumerator filter function, waiting variant - */ -static bool enumerator_filter_wait(private_ike_sa_manager_t *this, - entry_t **in, ike_sa_t **out, u_int *segment) +CALLBACK(enumerator_filter_wait, bool, + private_ike_sa_manager_t *this, enumerator_t *orig, va_list args) { - if (wait_for_entry(this, *in, *segment)) + entry_t *entry; + u_int segment; + ike_sa_t **out; + + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, &entry, &segment)) { - *out = (*in)->ike_sa; - charon->bus->set_sa(charon->bus, *out); - return TRUE; + if (wait_for_entry(this, entry, segment)) + { + *out = entry->ike_sa; + charon->bus->set_sa(charon->bus, *out); + return TRUE; + } } return FALSE; } -/** - * enumerator filter function, skipping variant - */ -static bool enumerator_filter_skip(private_ike_sa_manager_t *this, - entry_t **in, ike_sa_t **out, u_int *segment) +CALLBACK(enumerator_filter_skip, bool, + private_ike_sa_manager_t *this, enumerator_t *orig, va_list args) { - if (!(*in)->driveout_new_threads && - !(*in)->driveout_waiting_threads && - !(*in)->checked_out) + entry_t *entry; + u_int segment; + ike_sa_t **out; + + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, &entry, &segment)) { - *out = (*in)->ike_sa; - charon->bus->set_sa(charon->bus, *out); - return TRUE; + if (!entry->driveout_new_threads && + !entry->driveout_waiting_threads && + !entry->checked_out) + { + *out = entry->ike_sa; + charon->bus->set_sa(charon->bus, *out); + return TRUE; + } } return FALSE; } -/** - * Reset threads SA after enumeration - */ -static void reset_sa(void *data) +CALLBACK(reset_sa, void, + void *data) { charon->bus->set_sa(charon->bus, NULL); } @@ -2034,17 +2061,7 @@ METHOD(ike_sa_manager_t, has_contact, bool, METHOD(ike_sa_manager_t, get_count, u_int, private_ike_sa_manager_t *this) { - u_int segment, count = 0; - mutex_t *mutex; - - for (segment = 0; segment < this->segment_count; segment++) - { - mutex = this->segments[segment & this->segment_mask].mutex; - mutex->lock(mutex); - count += this->segments[segment].count; - mutex->unlock(mutex); - } - return count; + return (u_int)ref_cur(&this->total_sa_count); } METHOD(ike_sa_manager_t, get_half_open_count, u_int, diff --git a/src/libcharon/sa/ikev1/task_manager_v1.c b/src/libcharon/sa/ikev1/task_manager_v1.c index 1da17ee50..48ec3e7f5 100644 --- a/src/libcharon/sa/ikev1/task_manager_v1.c +++ b/src/libcharon/sa/ikev1/task_manager_v1.c @@ -210,6 +210,16 @@ struct private_task_manager_t { double retransmit_base; /** + * Jitter to apply to calculated retransmit timeout (in percent) + */ + u_int retransmit_jitter; + + /** + * Limit retransmit timeout to this value + */ + uint32_t retransmit_limit; + + /** * Sequence number for sending DPD requests */ uint32_t dpd_send; @@ -345,7 +355,7 @@ static status_t retransmit_packet(private_task_manager_t *this, uint32_t seqnr, u_int mid, u_int retransmitted, array_t *packets) { packet_t *packet; - uint32_t t; + uint32_t t, max_jitter; array_get(packets, 0, &packet); if (retransmitted > this->retransmit_tries) @@ -356,6 +366,15 @@ static status_t retransmit_packet(private_task_manager_t *this, uint32_t seqnr, } t = (uint32_t)(this->retransmit_timeout * 1000.0 * pow(this->retransmit_base, retransmitted)); + if (this->retransmit_limit) + { + t = min(t, this->retransmit_limit); + } + if (this->retransmit_jitter) + { + max_jitter = (t / 100.0) * this->retransmit_jitter; + t -= max_jitter * (random() / (RAND_MAX + 1.0)); + } if (retransmitted) { DBG1(DBG_IKE, "sending retransmit %u of %s message ID %u, seq %u", @@ -2034,11 +2053,15 @@ task_manager_v1_t *task_manager_v1_create(ike_sa_t *ike_sa) .active_tasks = linked_list_create(), .passive_tasks = linked_list_create(), .retransmit_tries = lib->settings->get_int(lib->settings, - "%s.retransmit_tries", RETRANSMIT_TRIES, lib->ns), + "%s.retransmit_tries", RETRANSMIT_TRIES, lib->ns), .retransmit_timeout = lib->settings->get_double(lib->settings, - "%s.retransmit_timeout", RETRANSMIT_TIMEOUT, lib->ns), + "%s.retransmit_timeout", RETRANSMIT_TIMEOUT, lib->ns), .retransmit_base = lib->settings->get_double(lib->settings, - "%s.retransmit_base", RETRANSMIT_BASE, lib->ns), + "%s.retransmit_base", RETRANSMIT_BASE, lib->ns), + .retransmit_jitter = min(lib->settings->get_int(lib->settings, + "%s.retransmit_jitter", 0, lib->ns), RETRANSMIT_JITTER_MAX), + .retransmit_limit = lib->settings->get_int(lib->settings, + "%s.retransmit_limit", 0, lib->ns) * 1000, ); if (!this->rng) diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c index bbb885850..8be82ebe2 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_mode.c +++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c @@ -325,6 +325,17 @@ static bool install(private_quick_mode_t *this) return FALSE; } + if (this->initiator) + { + this->child_sa->set_policies(this->child_sa, tsi, tsr); + } + else + { + this->child_sa->set_policies(this->child_sa, tsr, tsi); + } + tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy)); + tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy)); + if (this->keymat->derive_child_keys(this->keymat, this->proposal, this->dh, this->spi_i, this->spi_r, this->nonce_i, this->nonce_r, &encr_i, &integ_i, &encr_r, &integ_r)) @@ -333,19 +344,19 @@ static bool install(private_quick_mode_t *this) { status_i = this->child_sa->install(this->child_sa, encr_r, integ_r, this->spi_i, this->cpi_i, - this->initiator, TRUE, FALSE, tsi, tsr); + this->initiator, TRUE, FALSE); status_o = this->child_sa->install(this->child_sa, encr_i, integ_i, this->spi_r, this->cpi_r, - this->initiator, FALSE, FALSE, tsi, tsr); + this->initiator, FALSE, FALSE); } else { status_i = this->child_sa->install(this->child_sa, encr_i, integ_i, this->spi_r, this->cpi_r, - this->initiator, TRUE, FALSE, tsr, tsi); + this->initiator, TRUE, FALSE); status_o = this->child_sa->install(this->child_sa, encr_r, integ_r, this->spi_i, this->cpi_i, - this->initiator, FALSE, FALSE, tsr, tsi); + this->initiator, FALSE, FALSE); } } @@ -355,22 +366,12 @@ static bool install(private_quick_mode_t *this) (status_i != SUCCESS) ? "inbound " : "", (status_i != SUCCESS && status_o != SUCCESS) ? "and ": "", (status_o != SUCCESS) ? "outbound " : ""); - tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy)); - tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy)); status = FAILED; } else { - if (this->initiator) - { - status = this->child_sa->add_policies(this->child_sa, tsi, tsr); - } - else - { - status = this->child_sa->add_policies(this->child_sa, tsr, tsi); - } - tsi->destroy_offset(tsi, offsetof(traffic_selector_t, destroy)); - tsr->destroy_offset(tsr, offsetof(traffic_selector_t, destroy)); + status = this->child_sa->install_policies(this->child_sa); + if (status != SUCCESS) { DBG1(DBG_IKE, "unable to install IPsec policies (SPD) in kernel"); @@ -853,7 +854,7 @@ METHOD(task_t, build_i, status_t, add_nat_oa_payloads(this, message); } - if (this->config->use_ipcomp(this->config)) + if (this->config->has_option(this->config, OPT_IPCOMP)) { this->cpi_i = this->child_sa->alloc_cpi(this->child_sa); if (!this->cpi_i) @@ -1108,7 +1109,7 @@ METHOD(task_t, process_r, status_t, return send_notify(this, INVALID_ID_INFORMATION); } - if (this->config->use_ipcomp(this->config)) + if (this->config->has_option(this->config, OPT_IPCOMP)) { list = sa_payload->get_ipcomp_proposals(sa_payload, &this->cpi_i); diff --git a/src/libcharon/sa/ikev2/connect_manager.c b/src/libcharon/sa/ikev2/connect_manager.c index 280796d8c..35856788c 100644 --- a/src/libcharon/sa/ikev2/connect_manager.c +++ b/src/libcharon/sa/ikev2/connect_manager.c @@ -450,22 +450,21 @@ static initiate_data_t *initiate_data_create(check_list_t *checklist, return this; } -/** - * Find an initiated connection by the peers' ids - */ -static bool match_initiated_by_ids(initiated_t *current, identification_t *id, - identification_t *peer_id) +CALLBACK(match_initiated_by_ids, bool, + initiated_t *current, va_list args) { + identification_t *id, *peer_id; + + VA_ARGS_VGET(args, id, peer_id); return id->equals(id, current->id) && peer_id->equals(peer_id, current->peer_id); } -static status_t get_initiated_by_ids(private_connect_manager_t *this, - identification_t *id, - identification_t *peer_id, - initiated_t **initiated) +static bool get_initiated_by_ids(private_connect_manager_t *this, + identification_t *id, + identification_t *peer_id, + initiated_t **initiated) { - return this->initiated->find_first(this->initiated, - (linked_list_match_t)match_initiated_by_ids, + return this->initiated->find_first(this->initiated, match_initiated_by_ids, (void**)initiated, id, peer_id); } @@ -490,21 +489,20 @@ static void remove_initiated(private_connect_manager_t *this, enumerator->destroy(enumerator); } -/** - * Find the checklist with a specific connect ID - */ -static bool match_checklist_by_id(check_list_t *current, chunk_t *connect_id) +CALLBACK(match_checklist_by_id, bool, + check_list_t *current, va_list args) { - return chunk_equals(*connect_id, current->connect_id); + chunk_t connect_id; + + VA_ARGS_VGET(args, connect_id); + return chunk_equals(connect_id, current->connect_id); } -static status_t get_checklist_by_id(private_connect_manager_t *this, - chunk_t connect_id, - check_list_t **check_list) +static bool get_checklist_by_id(private_connect_manager_t *this, + chunk_t connect_id, check_list_t **check_list) { - return this->checklists->find_first(this->checklists, - (linked_list_match_t)match_checklist_by_id, - (void**)check_list, &connect_id); + return this->checklists->find_first(this->checklists, match_checklist_by_id, + (void**)check_list, connect_id); } /** @@ -528,19 +526,19 @@ static void remove_checklist(private_connect_manager_t *this, enumerator->destroy(enumerator); } -/** - * Checks if a list of endpoint_notify_t contains a certain host_t - */ -static bool match_endpoint_by_host(endpoint_notify_t *current, host_t *host) +CALLBACK(match_endpoint_by_host, bool, + endpoint_notify_t *current, va_list args) { + host_t *host; + + VA_ARGS_VGET(args, host); return host->equals(host, current->get_host(current)); } -static status_t endpoints_contain(linked_list_t *endpoints, host_t *host, +static bool endpoints_contain(linked_list_t *endpoints, host_t *host, endpoint_notify_t **endpoint) { - return endpoints->find_first(endpoints, - (linked_list_match_t)match_endpoint_by_host, + return endpoints->find_first(endpoints, match_endpoint_by_host, (void**)endpoint, host); } @@ -560,39 +558,44 @@ static void insert_pair_by_priority(linked_list_t *pairs, endpoint_pair_t *pair) enumerator->destroy(enumerator); } -/** - * Searches a list of endpoint_pair_t for a pair with specific host_ts - */ -static bool match_pair_by_hosts(endpoint_pair_t *current, host_t *local, - host_t *remote) +CALLBACK(match_pair_by_hosts, bool, + endpoint_pair_t *current, va_list args) { - return local->equals(local, current->local) && remote->equals(remote, current->remote); + host_t *local, *remote; + + VA_ARGS_VGET(args, local, remote); + return local->equals(local, current->local) && + remote->equals(remote, current->remote); } -static status_t get_pair_by_hosts(linked_list_t *pairs, host_t *local, - host_t *remote, endpoint_pair_t **pair) +static bool get_pair_by_hosts(linked_list_t *pairs, host_t *local, + host_t *remote, endpoint_pair_t **pair) { - return pairs->find_first(pairs, (linked_list_match_t)match_pair_by_hosts, - (void**)pair, local, remote); + return pairs->find_first(pairs, match_pair_by_hosts, (void**)pair, local, + remote); } -static bool match_pair_by_id(endpoint_pair_t *current, uint32_t *id) +CALLBACK(match_pair_by_id, bool, + endpoint_pair_t *current, va_list args) { - return current->id == *id; + uint32_t id; + + VA_ARGS_VGET(args, id); + return current->id == id; } /** * Searches for a pair with a specific id */ -static status_t get_pair_by_id(check_list_t *checklist, uint32_t id, - endpoint_pair_t **pair) +static bool get_pair_by_id(check_list_t *checklist, uint32_t id, + endpoint_pair_t **pair) { - return checklist->pairs->find_first(checklist->pairs, - (linked_list_match_t)match_pair_by_id, - (void**)pair, &id); + return checklist->pairs->find_first(checklist->pairs, match_pair_by_id, + (void**)pair, id); } -static bool match_succeeded_pair(endpoint_pair_t *current) +CALLBACK(match_succeeded_pair, bool, + endpoint_pair_t *current, va_list args) { return current->state == CHECK_SUCCEEDED; } @@ -600,15 +603,14 @@ static bool match_succeeded_pair(endpoint_pair_t *current) /** * Returns the best pair of state CHECK_SUCCEEDED from a checklist. */ -static status_t get_best_valid_pair(check_list_t *checklist, - endpoint_pair_t **pair) +static bool get_best_valid_pair(check_list_t *checklist, endpoint_pair_t **pair) { - return checklist->pairs->find_first(checklist->pairs, - (linked_list_match_t)match_succeeded_pair, - (void**)pair); + return checklist->pairs->find_first(checklist->pairs, match_succeeded_pair, + (void**)pair); } -static bool match_waiting_pair(endpoint_pair_t *current) +CALLBACK(match_waiting_pair, bool, + endpoint_pair_t *current, va_list args) { return current->state == CHECK_WAITING; } @@ -865,7 +867,7 @@ static job_requeue_t initiator_finish(callback_data_t *data) this->mutex->lock(this->mutex); check_list_t *checklist; - if (get_checklist_by_id(this, data->connect_id, &checklist) != SUCCESS) + if (!get_checklist_by_id(this, data->connect_id, &checklist)) { DBG1(DBG_IKE, "checklist with id '%#B' not found, can't finish " "connectivity checks", &data->connect_id); @@ -953,7 +955,7 @@ static job_requeue_t retransmit(callback_data_t *data) this->mutex->lock(this->mutex); check_list_t *checklist; - if (get_checklist_by_id(this, data->connect_id, &checklist) != SUCCESS) + if (!get_checklist_by_id(this, data->connect_id, &checklist)) { DBG1(DBG_IKE, "checklist with id '%#B' not found, can't retransmit " "connectivity check", &data->connect_id); @@ -962,7 +964,7 @@ static job_requeue_t retransmit(callback_data_t *data) } endpoint_pair_t *pair; - if (get_pair_by_id(checklist, data->mid, &pair) != SUCCESS) + if (!get_pair_by_id(checklist, data->mid, &pair)) { DBG1(DBG_IKE, "pair with id '%d' not found, can't retransmit " "connectivity check", data->mid); @@ -1108,7 +1110,7 @@ static job_requeue_t sender(callback_data_t *data) this->mutex->lock(this->mutex); check_list_t *checklist; - if (get_checklist_by_id(this, data->connect_id, &checklist) != SUCCESS) + if (!get_checklist_by_id(this, data->connect_id, &checklist)) { DBG1(DBG_IKE, "checklist with id '%#B' not found, can't send " "connectivity check", &data->connect_id); @@ -1124,9 +1126,8 @@ static job_requeue_t sender(callback_data_t *data) { DBG1(DBG_IKE, "no triggered check queued, sending an ordinary check"); - if (checklist->pairs->find_first(checklist->pairs, - (linked_list_match_t)match_waiting_pair, - (void**)&pair) != SUCCESS) + if (!checklist->pairs->find_first(checklist->pairs, match_waiting_pair, + (void**)&pair)) { this->mutex->unlock(this->mutex); DBG1(DBG_IKE, "no pairs in waiting state, aborting"); @@ -1182,7 +1183,7 @@ static job_requeue_t initiate_mediated(initiate_data_t *data) initiated_t *initiated = data->initiated; endpoint_pair_t *pair; - if (get_best_valid_pair(checklist, &pair) == SUCCESS) + if (get_best_valid_pair(checklist, &pair)) { ike_sa_id_t *waiting_sa; enumerator_t *enumerator = initiated->mediated->create_enumerator( @@ -1219,7 +1220,7 @@ static void finish_checks(private_connect_manager_t *this, check_list_t *checkli { initiated_t *initiated; if (get_initiated_by_ids(this, checklist->initiator.id, - checklist->responder.id, &initiated) == SUCCESS) + checklist->responder.id, &initiated)) { callback_job_t *job; @@ -1247,7 +1248,7 @@ static void process_response(private_connect_manager_t *this, check_t *check, check_list_t *checklist) { endpoint_pair_t *pair; - if (get_pair_by_id(checklist, check->mid, &pair) == SUCCESS) + if (get_pair_by_id(checklist, check->mid, &pair)) { if (pair->local->equals(pair->local, check->dst) && pair->remote->equals(pair->remote, check->src)) @@ -1261,9 +1262,9 @@ static void process_response(private_connect_manager_t *this, check_t *check, checklist->initiator.endpoints : checklist->responder.endpoints; endpoint_notify_t *local_endpoint; - if (endpoints_contain(local_endpoints, - check->endpoint->get_host(check->endpoint), - &local_endpoint) != SUCCESS) + if (!endpoints_contain(local_endpoints, + check->endpoint->get_host(check->endpoint), + &local_endpoint)) { local_endpoint = endpoint_notify_create_from_host(PEER_REFLEXIVE, check->endpoint->get_host(check->endpoint), pair->local); @@ -1302,15 +1303,14 @@ static void process_request(private_connect_manager_t *this, check_t *check, peer_reflexive->set_priority(peer_reflexive, check->endpoint->get_priority(check->endpoint)); - if (endpoints_contain(remote_endpoints, check->src, &remote_endpoint) != SUCCESS) + if (!endpoints_contain(remote_endpoints, check->src, &remote_endpoint)) { remote_endpoint = peer_reflexive->clone(peer_reflexive); remote_endpoints->insert_last(remote_endpoints, remote_endpoint); } endpoint_pair_t *pair; - if (get_pair_by_hosts(checklist->pairs, check->dst, check->src, - &pair) == SUCCESS) + if (get_pair_by_hosts(checklist->pairs, check->dst, check->src, &pair)) { switch(pair->state) { @@ -1389,7 +1389,7 @@ METHOD(connect_manager_t, process_check, void, this->mutex->lock(this->mutex); check_list_t *checklist; - if (get_checklist_by_id(this, check->connect_id, &checklist) != SUCCESS) + if (!get_checklist_by_id(this, check->connect_id, &checklist)) { DBG1(DBG_IKE, "checklist with id '%#B' not found", &check->connect_id); @@ -1423,6 +1423,15 @@ METHOD(connect_manager_t, process_check, void, check_destroy(check); } +CALLBACK(id_matches, bool, + ike_sa_id_t *a, va_list args) +{ + ike_sa_id_t *b; + + VA_ARGS_VGET(args, b); + return a->equals(a, b); +} + METHOD(connect_manager_t, check_and_register, bool, private_connect_manager_t *this, identification_t *id, identification_t *peer_id, ike_sa_id_t *mediated_sa) @@ -1432,7 +1441,7 @@ METHOD(connect_manager_t, check_and_register, bool, this->mutex->lock(this->mutex); - if (get_initiated_by_ids(this, id, peer_id, &initiated) != SUCCESS) + if (!get_initiated_by_ids(this, id, peer_id, &initiated)) { DBG2(DBG_IKE, "registered waiting mediated connection with '%Y'", peer_id); @@ -1441,9 +1450,8 @@ METHOD(connect_manager_t, check_and_register, bool, already_there = FALSE; } - if (initiated->mediated->find_first(initiated->mediated, - (linked_list_match_t)mediated_sa->equals, - NULL, mediated_sa) != SUCCESS) + if (!initiated->mediated->find_first(initiated->mediated, id_matches, + NULL, mediated_sa)) { initiated->mediated->insert_last(initiated->mediated, mediated_sa->clone(mediated_sa)); @@ -1462,7 +1470,7 @@ METHOD(connect_manager_t, check_and_initiate, void, this->mutex->lock(this->mutex); - if (get_initiated_by_ids(this, id, peer_id, &initiated) != SUCCESS) + if (!get_initiated_by_ids(this, id, peer_id, &initiated)) { DBG2(DBG_IKE, "no waiting mediated connections with '%Y'", peer_id); this->mutex->unlock(this->mutex); @@ -1492,7 +1500,7 @@ METHOD(connect_manager_t, set_initiator_data, status_t, this->mutex->lock(this->mutex); - if (get_checklist_by_id(this, connect_id, NULL) == SUCCESS) + if (get_checklist_by_id(this, connect_id, NULL)) { DBG1(DBG_IKE, "checklist with id '%#B' already exists, aborting", &connect_id); @@ -1517,7 +1525,7 @@ METHOD(connect_manager_t, set_responder_data, status_t, this->mutex->lock(this->mutex); - if (get_checklist_by_id(this, connect_id, &checklist) != SUCCESS) + if (!get_checklist_by_id(this, connect_id, &checklist)) { DBG1(DBG_IKE, "checklist with id '%#B' not found", &connect_id); @@ -1547,7 +1555,7 @@ METHOD(connect_manager_t, stop_checks, status_t, this->mutex->lock(this->mutex); - if (get_checklist_by_id(this, connect_id, &checklist) != SUCCESS) + if (!get_checklist_by_id(this, connect_id, &checklist)) { DBG1(DBG_IKE, "checklist with id '%#B' not found", &connect_id); diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index e4a16faf0..c2ddbc588 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -161,6 +161,16 @@ struct private_task_manager_t { double retransmit_base; /** + * Jitter to apply to calculated retransmit timeout (in percent) + */ + u_int retransmit_jitter; + + /** + * Limit retransmit timeout to this value + */ + uint32_t retransmit_limit; + + /** * Use make-before-break instead of break-before-make reauth? */ bool make_before_break; @@ -321,7 +331,7 @@ METHOD(task_manager_t, retransmit, status_t, if (message_id == this->initiating.mid && array_count(this->initiating.packets)) { - uint32_t timeout; + uint32_t timeout, max_jitter; job_t *job; enumerator_t *enumerator; packet_t *packet; @@ -351,6 +361,16 @@ METHOD(task_manager_t, retransmit, status_t, { timeout = (uint32_t)(this->retransmit_timeout * 1000.0 * pow(this->retransmit_base, this->initiating.retransmitted)); + + if (this->retransmit_limit) + { + timeout = min(timeout, this->retransmit_limit); + } + if (this->retransmit_jitter) + { + max_jitter = (timeout / 100.0) * this->retransmit_jitter; + timeout -= max_jitter * (random() / (RAND_MAX + 1.0)); + } } else { @@ -2059,13 +2079,20 @@ METHOD(task_manager_t, reset, void, this->reset = TRUE; } -/** - * Filter queued tasks - */ -static bool filter_queued(void *unused, queued_task_t **queued, task_t **task) +CALLBACK(filter_queued, bool, + void *unused, enumerator_t *orig, va_list args) { - *task = (*queued)->task; - return TRUE; + queued_task_t *queued; + task_t **task; + + VA_ARGS_VGET(args, task); + + if (orig->enumerate(orig, &queued)) + { + *task = queued->task; + return TRUE; + } + return FALSE; } METHOD(task_manager_t, create_task_enumerator, enumerator_t*, @@ -2080,7 +2107,7 @@ METHOD(task_manager_t, create_task_enumerator, enumerator_t*, case TASK_QUEUE_QUEUED: return enumerator_create_filter( array_create_enumerator(this->queued_tasks), - (void*)filter_queued, NULL, NULL); + filter_queued, NULL, NULL); default: return enumerator_create_empty(); } @@ -2151,6 +2178,10 @@ task_manager_v2_t *task_manager_v2_create(ike_sa_t *ike_sa) "%s.retransmit_timeout", RETRANSMIT_TIMEOUT, lib->ns), .retransmit_base = lib->settings->get_double(lib->settings, "%s.retransmit_base", RETRANSMIT_BASE, lib->ns), + .retransmit_jitter = min(lib->settings->get_int(lib->settings, + "%s.retransmit_jitter", 0, lib->ns), RETRANSMIT_JITTER_MAX), + .retransmit_limit = lib->settings->get_int(lib->settings, + "%s.retransmit_limit", 0, lib->ns) * 1000, .make_before_break = lib->settings->get_bool(lib->settings, "%s.make_before_break", FALSE, lib->ns), ); diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c index 71cb6b8ea..896cabb2b 100644 --- a/src/libcharon/sa/ikev2/tasks/child_create.c +++ b/src/libcharon/sa/ikev2/tasks/child_create.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2016 Tobias Brunner + * Copyright (C) 2008-2017 Tobias Brunner * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * HSR Hochschule fuer Technik Rapperswil @@ -602,7 +602,7 @@ static status_t select_and_install(private_child_create_t *this, switch (this->mode) { case MODE_TRANSPORT: - if (!this->config->use_proxy_mode(this->config) && + if (!this->config->has_option(this->config, OPT_PROXY_MODE) && (!ts_list_is_host(this->tsi, other) || !ts_list_is_host(this->tsr, me)) ) @@ -630,6 +630,32 @@ static status_t select_and_install(private_child_create_t *this, default: break; } + /* use a copy of the traffic selectors, as the POST hook should not + * change payloads */ + my_ts = this->tsr->clone_offset(this->tsr, + offsetof(traffic_selector_t, clone)); + other_ts = this->tsi->clone_offset(this->tsi, + offsetof(traffic_selector_t, clone)); + charon->bus->narrow(charon->bus, this->child_sa, + NARROW_RESPONDER_POST, my_ts, other_ts); + + if (my_ts->get_count(my_ts) == 0 || other_ts->get_count(other_ts) == 0) + { + my_ts->destroy_offset(my_ts, + offsetof(traffic_selector_t, destroy)); + other_ts->destroy_offset(other_ts, + offsetof(traffic_selector_t, destroy)); + return NOT_FOUND; + } + } + + this->child_sa->set_policies(this->child_sa, my_ts, other_ts); + if (!this->initiator) + { + my_ts->destroy_offset(my_ts, + offsetof(traffic_selector_t, destroy)); + other_ts->destroy_offset(other_ts, + offsetof(traffic_selector_t, destroy)); } this->child_sa->set_state(this->child_sa, CHILD_INSTALLING); @@ -651,19 +677,30 @@ static status_t select_and_install(private_child_create_t *this, { status_i = this->child_sa->install(this->child_sa, encr_r, integ_r, this->my_spi, this->my_cpi, this->initiator, - TRUE, this->tfcv3, my_ts, other_ts); + TRUE, this->tfcv3); status_o = this->child_sa->install(this->child_sa, encr_i, integ_i, this->other_spi, this->other_cpi, this->initiator, - FALSE, this->tfcv3, my_ts, other_ts); + FALSE, this->tfcv3); } - else + else if (!this->rekey) { status_i = this->child_sa->install(this->child_sa, encr_i, integ_i, this->my_spi, this->my_cpi, this->initiator, - TRUE, this->tfcv3, my_ts, other_ts); + TRUE, this->tfcv3); status_o = this->child_sa->install(this->child_sa, encr_r, integ_r, this->other_spi, this->other_cpi, this->initiator, - FALSE, this->tfcv3, my_ts, other_ts); + FALSE, this->tfcv3); + } + else + { /* as responder during a rekeying we only install the inbound + * SA now, the outbound SA and policies are installed when we + * receive the delete for the old SA */ + status_i = this->child_sa->install(this->child_sa, encr_i, integ_i, + this->my_spi, this->my_cpi, this->initiator, + TRUE, this->tfcv3); + this->child_sa->register_outbound(this->child_sa, encr_r, integ_r, + this->other_spi, this->other_cpi, this->tfcv3); + status_o = SUCCESS; } } @@ -679,36 +716,8 @@ static status_t select_and_install(private_child_create_t *this, } else { - if (this->initiator) - { - status = this->child_sa->add_policies(this->child_sa, - my_ts, other_ts); - } - else - { - /* use a copy of the traffic selectors, as the POST hook should not - * change payloads */ - my_ts = this->tsr->clone_offset(this->tsr, - offsetof(traffic_selector_t, clone)); - other_ts = this->tsi->clone_offset(this->tsi, - offsetof(traffic_selector_t, clone)); - charon->bus->narrow(charon->bus, this->child_sa, - NARROW_RESPONDER_POST, my_ts, other_ts); - if (my_ts->get_count(my_ts) == 0 || - other_ts->get_count(other_ts) == 0) - { - status = FAILED; - } - else - { - status = this->child_sa->add_policies(this->child_sa, - my_ts, other_ts); - } - my_ts->destroy_offset(my_ts, - offsetof(traffic_selector_t, destroy)); - other_ts->destroy_offset(other_ts, - offsetof(traffic_selector_t, destroy)); - } + status = this->child_sa->install_policies(this->child_sa); + if (status != SUCCESS) { DBG1(DBG_IKE, "unable to install IPsec policies (SPD) in kernel"); @@ -736,7 +745,6 @@ static status_t select_and_install(private_child_create_t *this, charon->bus->child_keys(charon->bus, this->child_sa, this->initiator, this->dh, nonce_i, nonce_r); - /* add to IKE_SA, and remove from task */ this->child_sa->set_state(this->child_sa, CHILD_INSTALLED); this->ike_sa->add_child_sa(this->ike_sa, this->child_sa); this->established = TRUE; @@ -748,16 +756,17 @@ static status_t select_and_install(private_child_create_t *this, other_ts = linked_list_create_from_enumerator( this->child_sa->create_ts_enumerator(this->child_sa, FALSE)); - DBG0(DBG_IKE, "CHILD_SA %s{%d} established " + DBG0(DBG_IKE, "%sCHILD_SA %s{%d} established " "with SPIs %.8x_i %.8x_o and TS %#R === %#R", + this->rekey && !this->initiator ? "inbound " : "", this->child_sa->get_name(this->child_sa), this->child_sa->get_unique_id(this->child_sa), ntohl(this->child_sa->get_spi(this->child_sa, TRUE)), - ntohl(this->child_sa->get_spi(this->child_sa, FALSE)), my_ts, other_ts); + ntohl(this->child_sa->get_spi(this->child_sa, FALSE)), + my_ts, other_ts); my_ts->destroy(my_ts); other_ts->destroy(other_ts); - return SUCCESS; } @@ -1073,7 +1082,7 @@ METHOD(task_t, build_i, status_t, this->dh_group); } - if (this->config->use_ipcomp(this->config)) + if (this->config->has_option(this->config, OPT_IPCOMP)) { /* IPCOMP_DEFLATE is the only transform we support at the moment */ add_ipcomp_notify(this, message, IPCOMP_DEFLATE); @@ -1327,7 +1336,7 @@ METHOD(task_t, build_r, status_t, if (this->ipcomp_received != IPCOMP_NONE) { - if (this->config->use_ipcomp(this->config)) + if (this->config->has_option(this->config, OPT_IPCOMP)) { add_ipcomp_notify(this, message, this->ipcomp_received); } @@ -1690,7 +1699,6 @@ METHOD(task_t, destroy, void, { this->proposals->destroy_offset(this->proposals, offsetof(proposal_t, destroy)); } - DESTROY_IF(this->config); DESTROY_IF(this->nonceg); free(this); diff --git a/src/libcharon/sa/ikev2/tasks/child_delete.c b/src/libcharon/sa/ikev2/tasks/child_delete.c index 6fa8836ac..626796383 100644 --- a/src/libcharon/sa/ikev2/tasks/child_delete.c +++ b/src/libcharon/sa/ikev2/tasks/child_delete.c @@ -18,9 +18,14 @@ #include <daemon.h> #include <encoding/payloads/delete_payload.h> +#include <processing/jobs/delete_child_sa_job.h> #include <sa/ikev2/tasks/child_create.h> #include <sa/ikev2/tasks/child_rekey.h> +#ifndef DELETE_REKEYED_DELAY +#define DELETE_REKEYED_DELAY 5 +#endif + typedef struct private_child_delete_t private_child_delete_t; /** @@ -39,67 +44,80 @@ struct private_child_delete_t { ike_sa_t *ike_sa; /** - * Are we the initiator? + * Whether we are the initiator of the exchange */ bool initiator; /** - * Protocol of CHILD_SA to delete + * Protocol of CHILD_SA to delete (as initiator) */ protocol_id_t protocol; /** - * Inbound SPI of CHILD_SA to delete + * Inbound SPI of CHILD_SA to delete (as initiator) */ uint32_t spi; /** - * whether to enforce delete action policy - */ - bool check_delete_action; - - /** - * is this delete exchange following a rekey? - */ - bool rekeyed; - - /** - * CHILD_SA already expired? + * CHILD_SA already expired (as initiator) */ bool expired; /** - * CHILD_SAs which get deleted + * CHILD_SAs which get deleted, entry_t* */ linked_list_t *child_sas; }; /** + * Information about a deleted CHILD_SA + */ +typedef struct { + /** Deleted CHILD_SA */ + child_sa_t *child_sa; + /** Whether the CHILD_SA was rekeyed */ + bool rekeyed; + /** Whether to enforce any delete action policy */ + bool check_delete_action; +} entry_t; + +CALLBACK(match_child, bool, + entry_t *entry, va_list args) +{ + child_sa_t *child_sa; + + VA_ARGS_VGET(args, child_sa); + return entry->child_sa == child_sa; +} + +/** * build the delete payloads from the listed child_sas */ static void build_payloads(private_child_delete_t *this, message_t *message) { delete_payload_t *ah = NULL, *esp = NULL; enumerator_t *enumerator; - child_sa_t *child_sa; + entry_t *entry; + protocol_id_t protocol; + uint32_t spi; enumerator = this->child_sas->create_enumerator(this->child_sas); - while (enumerator->enumerate(enumerator, (void**)&child_sa)) + while (enumerator->enumerate(enumerator, (void**)&entry)) { - protocol_id_t protocol = child_sa->get_protocol(child_sa); - uint32_t spi = child_sa->get_spi(child_sa, TRUE); + protocol = entry->child_sa->get_protocol(entry->child_sa); + spi = entry->child_sa->get_spi(entry->child_sa, TRUE); switch (protocol) { case PROTO_ESP: - if (esp == NULL) + if (!esp) { esp = delete_payload_create(PLV2_DELETE, PROTO_ESP); message->add_payload(message, (payload_t*)esp); } esp->add_spi(esp, spi); DBG1(DBG_IKE, "sending DELETE for %N CHILD_SA with SPI %.8x", - protocol_id_names, protocol, ntohl(spi)); + protocol_id_names, protocol, ntohl(spi)); break; case PROTO_AH: if (ah == NULL) @@ -109,12 +127,12 @@ static void build_payloads(private_child_delete_t *this, message_t *message) } ah->add_spi(ah, spi); DBG1(DBG_IKE, "sending DELETE for %N CHILD_SA with SPI %.8x", - protocol_id_names, protocol, ntohl(spi)); + protocol_id_names, protocol, ntohl(spi)); break; default: break; } - child_sa->set_state(child_sa, CHILD_DELETING); + entry->child_sa->set_state(entry->child_sa, CHILD_DELETING); } enumerator->destroy(enumerator); } @@ -147,6 +165,57 @@ static bool is_redundant(private_child_delete_t *this, child_sa_t *child) } /** + * Install the outbound CHILD_SA with the given SPI + */ +static void install_outbound(private_child_delete_t *this, + protocol_id_t protocol, uint32_t spi) +{ + child_sa_t *child_sa; + linked_list_t *my_ts, *other_ts; + status_t status; + + child_sa = this->ike_sa->get_child_sa(this->ike_sa, protocol, + spi, FALSE); + if (!child_sa) + { + DBG1(DBG_IKE, "CHILD_SA not found after rekeying"); + return; + } + if (this->initiator && is_redundant(this, child_sa)) + { /* if we won the rekey collision we don't want to install the + * redundant SA created by the peer */ + return; + } + + status = child_sa->install_outbound(child_sa); + if (status != SUCCESS) + { + DBG1(DBG_IKE, "unable to install outbound IPsec SA (SAD) in kernel"); + charon->bus->alert(charon->bus, ALERT_INSTALL_CHILD_SA_FAILED, + child_sa); + /* FIXME: delete the new child_sa? */ + return; + } + child_sa->set_state(child_sa, CHILD_INSTALLED); + + my_ts = linked_list_create_from_enumerator( + child_sa->create_ts_enumerator(child_sa, TRUE)); + other_ts = linked_list_create_from_enumerator( + child_sa->create_ts_enumerator(child_sa, FALSE)); + + DBG0(DBG_IKE, "outbound CHILD_SA %s{%d} established " + "with SPIs %.8x_i %.8x_o and TS %#R === %#R", + child_sa->get_name(child_sa), + child_sa->get_unique_id(child_sa), + ntohl(child_sa->get_spi(child_sa, TRUE)), + ntohl(child_sa->get_spi(child_sa, FALSE)), + my_ts, other_ts); + + my_ts->destroy(my_ts); + other_ts->destroy(other_ts); +} + +/** * read in payloads and find the children to delete */ static void process_payloads(private_child_delete_t *this, message_t *message) @@ -157,6 +226,7 @@ static void process_payloads(private_child_delete_t *this, message_t *message) uint32_t spi; protocol_id_t protocol; child_sa_t *child_sa; + entry_t *entry; payloads = message->create_payload_enumerator(message); while (payloads->enumerate(payloads, &payload)) @@ -174,27 +244,37 @@ static void process_payloads(private_child_delete_t *this, message_t *message) { child_sa = this->ike_sa->get_child_sa(this->ike_sa, protocol, spi, FALSE); - if (child_sa == NULL) + if (!child_sa) { - DBG1(DBG_IKE, "received DELETE for %N CHILD_SA with SPI %.8x, " - "but no such SA", protocol_id_names, protocol, ntohl(spi)); + DBG1(DBG_IKE, "received DELETE for unknown %N CHILD_SA with" + " SPI %.8x", protocol_id_names, protocol, ntohl(spi)); continue; } DBG1(DBG_IKE, "received DELETE for %N CHILD_SA with SPI %.8x", protocol_id_names, protocol, ntohl(spi)); + if (this->child_sas->find_first(this->child_sas, match_child, + NULL, child_sa)) + { + continue; + } + INIT(entry, + .child_sa = child_sa + ); switch (child_sa->get_state(child_sa)) { case CHILD_REKEYED: - this->rekeyed = TRUE; + entry->rekeyed = TRUE; break; case CHILD_DELETING: - /* we don't send back a delete if we initiated ourself */ + /* we don't send back a delete if we already initiated + * a delete ourself */ if (!this->initiator) { + free(entry); continue; } - /* fall through */ + break; case CHILD_REKEYING: /* we reply as usual, rekeying will fail */ case CHILD_INSTALLED: @@ -202,22 +282,18 @@ static void process_payloads(private_child_delete_t *this, message_t *message) { if (is_redundant(this, child_sa)) { - this->rekeyed = TRUE; + entry->rekeyed = TRUE; } else { - this->check_delete_action = TRUE; + entry->check_delete_action = TRUE; } } break; default: break; } - if (this->child_sas->find_first(this->child_sas, NULL, - (void**)&child_sa) != SUCCESS) - { - this->child_sas->insert_last(this->child_sas, child_sa); - } + this->child_sas->insert_last(this->child_sas, entry); } spis->destroy(spis); } @@ -231,29 +307,64 @@ static void process_payloads(private_child_delete_t *this, message_t *message) static status_t destroy_and_reestablish(private_child_delete_t *this) { enumerator_t *enumerator; + entry_t *entry; child_sa_t *child_sa; child_cfg_t *child_cfg; protocol_id_t protocol; - uint32_t spi, reqid; + uint32_t spi, reqid, rekey_spi; action_t action; status_t status = SUCCESS; + time_t now, expire; + u_int delay; + + now = time_monotonic(NULL); + delay = lib->settings->get_int(lib->settings, "%s.delete_rekeyed_delay", + DELETE_REKEYED_DELAY, lib->ns); enumerator = this->child_sas->create_enumerator(this->child_sas); - while (enumerator->enumerate(enumerator, (void**)&child_sa)) + while (enumerator->enumerate(enumerator, (void**)&entry)) { + child_sa = entry->child_sa; /* signal child down event if we weren't rekeying */ - if (!this->rekeyed) + protocol = child_sa->get_protocol(child_sa); + if (!entry->rekeyed) { charon->bus->child_updown(charon->bus, child_sa, FALSE); } + else + { + rekey_spi = child_sa->get_rekey_spi(child_sa); + if (rekey_spi) + { + install_outbound(this, protocol, rekey_spi); + } + /* for rekeyed CHILD_SAs we uninstall the outbound SA but don't + * immediately destroy it, by default, so we can process delayed + * packets */ + child_sa->remove_outbound(child_sa); + expire = child_sa->get_lifetime(child_sa, TRUE); + if (delay && (!expire || ((now + delay) < expire))) + { + lib->scheduler->schedule_job(lib->scheduler, + (job_t*)delete_child_sa_job_create_id( + child_sa->get_unique_id(child_sa)), delay); + continue; + } + else if (expire) + { /* let it expire naturally */ + continue; + } + /* no delay and no lifetime, destroy it immediately */ + } spi = child_sa->get_spi(child_sa, TRUE); reqid = child_sa->get_reqid(child_sa); - protocol = child_sa->get_protocol(child_sa); child_cfg = child_sa->get_config(child_sa); child_cfg->get_ref(child_cfg); action = child_sa->get_close_action(child_sa); + this->ike_sa->destroy_child_sa(this->ike_sa, protocol, spi); - if (this->check_delete_action) + + if (entry->check_delete_action) { /* enforce child_cfg policy if deleted passively */ switch (action) { @@ -288,12 +399,14 @@ static void log_children(private_child_delete_t *this) { linked_list_t *my_ts, *other_ts; enumerator_t *enumerator; + entry_t *entry; child_sa_t *child_sa; uint64_t bytes_in, bytes_out; enumerator = this->child_sas->create_enumerator(this->child_sas); - while (enumerator->enumerate(enumerator, (void**)&child_sa)) + while (enumerator->enumerate(enumerator, (void**)&entry)) { + child_sa = entry->child_sa; my_ts = linked_list_create_from_enumerator( child_sa->create_ts_enumerator(child_sa, TRUE)); other_ts = linked_list_create_from_enumerator( @@ -328,6 +441,7 @@ METHOD(task_t, build_i, status_t, private_child_delete_t *this, message_t *message) { child_sa_t *child_sa; + entry_t *entry; child_sa = this->ike_sa->get_child_sa(this->ike_sa, this->protocol, this->spi, TRUE); @@ -342,15 +456,24 @@ METHOD(task_t, build_i, status_t, /* we work only with the inbound SPI */ this->spi = child_sa->get_spi(child_sa, TRUE); } - this->child_sas->insert_last(this->child_sas, child_sa); - if (child_sa->get_state(child_sa) == CHILD_REKEYED) - { - this->rekeyed = TRUE; + + if (child_sa->get_state(child_sa) == CHILD_DELETING) + { /* DELETEs for this CHILD_SA were already exchanged, but it was not yet + * destroyed to allow delayed packets to get processed */ + this->ike_sa->destroy_child_sa(this->ike_sa, this->protocol, this->spi); + message->set_exchange_type(message, EXCHANGE_TYPE_UNDEFINED); + return SUCCESS; } + + INIT(entry, + .child_sa = child_sa, + .rekeyed = child_sa->get_state(child_sa) == CHILD_REKEYED, + ); + this->child_sas->insert_last(this->child_sas, entry); log_children(this); build_payloads(this, message); - if (!this->rekeyed && this->expired) + if (!entry->rekeyed && this->expired) { child_cfg_t *child_cfg; @@ -397,24 +520,28 @@ METHOD(child_delete_t , get_child, child_sa_t*, private_child_delete_t *this) { child_sa_t *child_sa = NULL; - this->child_sas->get_first(this->child_sas, (void**)&child_sa); + entry_t *entry; + + if (this->child_sas->get_first(this->child_sas, (void**)&entry) == SUCCESS) + { + child_sa = entry->child_sa; + } return child_sa; } METHOD(task_t, migrate, void, private_child_delete_t *this, ike_sa_t *ike_sa) { - this->check_delete_action = FALSE; this->ike_sa = ike_sa; - this->child_sas->destroy(this->child_sas); + this->child_sas->destroy_function(this->child_sas, free); this->child_sas = linked_list_create(); } METHOD(task_t, destroy, void, private_child_delete_t *this) { - this->child_sas->destroy(this->child_sas); + this->child_sas->destroy_function(this->child_sas, free); free(this); } diff --git a/src/libcharon/sa/ikev2/tasks/child_rekey.c b/src/libcharon/sa/ikev2/tasks/child_rekey.c index c04ec141f..761c860e7 100644 --- a/src/libcharon/sa/ikev2/tasks/child_rekey.c +++ b/src/libcharon/sa/ikev2/tasks/child_rekey.c @@ -132,6 +132,7 @@ static void find_child(private_child_rekey_t *this, message_t *message) notify_payload_t *notify; protocol_id_t protocol; uint32_t spi; + child_sa_t *child_sa; notify = message->get_notify(message, REKEY_SA); if (notify) @@ -141,8 +142,15 @@ static void find_child(private_child_rekey_t *this, message_t *message) if (protocol == PROTO_ESP || protocol == PROTO_AH) { - this->child_sa = this->ike_sa->get_child_sa(this->ike_sa, protocol, - spi, FALSE); + child_sa = this->ike_sa->get_child_sa(this->ike_sa, protocol, + spi, FALSE); + if (child_sa && + child_sa->get_state(child_sa) == CHILD_DELETING && + child_sa->get_outbound_state(child_sa) == CHILD_OUTBOUND_NONE) + { /* ignore rekeyed CHILD_SAs we keep around */ + return; + } + this->child_sa = child_sa; } } } @@ -227,6 +235,7 @@ METHOD(task_t, build_r, status_t, child_cfg_t *config; uint32_t reqid; child_sa_state_t state; + child_sa_t *child_sa; if (!this->child_sa) { @@ -260,7 +269,10 @@ METHOD(task_t, build_r, status_t, return SUCCESS; } + child_sa = this->child_create->get_child(this->child_create); this->child_sa->set_state(this->child_sa, CHILD_REKEYED); + this->child_sa->set_rekey_spi(this->child_sa, + child_sa->get_spi(child_sa, FALSE)); /* invoke rekey hook */ charon->bus->child_rekey(charon->bus, this->child_sa, diff --git a/src/libcharon/sa/shunt_manager.c b/src/libcharon/sa/shunt_manager.c index b0162751d..ad12f0579 100644 --- a/src/libcharon/sa/shunt_manager.c +++ b/src/libcharon/sa/shunt_manager.c @@ -381,14 +381,24 @@ METHOD(shunt_manager_t, uninstall, bool, } CALLBACK(filter_entries, bool, - void *unused, entry_t **entry, char **ns, void **in, child_cfg_t **cfg) + void *unused, enumerator_t *orig, va_list args) { - if (ns) + entry_t *entry; + child_cfg_t **cfg; + char **ns; + + VA_ARGS_VGET(args, ns, cfg); + + if (orig->enumerate(orig, &entry)) { - *ns = (*entry)->ns; + if (ns) + { + *ns = entry->ns; + } + *cfg = entry->cfg; + return TRUE; } - *cfg = (*entry)->cfg; - return TRUE; + return FALSE; } METHOD(shunt_manager_t, create_enumerator, enumerator_t*, @@ -397,7 +407,7 @@ METHOD(shunt_manager_t, create_enumerator, enumerator_t*, this->lock->read_lock(this->lock); return enumerator_create_filter( this->shunts->create_enumerator(this->shunts), - (void*)filter_entries, this->lock, + filter_entries, this->lock, (void*)this->lock->unlock); } diff --git a/src/libcharon/sa/task_manager.c b/src/libcharon/sa/task_manager.c index c42008ba9..bd1191406 100644 --- a/src/libcharon/sa/task_manager.c +++ b/src/libcharon/sa/task_manager.c @@ -15,10 +15,40 @@ #include "task_manager.h" +#include <math.h> #include <sa/ikev1/task_manager_v1.h> #include <sa/ikev2/task_manager_v2.h> -/** +/* + * See header + */ +u_int task_manager_total_retransmit_timeout() +{ + double timeout, base, limit = 0, total = 0; + int tries, i; + + tries = lib->settings->get_int(lib->settings, "%s.retransmit_tries", + RETRANSMIT_TRIES, lib->ns); + base = lib->settings->get_double(lib->settings, "%s.retransmit_base", + RETRANSMIT_BASE, lib->ns); + timeout = lib->settings->get_double(lib->settings, "%s.retransmit_timeout", + RETRANSMIT_TIMEOUT, lib->ns); + limit = lib->settings->get_double(lib->settings, "%s.retransmit_limit", + 0, lib->ns); + + for (i = 0; i <= tries; i++) + { + double interval = timeout * pow(base, i); + if (limit) + { + interval = min(interval, limit); + } + total += interval; + } + return (u_int)total; +} + +/* * See header */ task_manager_t *task_manager_create(ike_sa_t *ike_sa) diff --git a/src/libcharon/sa/task_manager.h b/src/libcharon/sa/task_manager.h index 7e9262291..e3fddf39b 100644 --- a/src/libcharon/sa/task_manager.h +++ b/src/libcharon/sa/task_manager.h @@ -48,6 +48,11 @@ typedef enum task_queue_t task_queue_t; #define RETRANSMIT_TRIES 5 /** + * Maximum jitter in percent. + */ +#define RETRANSMIT_JITTER_MAX 20 + +/** * Interval for mobike routability checks in ms. */ #define ROUTEABILITY_CHECK_INTERVAL 2500 @@ -298,6 +303,17 @@ struct task_manager_t { }; /** + * Calculate total timeout of the retransmission mechanism. + * + * This is affected by modifications of retransmit_base, retransmit_timeout, + * retransmit_limit or retransmit_tries. The resulting value can then be used + * e.g. in kernel plugins to set the system's acquire timeout properly. + * + * @return calculated total retransmission timeout in seconds + */ +u_int task_manager_total_retransmit_timeout(); + +/** * Create a task manager instance for the correct IKE version. * * @param ike_sa IKE_SA to create a task manager for diff --git a/src/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c index 40a0682f2..f9fee5e7e 100644 --- a/src/libcharon/sa/trap_manager.c +++ b/src/libcharon/sa/trap_manager.c @@ -140,19 +140,21 @@ static void destroy_acquire(acquire_t *this) free(this); } -/** - * match an acquire entry by reqid - */ -static bool acquire_by_reqid(acquire_t *this, uint32_t *reqid) +CALLBACK(acquire_by_reqid, bool, + acquire_t *this, va_list args) { - return this->reqid == *reqid; + uint32_t reqid; + + VA_ARGS_VGET(args, reqid); + return this->reqid == reqid; } -/** - * match an acquire entry by destination address - */ -static bool acquire_by_dst(acquire_t *this, host_t *dst) +CALLBACK(acquire_by_dst, bool, + acquire_t *this, va_list args) { + host_t *dst; + + VA_ARGS_VGET(args, dst); return this->dst && this->dst->ip_equals(this->dst, dst); } @@ -272,7 +274,8 @@ METHOD(trap_manager_t, install, uint32_t, proposals->destroy_offset(proposals, offsetof(proposal_t, destroy)); child_sa->set_protocol(child_sa, proto); child_sa->set_mode(child_sa, child->get_mode(child)); - status = child_sa->add_policies(child_sa, my_ts, other_ts); + child_sa->set_policies(child_sa, my_ts, other_ts); + status = child_sa->install_policies(child_sa); my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy)); other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy)); if (status != SUCCESS) @@ -334,25 +337,32 @@ METHOD(trap_manager_t, uninstall, bool, return TRUE; } -/** - * convert enumerated entries to peer_cfg, child_sa - */ -static bool trap_filter(rwlock_t *lock, entry_t **entry, peer_cfg_t **peer_cfg, - void *none, child_sa_t **child_sa) +CALLBACK(trap_filter, bool, + rwlock_t *lock, enumerator_t *orig, va_list args) { - if (!(*entry)->child_sa) - { /* skip entries that are currently being installed */ - return FALSE; - } - if (peer_cfg) - { - *peer_cfg = (*entry)->peer_cfg; - } - if (child_sa) + entry_t *entry; + peer_cfg_t **peer_cfg; + child_sa_t **child_sa; + + VA_ARGS_VGET(args, peer_cfg, child_sa); + + while (orig->enumerate(orig, &entry)) { - *child_sa = (*entry)->child_sa; + if (!entry->child_sa) + { /* skip entries that are currently being installed */ + continue; + } + if (peer_cfg) + { + *peer_cfg = entry->peer_cfg; + } + if (child_sa) + { + *child_sa = entry->child_sa; + } + return TRUE; } - return TRUE; + return FALSE; } METHOD(trap_manager_t, create_enumerator, enumerator_t*, @@ -360,7 +370,7 @@ METHOD(trap_manager_t, create_enumerator, enumerator_t*, { this->lock->read_lock(this->lock); return enumerator_create_filter(this->traps->create_enumerator(this->traps), - (void*)trap_filter, this->lock, + trap_filter, this->lock, (void*)this->lock->unlock); } @@ -431,8 +441,8 @@ METHOD(trap_manager_t, acquire, void, uint8_t mask; dst->to_subnet(dst, &host, &mask); - if (this->acquires->find_first(this->acquires, (void*)acquire_by_dst, - (void**)&acquire, host) == SUCCESS) + if (this->acquires->find_first(this->acquires, acquire_by_dst, + (void**)&acquire, host)) { host->destroy(host); ignore = TRUE; @@ -448,8 +458,8 @@ METHOD(trap_manager_t, acquire, void, } else { - if (this->acquires->find_first(this->acquires, (void*)acquire_by_reqid, - (void**)&acquire, &reqid) == SUCCESS) + if (this->acquires->find_first(this->acquires, acquire_by_reqid, + (void**)&acquire, reqid)) { ignore = TRUE; } diff --git a/src/libcharon/tests/Makefile.in b/src/libcharon/tests/Makefile.in index e922a7171..3070f429b 100644 --- a/src/libcharon/tests/Makefile.in +++ b/src/libcharon/tests/Makefile.in @@ -380,6 +380,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -402,6 +403,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libcharon/tests/suites/test_child_rekey.c b/src/libcharon/tests/suites/test_child_rekey.c index fcac49388..76b23f589 100644 --- a/src/libcharon/tests/suites/test_child_rekey.c +++ b/src/libcharon/tests/suites/test_child_rekey.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Tobias Brunner + * Copyright (C) 2016-2017 Tobias Brunner * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -28,7 +28,23 @@ assert_hook_not_called(child_updown); \ assert_hook_not_called(child_rekey); \ call_ikesa(sa, rekey_child_sa, PROTO_ESP, spi); \ - assert_child_sa_state(sa, spi, CHILD_REKEYING); \ + assert_child_sa_state(sa, spi, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED); \ + assert_hook(); \ + assert_hook(); \ +}) + +/** + * Destroy a rekeyed CHILD_SA that was kept around to accept inbound traffic. + * Simulates the job that's scheduled to do this. + */ +#define destroy_rekeyed(sa, spi) ({ \ + assert_hook_not_called(child_updown); \ + assert_hook_not_called(child_rekey); \ + assert_no_jobs_scheduled(); \ + assert_child_sa_state(sa, spi, CHILD_DELETING, CHILD_OUTBOUND_NONE); \ + call_ikesa(sa, delete_child_sa, PROTO_ESP, spi, FALSE); \ + assert_child_sa_not_exists(sa, spi); \ + assert_scheduler(); \ assert_hook(); \ assert_hook(); \ }) @@ -53,6 +69,7 @@ START_TEST(test_regular) &a, &b, NULL); } initiate_rekey(a, spi_a); + assert_ipsec_sas_installed(a, spi_a, spi_b); /* this should never get called as this results in a successful rekeying */ assert_hook_not_called(child_updown); @@ -61,33 +78,51 @@ START_TEST(test_regular) assert_hook_called(child_rekey); assert_notify(IN, REKEY_SA); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, spi_b, CHILD_REKEYED); - assert_child_sa_state(b, 4, CHILD_INSTALLED); + assert_child_sa_state(b, spi_b, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED); + assert_ipsec_sas_installed(b, spi_a, spi_b, 4); assert_hook(); /* <-- CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } */ assert_hook_called(child_rekey); assert_no_notify(IN, REKEY_SA); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, spi_a, CHILD_DELETING); - assert_child_sa_state(a, 3, CHILD_INSTALLED); + assert_child_sa_state(a, spi_a, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(a, 3, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_ipsec_sas_installed(a, spi_a, spi_b, 3, 4); assert_hook(); /* INFORMATIONAL { D } --> */ assert_hook_not_called(child_rekey); + assert_jobs_scheduled(1); assert_single_payload(IN, PLV2_DELETE); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, 4, CHILD_INSTALLED); - assert_child_sa_count(b, 1); + assert_child_sa_state(b, spi_b, CHILD_DELETING, CHILD_OUTBOUND_NONE); + assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(b, 2); + assert_ipsec_sas_installed(b, spi_b, 3, 4); + assert_scheduler(); assert_hook(); /* <-- INFORMATIONAL { D } */ assert_hook_not_called(child_rekey); + assert_jobs_scheduled(1); assert_single_payload(IN, PLV2_DELETE); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, 3, CHILD_INSTALLED); - assert_child_sa_count(a, 1); + assert_child_sa_state(a, spi_a, CHILD_DELETING, CHILD_OUTBOUND_NONE); + assert_child_sa_state(a, 3, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(a, 2); + assert_ipsec_sas_installed(a, spi_a, 3, 4); + assert_scheduler(); assert_hook(); + /* simulate the execution of the scheduled jobs */ + destroy_rekeyed(a, spi_a); + assert_child_sa_count(a, 1); + assert_ipsec_sas_installed(a, 3, 4); + destroy_rekeyed(b, spi_b); + assert_child_sa_count(b, 1); + assert_ipsec_sas_installed(a, 3, 4); + /* child_updown */ assert_hook(); @@ -125,6 +160,7 @@ START_TEST(test_regular_ke_invalid) &a, &b, &conf); } initiate_rekey(a, spi_a); + assert_ipsec_sas_installed(a, spi_a, spi_b); /* this should never get called as this results in a successful rekeying */ assert_hook_not_called(child_updown); @@ -135,6 +171,7 @@ START_TEST(test_regular_ke_invalid) exchange_test_helper->process_message(exchange_test_helper, b, NULL); assert_child_sa_state(b, spi_b, CHILD_INSTALLED); assert_child_sa_count(b, 1); + assert_ipsec_sas_installed(b, spi_a, spi_b); assert_hook(); /* <-- CREATE_CHILD_SA { N(INVAL_KE) } */ @@ -143,6 +180,7 @@ START_TEST(test_regular_ke_invalid) exchange_test_helper->process_message(exchange_test_helper, a, NULL); assert_child_sa_state(a, spi_a, CHILD_REKEYING); assert_child_sa_count(a, 1); + assert_ipsec_sas_installed(a, spi_a, spi_b); assert_hook(); /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> */ @@ -150,7 +188,8 @@ START_TEST(test_regular_ke_invalid) assert_notify(IN, REKEY_SA); exchange_test_helper->process_message(exchange_test_helper, b, NULL); assert_child_sa_state(b, spi_b, CHILD_REKEYED); - assert_child_sa_state(b, 6, CHILD_INSTALLED); + assert_child_sa_state(b, 6, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED); + assert_ipsec_sas_installed(b, spi_a, spi_b, 6); assert_hook(); /* <-- CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } */ @@ -158,24 +197,37 @@ START_TEST(test_regular_ke_invalid) assert_no_notify(IN, REKEY_SA); exchange_test_helper->process_message(exchange_test_helper, a, NULL); assert_child_sa_state(a, spi_a, CHILD_DELETING); - assert_child_sa_state(a, 5, CHILD_INSTALLED); + assert_child_sa_state(a, 5, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_ipsec_sas_installed(a, spi_a, spi_b, 5, 6); assert_hook(); /* INFORMATIONAL { D } --> */ assert_hook_not_called(child_rekey); assert_single_payload(IN, PLV2_DELETE); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, 6, CHILD_INSTALLED); - assert_child_sa_count(b, 1); + assert_child_sa_state(b, spi_b, CHILD_DELETING, CHILD_OUTBOUND_NONE); + assert_child_sa_state(b, 6, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(b, 2); + assert_ipsec_sas_installed(b, spi_b, 5, 6); assert_hook(); /* <-- INFORMATIONAL { D } */ assert_hook_not_called(child_rekey); assert_single_payload(IN, PLV2_DELETE); exchange_test_helper->process_message(exchange_test_helper, a, NULL); + assert_child_sa_state(a, spi_a, CHILD_DELETING, CHILD_OUTBOUND_NONE); assert_child_sa_state(a, 5, CHILD_INSTALLED); - assert_child_sa_count(a, 1); + assert_child_sa_count(a, 2); + assert_ipsec_sas_installed(a, spi_a, 5, 6); assert_hook(); + /* simulate the execution of the scheduled jobs */ + destroy_rekeyed(a, spi_a); + assert_child_sa_count(a, 1); + assert_ipsec_sas_installed(a, 5, 6); + destroy_rekeyed(b, spi_b); + assert_child_sa_count(b, 1); + assert_ipsec_sas_installed(b, 5, 6); + /* child_updown */ assert_hook(); @@ -195,6 +247,7 @@ START_TEST(test_regular_responder_ignore_soft_expire) exchange_test_helper->establish_sa(exchange_test_helper, &a, &b, NULL); initiate_rekey(a, 1); + assert_ipsec_sas_installed(a, 1, 2); /* this should never get called as this results in a successful rekeying */ assert_hook_not_called(child_updown); @@ -204,7 +257,8 @@ START_TEST(test_regular_responder_ignore_soft_expire) assert_notify(IN, REKEY_SA); exchange_test_helper->process_message(exchange_test_helper, b, NULL); assert_child_sa_state(b, 2, CHILD_REKEYED); - assert_child_sa_state(b, 4, CHILD_INSTALLED); + assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED); + assert_ipsec_sas_installed(b, 1, 2, 4); assert_hook(); /* <-- CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } */ @@ -212,7 +266,8 @@ START_TEST(test_regular_responder_ignore_soft_expire) assert_no_notify(IN, REKEY_SA); exchange_test_helper->process_message(exchange_test_helper, a, NULL); assert_child_sa_state(a, 1, CHILD_DELETING); - assert_child_sa_state(a, 3, CHILD_INSTALLED); + assert_child_sa_state(a, 3, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_ipsec_sas_installed(a, 1, 2, 3, 4); assert_hook(); /* we don't expect this to get called anymore */ @@ -223,15 +278,31 @@ START_TEST(test_regular_responder_ignore_soft_expire) assert_child_sa_state(b, 2, CHILD_REKEYED); /* INFORMATIONAL { D } --> */ + assert_jobs_scheduled(1); assert_single_payload(IN, PLV2_DELETE); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, 4, CHILD_INSTALLED); - assert_child_sa_count(b, 1); + assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_NONE); + assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(b, 2); + assert_ipsec_sas_installed(b, 2, 3, 4); + assert_scheduler(); /* <-- INFORMATIONAL { D } */ + assert_jobs_scheduled(1); assert_single_payload(IN, PLV2_DELETE); exchange_test_helper->process_message(exchange_test_helper, a, NULL); + assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_NONE); assert_child_sa_state(a, 3, CHILD_INSTALLED); + assert_child_sa_count(a, 2); + assert_ipsec_sas_installed(a, 1, 3, 4); + assert_scheduler(); + + /* simulate the execution of the scheduled jobs */ + destroy_rekeyed(a, 1); assert_child_sa_count(a, 1); + assert_ipsec_sas_installed(a, 3, 4); + destroy_rekeyed(b, 2); + assert_child_sa_count(b, 1); + assert_ipsec_sas_installed(b, 3, 4); /* child_rekey/child_updown */ assert_hook(); @@ -254,6 +325,7 @@ START_TEST(test_regular_responder_handle_hard_expire) exchange_test_helper->establish_sa(exchange_test_helper, &a, &b, NULL); initiate_rekey(a, 1); + assert_ipsec_sas_installed(a, 1, 2); /* this should never get called as this results in a successful rekeying */ assert_hook_not_called(child_updown); @@ -263,7 +335,8 @@ START_TEST(test_regular_responder_handle_hard_expire) assert_notify(IN, REKEY_SA); exchange_test_helper->process_message(exchange_test_helper, b, NULL); assert_child_sa_state(b, 2, CHILD_REKEYED); - assert_child_sa_state(b, 4, CHILD_INSTALLED); + assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED); + assert_ipsec_sas_installed(b, 1, 2, 4); assert_hook(); /* <-- CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } */ @@ -271,7 +344,8 @@ START_TEST(test_regular_responder_handle_hard_expire) assert_no_notify(IN, REKEY_SA); exchange_test_helper->process_message(exchange_test_helper, a, NULL); assert_child_sa_state(a, 1, CHILD_DELETING); - assert_child_sa_state(a, 3, CHILD_INSTALLED); + assert_child_sa_state(a, 3, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_ipsec_sas_installed(a, 1, 2, 3, 4); assert_hook(); /* we don't expect this to get called anymore */ @@ -279,28 +353,51 @@ START_TEST(test_regular_responder_handle_hard_expire) /* this is similar to a regular delete collision */ assert_single_payload(OUT, PLV2_DELETE); call_ikesa(b, delete_child_sa, PROTO_ESP, 2, TRUE); - assert_child_sa_state(b, 2, CHILD_DELETING); + assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED); + /* since the SAs expired they would not actually be installed in the kernel + * anymore and since we have not yet installed a new outbound SA this + * will result in dropped packets and possibly acquires */ + assert_ipsec_sas_installed(b, 1, 2, 4); /* INFORMATIONAL { D } --> */ assert_single_payload(IN, PLV2_DELETE); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, 4, CHILD_INSTALLED); - assert_child_sa_state(a, 2, CHILD_DELETING); + assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED); + assert_ipsec_sas_installed(b, 1, 2, 4); /* <-- INFORMATIONAL { D } */ assert_single_payload(IN, PLV2_DELETE); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, 3, CHILD_INSTALLED); - assert_child_sa_state(a, 1, CHILD_DELETING); + assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(a, 3, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_ipsec_sas_installed(a, 1, 2, 3, 4); /* <-- INFORMATIONAL { } */ + assert_jobs_scheduled(1); assert_message_empty(IN); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, 3, CHILD_INSTALLED); - assert_child_sa_count(a, 1); + assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_NONE); + assert_child_sa_state(a, 3, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(a, 2); + assert_ipsec_sas_installed(a, 1, 3, 4); + assert_scheduler(); /* INFORMATIONAL { } --> */ + assert_jobs_scheduled(1); assert_message_empty(IN); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, 4, CHILD_INSTALLED); + assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_NONE); + assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(b, 2); + assert_ipsec_sas_installed(b, 2, 3, 4); + assert_scheduler(); + + /* simulate the execution of the scheduled jobs */ + destroy_rekeyed(a, 1); + assert_child_sa_count(a, 1); + assert_ipsec_sas_installed(a, 3, 4); + destroy_rekeyed(b, 2); assert_child_sa_count(b, 1); + assert_ipsec_sas_installed(b, 3, 4); /* child_rekey/child_updown */ assert_hook(); @@ -350,8 +447,10 @@ START_TEST(test_collision) exchange_test_helper->nonce_first_byte = data[_i].nonces[0]; initiate_rekey(a, 1); + assert_ipsec_sas_installed(a, 1, 2); exchange_test_helper->nonce_first_byte = data[_i].nonces[1]; initiate_rekey(b, 2); + assert_ipsec_sas_installed(b, 1, 2); /* this should never get called as this results in a successful rekeying */ assert_hook_not_called(child_updown); @@ -360,15 +459,17 @@ START_TEST(test_collision) exchange_test_helper->nonce_first_byte = data[_i].nonces[2]; assert_hook_rekey(child_rekey, 2, 5); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, 2, CHILD_REKEYED); - assert_child_sa_state(b, 5, CHILD_INSTALLED); + assert_child_sa_state(b, 2, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(b, 5, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED); + assert_ipsec_sas_installed(b, 1, 2, 5); assert_hook(); /* <-- CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } */ exchange_test_helper->nonce_first_byte = data[_i].nonces[3]; assert_hook_rekey(child_rekey, 1, 6); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, 1, CHILD_REKEYED); - assert_child_sa_state(a, 6, CHILD_INSTALLED); + assert_child_sa_state(a, 1, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(a, 6, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED); + assert_ipsec_sas_installed(a, 1, 2, 6); assert_hook(); /* <-- CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } */ @@ -378,53 +479,113 @@ START_TEST(test_collision) assert_hook_rekey(child_rekey, 1, data[_i].spi_a); exchange_test_helper->process_message(exchange_test_helper, a, NULL); assert_hook(); + assert_child_sa_state(a, data[_i].spi_del_b, CHILD_REKEYED, + CHILD_OUTBOUND_REGISTERED); + assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED, + CHILD_OUTBOUND_INSTALLED); } else { assert_hook_not_called(child_rekey); exchange_test_helper->process_message(exchange_test_helper, a, NULL); assert_hook(); + assert_child_sa_state(a, data[_i].spi_del_b, CHILD_REKEYED, + CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED, + CHILD_OUTBOUND_REGISTERED); } - assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING); - assert_child_sa_state(a, data[_i].spi_del_b, CHILD_REKEYED); - assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED); + assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING, + CHILD_OUTBOUND_INSTALLED); + assert_ipsec_sas_installed(a, 1, 2, 3, 5, 6); /* CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } --> */ if (data[_i].spi_del_b == 2) { assert_hook_rekey(child_rekey, 2, data[_i].spi_b); exchange_test_helper->process_message(exchange_test_helper, b, NULL); assert_hook(); + assert_child_sa_state(b, data[_i].spi_del_a, CHILD_REKEYED, + CHILD_OUTBOUND_REGISTERED); + assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED, + CHILD_OUTBOUND_INSTALLED); } else { assert_hook_not_called(child_rekey); exchange_test_helper->process_message(exchange_test_helper, b, NULL); assert_hook(); + assert_child_sa_state(b, data[_i].spi_del_a, CHILD_REKEYED, + CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED, + CHILD_OUTBOUND_REGISTERED); } - assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING); - assert_child_sa_state(b, data[_i].spi_del_a, CHILD_REKEYED); - assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED); + assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING, + CHILD_OUTBOUND_INSTALLED); + assert_ipsec_sas_installed(b, 1, 2, 4, 5, 6); /* we don't expect this hook to get called anymore */ assert_hook_not_called(child_rekey); /* INFORMATIONAL { D } --> */ + assert_jobs_scheduled(1); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING); - assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED); - assert_child_sa_count(b, 2); + assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING, + CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(b, data[_i].spi_del_a, CHILD_DELETING, + CHILD_OUTBOUND_NONE); + assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED, + CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(b, 3); + assert_ipsec_sas_installed(b, 2, 4, 5, 6, + data[_i].spi_del_b == 2 ? 1 : 3); + assert_scheduler(); /* <-- INFORMATIONAL { D } */ + assert_jobs_scheduled(1); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING); - assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED); - assert_child_sa_count(a, 2); + assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING, + CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(a, data[_i].spi_del_b, CHILD_DELETING, + CHILD_OUTBOUND_NONE); + assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED, + CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(a, 3); + assert_ipsec_sas_installed(a, 1, 3, 5, 6, + data[_i].spi_del_a == 1 ? 2 : 4); + assert_scheduler(); /* <-- INFORMATIONAL { D } */ + assert_jobs_scheduled(1); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED); - assert_child_sa_count(a, 1); + assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING, + CHILD_OUTBOUND_NONE); + assert_child_sa_state(a, data[_i].spi_del_b, CHILD_DELETING, + CHILD_OUTBOUND_NONE); + assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED, + CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(a, 3); + assert_ipsec_sas_installed(a, 1, 3, 6, + data[_i].spi_del_a == 1 ? 5 : 4); + assert_scheduler(); /* INFORMATIONAL { D } --> */ + assert_jobs_scheduled(1); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED); + assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING, + CHILD_OUTBOUND_NONE); + assert_child_sa_state(b, data[_i].spi_del_a, CHILD_DELETING, + CHILD_OUTBOUND_NONE); + assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED, + CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(b, 3); + assert_ipsec_sas_installed(b, 2, 4, 5, + data[_i].spi_del_b == 2 ? 6 : 3); + assert_scheduler(); + + /* simulate the execution of the scheduled jobs */ + destroy_rekeyed(a, data[_i].spi_del_a); + destroy_rekeyed(a, data[_i].spi_del_b); + assert_child_sa_count(a, 1); + assert_ipsec_sas_installed(a, data[_i].spi_a, data[_i].spi_b); + destroy_rekeyed(b, data[_i].spi_del_a); + destroy_rekeyed(b, data[_i].spi_del_b); assert_child_sa_count(b, 1); + assert_ipsec_sas_installed(b, data[_i].spi_a, data[_i].spi_b); /* child_rekey/child_updown */ assert_hook(); @@ -483,8 +644,10 @@ START_TEST(test_collision_delayed_response) exchange_test_helper->nonce_first_byte = data[_i].nonces[0]; initiate_rekey(a, 1); + assert_ipsec_sas_installed(a, 1, 2); exchange_test_helper->nonce_first_byte = data[_i].nonces[1]; initiate_rekey(b, 2); + assert_ipsec_sas_installed(b, 1, 2); /* this should never get called as this results in a successful rekeying */ assert_hook_not_called(child_updown); @@ -493,15 +656,17 @@ START_TEST(test_collision_delayed_response) exchange_test_helper->nonce_first_byte = data[_i].nonces[2]; assert_hook_rekey(child_rekey, 2, 5); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, 2, CHILD_REKEYED); - assert_child_sa_state(b, 5, CHILD_INSTALLED); + assert_child_sa_state(b, 2, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(b, 5, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED); + assert_ipsec_sas_installed(b, 1, 2, 5); assert_hook(); /* <-- CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } */ exchange_test_helper->nonce_first_byte = data[_i].nonces[3]; assert_hook_rekey(child_rekey, 1, 6); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, 1, CHILD_REKEYED); - assert_child_sa_state(a, 6, CHILD_INSTALLED); + assert_child_sa_state(a, 1, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(a, 6, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED); + assert_ipsec_sas_installed(a, 1, 2, 6); assert_hook(); /* delay the CREATE_CHILD_SA response from b to a */ @@ -513,35 +678,68 @@ START_TEST(test_collision_delayed_response) assert_hook_rekey(child_rekey, 2, data[_i].spi_b); exchange_test_helper->process_message(exchange_test_helper, b, NULL); assert_hook(); + assert_child_sa_state(b, data[_i].spi_del_a, CHILD_REKEYED, + CHILD_OUTBOUND_REGISTERED); + assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED, + CHILD_OUTBOUND_INSTALLED); } else { assert_hook_not_called(child_rekey); exchange_test_helper->process_message(exchange_test_helper, b, NULL); assert_hook(); + assert_child_sa_state(b, data[_i].spi_del_a, CHILD_REKEYED, + CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED, + CHILD_OUTBOUND_REGISTERED); } - assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING); - assert_child_sa_state(b, data[_i].spi_del_a, CHILD_REKEYED); - assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED); + assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING, + CHILD_OUTBOUND_INSTALLED); + assert_ipsec_sas_installed(b, 1, 2, 4, 5, 6); /* <-- INFORMATIONAL { D } */ assert_hook_not_called(child_rekey); + assert_jobs_scheduled(1); exchange_test_helper->process_message(exchange_test_helper, a, NULL); if (data[_i].spi_del_b == 2) { - assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED); - assert_child_sa_count(a, 1); + assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_NONE); + assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED, + CHILD_OUTBOUND_INSTALLED); + assert_ipsec_sas_installed(a, 1, 4, 6); } else { - assert_child_sa_state(a, 1, CHILD_REKEYED); - assert_child_sa_count(a, 1); + assert_child_sa_state(a, 1, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(a, data[_i].spi_del_b, CHILD_DELETING, + CHILD_OUTBOUND_NONE); + assert_ipsec_sas_installed(a, 1, 2, 6); } + assert_child_sa_count(a, 2); + assert_scheduler(); /* INFORMATIONAL { D } --> */ + assert_jobs_scheduled(1); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, data[_i].spi_del_a, CHILD_REKEYED); - assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED); - assert_child_sa_count(b, 2); + if (data[_i].spi_del_b == 2) + { + assert_child_sa_state(b, data[_i].spi_del_a, CHILD_REKEYED, + CHILD_OUTBOUND_REGISTERED); + assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED, + CHILD_OUTBOUND_INSTALLED); + assert_ipsec_sas_installed(b, 2, 4, 5, 6); + } + else + { + assert_child_sa_state(b, data[_i].spi_del_a, CHILD_REKEYED, + CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED, + CHILD_OUTBOUND_REGISTERED); + assert_ipsec_sas_installed(b, 1, 2, 4, 5); + } + assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING, + CHILD_OUTBOUND_NONE); + assert_child_sa_count(b, 3); + assert_scheduler(); assert_hook(); /* <-- CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } (delayed) */ @@ -557,20 +755,54 @@ START_TEST(test_collision_delayed_response) exchange_test_helper->process_message(exchange_test_helper, a, msg); assert_hook(); } - assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING); - assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED); - assert_child_sa_count(a, 2); + assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING, + CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(a, data[_i].spi_del_b, CHILD_DELETING, + CHILD_OUTBOUND_NONE); + assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED, + CHILD_OUTBOUND_INSTALLED); + assert_ipsec_sas_installed(a, 1, 3, 5, 6, + data[_i].spi_del_a == 1 ? 2 : 4); + assert_child_sa_count(a, 3); /* we don't expect this hook to get called anymore */ assert_hook_not_called(child_rekey); /* INFORMATIONAL { D } --> */ + assert_jobs_scheduled(1); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED); - assert_child_sa_count(b, 1); + assert_child_sa_state(b, data[_i].spi_del_a, CHILD_DELETING, + CHILD_OUTBOUND_NONE); + assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING, + CHILD_OUTBOUND_NONE); + assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED, + CHILD_OUTBOUND_INSTALLED); + assert_ipsec_sas_installed(b, 2, 4, 5, + data[_i].spi_del_b == 2 ? 6 : 3); + assert_child_sa_count(b, 3); + assert_scheduler(); /* <-- INFORMATIONAL { D } */ + assert_jobs_scheduled(1); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED); + assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING, + CHILD_OUTBOUND_NONE); + assert_child_sa_state(a, data[_i].spi_del_b, CHILD_DELETING, + CHILD_OUTBOUND_NONE); + assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED, + CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(a, 3); + assert_ipsec_sas_installed(a, 1, 3, 6, + data[_i].spi_del_a == 1 ? 5 : 4); + assert_scheduler(); + + /* simulate the execution of the scheduled jobs */ + destroy_rekeyed(a, data[_i].spi_del_a); + destroy_rekeyed(a, data[_i].spi_del_b); assert_child_sa_count(a, 1); + assert_ipsec_sas_installed(a, data[_i].spi_a, data[_i].spi_b); + destroy_rekeyed(b, data[_i].spi_del_a); + destroy_rekeyed(b, data[_i].spi_del_b); + assert_child_sa_count(b, 1); + assert_ipsec_sas_installed(b, data[_i].spi_a, data[_i].spi_b); /* child_rekey/child_updown */ assert_hook(); @@ -621,8 +853,10 @@ START_TEST(test_collision_delayed_request) exchange_test_helper->nonce_first_byte = data[_i].nonces[0]; initiate_rekey(a, 1); + assert_ipsec_sas_installed(a, 1, 2); exchange_test_helper->nonce_first_byte = data[_i].nonces[1]; initiate_rekey(b, 2); + assert_ipsec_sas_installed(b, 1, 2); /* delay the CREATE_CHILD_SA request from a to b */ msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender); @@ -634,14 +868,16 @@ START_TEST(test_collision_delayed_request) exchange_test_helper->nonce_first_byte = data[_i].nonces[2]; assert_hook_rekey(child_rekey, 1, 5); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, 1, CHILD_REKEYED); - assert_child_sa_state(a, 5, CHILD_INSTALLED); + assert_child_sa_state(a, 1, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(a, 5, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED); + assert_ipsec_sas_installed(a, 1, 2, 5); assert_hook(); /* CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } --> */ assert_hook_rekey(child_rekey, 2, 4); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, 2, CHILD_DELETING); - assert_child_sa_state(b, 4, CHILD_INSTALLED); + assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_ipsec_sas_installed(b, 1, 2, 4, 5); assert_hook(); /* we don't expect this hook to get called anymore */ @@ -650,25 +886,43 @@ START_TEST(test_collision_delayed_request) /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> (delayed) */ assert_single_notify(OUT, TEMPORARY_FAILURE); exchange_test_helper->process_message(exchange_test_helper, b, msg); - assert_child_sa_state(b, 2, CHILD_DELETING); - assert_child_sa_state(b, 4, CHILD_INSTALLED); + assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); /* <-- INFORMATIONAL { D } */ + assert_jobs_scheduled(1); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, 5, CHILD_INSTALLED); - assert_child_sa_count(a, 1); + assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_NONE); + assert_child_sa_state(a, 5, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(a, 2); + assert_ipsec_sas_installed(a, 1, 4, 5); + assert_scheduler(); /* <-- CREATE_CHILD_SA { N(TEMP_FAIL) } */ assert_no_jobs_scheduled(); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, 5, CHILD_INSTALLED); - assert_child_sa_count(a, 1); + assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_NONE); + assert_child_sa_state(a, 5, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(a, 2); + assert_ipsec_sas_installed(a, 1, 4, 5); assert_scheduler(); /* INFORMATIONAL { D } --> */ + assert_jobs_scheduled(1); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, 4, CHILD_INSTALLED); + assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_NONE); + assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(b, 2); + assert_ipsec_sas_installed(b, 2, 4, 5); + assert_scheduler(); + + /* simulate the execution of the scheduled jobs */ + destroy_rekeyed(a, 1); + assert_child_sa_count(a, 1); + assert_ipsec_sas_installed(a, 4, 5); + destroy_rekeyed(b, 2); assert_child_sa_count(b, 1); + assert_ipsec_sas_installed(b, 4, 5); /* child_rekey/child_updown */ assert_hook(); @@ -722,8 +976,10 @@ START_TEST(test_collision_delayed_request_more) exchange_test_helper->nonce_first_byte = data[_i].nonces[0]; initiate_rekey(a, 1); + assert_ipsec_sas_installed(a, 1, 2); exchange_test_helper->nonce_first_byte = data[_i].nonces[1]; initiate_rekey(b, 2); + assert_ipsec_sas_installed(b, 1, 2); /* delay the CREATE_CHILD_SA request from a to b */ msg = exchange_test_helper->sender->dequeue(exchange_test_helper->sender); @@ -735,40 +991,62 @@ START_TEST(test_collision_delayed_request_more) exchange_test_helper->nonce_first_byte = data[_i].nonces[2]; assert_hook_rekey(child_rekey, 1, 5); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, 1, CHILD_REKEYED); - assert_child_sa_state(a, 5, CHILD_INSTALLED); + assert_child_sa_state(a, 1, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(a, 5, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED); + assert_ipsec_sas_installed(a, 1, 2, 5); assert_hook(); /* CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } --> */ assert_hook_rekey(child_rekey, 2, 4); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, 2, CHILD_DELETING); - assert_child_sa_state(b, 4, CHILD_INSTALLED); + assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_ipsec_sas_installed(b, 1, 2, 4, 5); assert_hook(); /* we don't expect this hook to get called anymore */ assert_hook_not_called(child_rekey); /* <-- INFORMATIONAL { D } */ + assert_jobs_scheduled(1); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, 5, CHILD_INSTALLED); - assert_child_sa_count(a, 1); + assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_NONE); + assert_child_sa_state(a, 5, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(a, 2); + assert_ipsec_sas_installed(a, 1, 4, 5); + assert_scheduler(); /* INFORMATIONAL { D } --> */ + assert_jobs_scheduled(1); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, 4, CHILD_INSTALLED); - assert_child_sa_count(b, 1); + assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_NONE); + assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(b, 2); + assert_ipsec_sas_installed(b, 2, 4, 5); + assert_scheduler(); /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> */ assert_single_notify(OUT, CHILD_SA_NOT_FOUND); exchange_test_helper->process_message(exchange_test_helper, b, msg); - assert_child_sa_state(b, 4, CHILD_INSTALLED); - assert_child_sa_count(b, 1); + assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_NONE); + assert_child_sa_state(b, 4, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(b, 2); + assert_ipsec_sas_installed(b, 2, 4, 5); /* <-- CREATE_CHILD_SA { N(NO_CHILD_SA) } */ assert_no_jobs_scheduled(); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, 5, CHILD_INSTALLED); - assert_child_sa_count(a, 1); + assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_NONE); + assert_child_sa_state(a, 5, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(a, 2); + assert_ipsec_sas_installed(a, 1, 4, 5); assert_scheduler(); + /* simulate the execution of the scheduled jobs */ + destroy_rekeyed(a, 1); + assert_child_sa_count(a, 1); + assert_ipsec_sas_installed(a, 4, 5); + destroy_rekeyed(b, 2); + assert_child_sa_count(b, 1); + assert_ipsec_sas_installed(b, 4, 5); + /* child_rekey/child_updown */ assert_hook(); assert_hook(); @@ -842,13 +1120,13 @@ START_TEST(test_collision_ke_invalid) /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> */ assert_hook_not_called(child_rekey); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, 2, CHILD_REKEYING); + assert_child_sa_state(b, 2, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED); assert_child_sa_count(b, 1); assert_hook(); /* <-- CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } */ assert_hook_not_called(child_rekey); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, 1, CHILD_REKEYING); + assert_child_sa_state(a, 1, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED); assert_child_sa_count(a, 1); assert_hook(); @@ -857,7 +1135,7 @@ START_TEST(test_collision_ke_invalid) assert_hook_not_called(child_rekey); assert_single_notify(IN, INVALID_KE_PAYLOAD); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, 1, CHILD_REKEYING); + assert_child_sa_state(a, 1, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED); assert_child_sa_count(a, 1); assert_hook(); /* CREATE_CHILD_SA { N(INVAL_KE) } --> */ @@ -865,7 +1143,7 @@ START_TEST(test_collision_ke_invalid) assert_hook_not_called(child_rekey); assert_single_notify(IN, INVALID_KE_PAYLOAD); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, 2, CHILD_REKEYING); + assert_child_sa_state(b, 2, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED); assert_child_sa_count(b, 1); assert_hook(); @@ -873,15 +1151,15 @@ START_TEST(test_collision_ke_invalid) exchange_test_helper->nonce_first_byte = data[_i].nonces[2]; assert_hook_rekey(child_rekey, 2, 9); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, 2, CHILD_REKEYED); - assert_child_sa_state(b, 9, CHILD_INSTALLED); + assert_child_sa_state(b, 2, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(b, 9, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED); assert_hook(); /* <-- CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } */ exchange_test_helper->nonce_first_byte = data[_i].nonces[3]; assert_hook_rekey(child_rekey, 1, 10); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, 1, CHILD_REKEYED); - assert_child_sa_state(a,10, CHILD_INSTALLED); + assert_child_sa_state(a, 1, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(a,10, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED); assert_hook(); /* <-- CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } */ @@ -891,49 +1169,99 @@ START_TEST(test_collision_ke_invalid) assert_hook_rekey(child_rekey, 1, data[_i].spi_a); exchange_test_helper->process_message(exchange_test_helper, a, NULL); assert_hook(); + assert_child_sa_state(a, data[_i].spi_del_b, CHILD_REKEYED, + CHILD_OUTBOUND_REGISTERED); + assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED, + CHILD_OUTBOUND_INSTALLED); } else { exchange_test_helper->process_message(exchange_test_helper, a, NULL); + assert_child_sa_state(a, data[_i].spi_del_b, CHILD_REKEYED, + CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED, + CHILD_OUTBOUND_REGISTERED); } - assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING); - assert_child_sa_state(a, data[_i].spi_del_b, CHILD_REKEYED); - assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED); + assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING, + CHILD_OUTBOUND_INSTALLED); /* CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } --> */ if (data[_i].spi_del_b == 2) { assert_hook_rekey(child_rekey, 2, data[_i].spi_b); exchange_test_helper->process_message(exchange_test_helper, b, NULL); assert_hook(); + assert_child_sa_state(b, data[_i].spi_del_a, CHILD_REKEYED, + CHILD_OUTBOUND_REGISTERED); + assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED, + CHILD_OUTBOUND_INSTALLED); } else { exchange_test_helper->process_message(exchange_test_helper, b, NULL); + assert_child_sa_state(b, data[_i].spi_del_a, CHILD_REKEYED, + CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED, + CHILD_OUTBOUND_REGISTERED); } - assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING); - assert_child_sa_state(b, data[_i].spi_del_a, CHILD_REKEYED); - assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED); + assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING, + CHILD_OUTBOUND_INSTALLED); /* we don't expect this hook to get called anymore */ assert_hook_not_called(child_rekey); /* INFORMATIONAL { D } --> */ + assert_jobs_scheduled(1); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING); - assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED); - assert_child_sa_count(b, 2); + assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING, + CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(b, data[_i].spi_del_a, CHILD_DELETING, + CHILD_OUTBOUND_NONE); + assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED, + CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(b, 3); + assert_scheduler(); /* <-- INFORMATIONAL { D } */ + assert_jobs_scheduled(1); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING); - assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED); - assert_child_sa_count(a, 2); + assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING, + CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(a, data[_i].spi_del_b, CHILD_DELETING, + CHILD_OUTBOUND_NONE); + assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED, + CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(a, 3); + assert_scheduler(); /* <-- INFORMATIONAL { D } */ + assert_jobs_scheduled(1); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED); - assert_child_sa_count(a, 1); + assert_child_sa_state(a, data[_i].spi_del_a, CHILD_DELETING, + CHILD_OUTBOUND_NONE); + assert_child_sa_state(a, data[_i].spi_del_b, CHILD_DELETING, + CHILD_OUTBOUND_NONE); + assert_child_sa_state(a, data[_i].spi_a, CHILD_INSTALLED, + CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(a, 3); + assert_scheduler(); /* INFORMATIONAL { D } --> */ + assert_jobs_scheduled(1); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED); + assert_child_sa_state(b, data[_i].spi_del_b, CHILD_DELETING, + CHILD_OUTBOUND_NONE); + assert_child_sa_state(b, data[_i].spi_del_a, CHILD_DELETING, + CHILD_OUTBOUND_NONE); + assert_child_sa_state(b, data[_i].spi_b, CHILD_INSTALLED, + CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(b, 3); + assert_scheduler(); + + /* simulate the execution of the scheduled jobs */ + destroy_rekeyed(a, data[_i].spi_del_a); + destroy_rekeyed(a, data[_i].spi_del_b); + assert_child_sa_count(a, 1); + assert_ipsec_sas_installed(a, data[_i].spi_a, data[_i].spi_b); + destroy_rekeyed(b, data[_i].spi_del_a); + destroy_rekeyed(b, data[_i].spi_del_b); assert_child_sa_count(b, 1); + assert_ipsec_sas_installed(b, data[_i].spi_a, data[_i].spi_b); /* child_rekey/child_updown */ assert_hook(); @@ -1004,13 +1332,13 @@ START_TEST(test_collision_ke_invalid_delayed_retry) /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> */ assert_hook_not_called(child_rekey); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, 2, CHILD_REKEYING); + assert_child_sa_state(b, 2, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED); assert_child_sa_count(b, 1); assert_hook(); /* <-- CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } */ assert_hook_not_called(child_rekey); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, 1, CHILD_REKEYING); + assert_child_sa_state(a, 1, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED); assert_child_sa_count(a, 1); assert_hook(); @@ -1019,7 +1347,7 @@ START_TEST(test_collision_ke_invalid_delayed_retry) assert_hook_not_called(child_rekey); assert_single_notify(IN, INVALID_KE_PAYLOAD); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, 1, CHILD_REKEYING); + assert_child_sa_state(a, 1, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED); assert_child_sa_count(a, 1); assert_hook(); /* CREATE_CHILD_SA { N(INVAL_KE) } --> */ @@ -1027,7 +1355,7 @@ START_TEST(test_collision_ke_invalid_delayed_retry) assert_hook_not_called(child_rekey); assert_single_notify(IN, INVALID_KE_PAYLOAD); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, 2, CHILD_REKEYING); + assert_child_sa_state(b, 2, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED); assert_child_sa_count(b, 1); assert_hook(); @@ -1038,14 +1366,14 @@ START_TEST(test_collision_ke_invalid_delayed_retry) exchange_test_helper->nonce_first_byte = data[_i].nonces[2]; assert_hook_rekey(child_rekey, 1, 9); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, 1, CHILD_REKEYED); - assert_child_sa_state(a, 9, CHILD_INSTALLED); + assert_child_sa_state(a, 1, CHILD_REKEYED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(a, 9, CHILD_INSTALLED, CHILD_OUTBOUND_REGISTERED); assert_hook(); /* CREATE_CHILD_SA { SA, Nr, [KEr,] TSi, TSr } --> */ assert_hook_rekey(child_rekey, 2, 8); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, 2, CHILD_DELETING); - assert_child_sa_state(b, 8, CHILD_INSTALLED); + assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(b, 8, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); assert_hook(); /* we don't expect this hook to get called anymore */ @@ -1054,25 +1382,40 @@ START_TEST(test_collision_ke_invalid_delayed_retry) /* CREATE_CHILD_SA { N(REKEY_SA), SA, Ni, [KEi,] TSi, TSr } --> (delayed) */ assert_single_notify(OUT, TEMPORARY_FAILURE); exchange_test_helper->process_message(exchange_test_helper, b, msg); - assert_child_sa_state(b, 2, CHILD_DELETING); - assert_child_sa_state(b, 8, CHILD_INSTALLED); + assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_state(b, 8, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); /* <-- INFORMATIONAL { D } */ + assert_jobs_scheduled(1); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, 9, CHILD_INSTALLED); - assert_child_sa_count(a, 1); + assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_NONE); + assert_child_sa_state(a, 9, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(a, 2); + assert_scheduler(); /* <-- CREATE_CHILD_SA { N(TEMP_FAIL) } */ assert_no_jobs_scheduled(); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, 9, CHILD_INSTALLED); - assert_child_sa_count(a, 1); + assert_child_sa_state(a, 1, CHILD_DELETING, CHILD_OUTBOUND_NONE); + assert_child_sa_state(a, 9, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(a, 2); assert_scheduler(); /* INFORMATIONAL { D } --> */ + assert_jobs_scheduled(1); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, 8, CHILD_INSTALLED); + assert_child_sa_state(b, 2, CHILD_DELETING, CHILD_OUTBOUND_NONE); + assert_child_sa_state(b, 8, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); + assert_child_sa_count(b, 2); + assert_scheduler(); + + /* simulate the execution of the scheduled jobs */ + destroy_rekeyed(a, 1); + assert_child_sa_count(a, 1); + assert_ipsec_sas_installed(a, 8, 9); + destroy_rekeyed(b, 2); assert_child_sa_count(b, 1); + assert_ipsec_sas_installed(b, 8, 9); /* child_rekey/child_updown */ assert_hook(); @@ -1114,7 +1457,7 @@ START_TEST(test_collision_delete) } initiate_rekey(a, spi_a); call_ikesa(b, delete_child_sa, PROTO_ESP, spi_b, FALSE); - assert_child_sa_state(b, spi_b, CHILD_DELETING); + assert_child_sa_state(b, spi_b, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED); /* this should never get called as there is no successful rekeying on * either side */ @@ -1129,7 +1472,7 @@ START_TEST(test_collision_delete) assert_notify(IN, REKEY_SA); assert_single_notify(OUT, TEMPORARY_FAILURE); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, spi_b, CHILD_DELETING); + assert_child_sa_state(b, spi_b, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED); assert_hook(); /* RFC 7296, 2.25.1: If a peer receives a request to delete a CHILD_SA that @@ -1201,7 +1544,7 @@ START_TEST(test_collision_delete_drop_delete) } initiate_rekey(a, spi_a); call_ikesa(b, delete_child_sa, PROTO_ESP, spi_b, FALSE); - assert_child_sa_state(b, spi_b, CHILD_DELETING); + assert_child_sa_state(b, spi_b, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED); /* this should never get called as there is no successful rekeying on * either side */ @@ -1216,7 +1559,7 @@ START_TEST(test_collision_delete_drop_delete) assert_notify(IN, REKEY_SA); assert_single_notify(OUT, TEMPORARY_FAILURE); exchange_test_helper->process_message(exchange_test_helper, b, NULL); - assert_child_sa_state(b, spi_b, CHILD_DELETING); + assert_child_sa_state(b, spi_b, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED); assert_hook(); /* delay the DELETE request */ @@ -1227,7 +1570,7 @@ START_TEST(test_collision_delete_drop_delete) /* we expect a job to retry the rekeying is scheduled */ assert_jobs_scheduled(1); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, spi_a, CHILD_INSTALLED); + assert_child_sa_state(a, spi_a, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); assert_scheduler(); assert_hook(); @@ -1286,7 +1629,7 @@ END_TEST } initiate_rekey(a, spi_a); call_ikesa(b, delete_child_sa, PROTO_ESP, spi_b, FALSE); - assert_child_sa_state(b, spi_b, CHILD_DELETING); + assert_child_sa_state(b, spi_b, CHILD_DELETING, CHILD_OUTBOUND_INSTALLED); /* this should never get called as there is no successful rekeying on * either side */ @@ -1419,13 +1762,13 @@ START_TEST(test_collision_ike_rekey) /* <-- CREATE_CHILD_SA { SA, Ni, KEi } */ assert_single_notify(OUT, TEMPORARY_FAILURE); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, spi_a, CHILD_REKEYING); + assert_child_sa_state(a, spi_a, CHILD_REKEYING, CHILD_OUTBOUND_INSTALLED); /* <-- CREATE_CHILD_SA { N(TEMP_FAIL) } */ /* we expect a job to retry the rekeying is scheduled */ assert_jobs_scheduled(1); exchange_test_helper->process_message(exchange_test_helper, a, NULL); - assert_child_sa_state(a, spi_a, CHILD_INSTALLED); + assert_child_sa_state(a, spi_a, CHILD_INSTALLED, CHILD_OUTBOUND_INSTALLED); assert_scheduler(); /* CREATE_CHILD_SA { N(TEMP_FAIL) } --> */ diff --git a/src/libcharon/tests/utils/exchange_test_asserts.c b/src/libcharon/tests/utils/exchange_test_asserts.c index 2602b97b7..8042d0b63 100644 --- a/src/libcharon/tests/utils/exchange_test_asserts.c +++ b/src/libcharon/tests/utils/exchange_test_asserts.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Tobias Brunner + * Copyright (C) 2016-2017 Tobias Brunner * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -18,6 +18,7 @@ #include <test_suite.h> #include "exchange_test_asserts.h" +#include "mock_ipsec.h" /* * Described in header @@ -180,3 +181,57 @@ bool exchange_test_asserts_message(listener_t *listener, ike_sa_t *ike_sa, } return TRUE; } + +/** + * Compare two SPIs + */ +static int spis_cmp(const void *a, const void *b) +{ + return *(const uint32_t*)a - *(const uint32_t*)b; +} + +/** + * Compare two SPIs to sort them + */ +static int spis_sort(const void *a, const void *b, void *data) +{ + return spis_cmp(a, b); +} + + +/* + * Described in header + */ +void exchange_test_asserts_ipsec_sas(ipsec_sas_assert_t *sas) +{ + enumerator_t *enumerator; + array_t *spis; + ike_sa_t *ike_sa; + uint32_t spi; + int i; + + spis = array_create(sizeof(uint32_t), 0); + for (i = 0; i < sas->count; i++) + { + array_insert(spis, ARRAY_TAIL, &sas->spis[i]); + } + array_sort(spis, spis_sort, NULL); + + enumerator = mock_ipsec_create_sa_enumerator(); + while (enumerator->enumerate(enumerator, &ike_sa, &spi)) + { + if (ike_sa == sas->ike_sa) + { + i = array_bsearch(spis, &spi, spis_cmp, NULL); + assert_listener_msg(i != -1, sas, "unexpected IPsec SA %.8x", spi); + array_remove(spis, i, NULL); + } + } + enumerator->destroy(enumerator); + for (i = 0; i < array_count(spis); i++) + { + array_get(spis, i, &spi); + assert_listener_msg(!spi, sas, "expected IPsec SA %.8x not found", spi); + } + array_destroy(spis); +} diff --git a/src/libcharon/tests/utils/exchange_test_asserts.h b/src/libcharon/tests/utils/exchange_test_asserts.h index 32afcc2e4..4d363edfd 100644 --- a/src/libcharon/tests/utils/exchange_test_asserts.h +++ b/src/libcharon/tests/utils/exchange_test_asserts.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Tobias Brunner + * Copyright (C) 2016-2017 Tobias Brunner * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -14,7 +14,7 @@ */ /** - * Special assertions using listener_t. + * Special assertions using listener_t etc. * * @defgroup exchange_test_asserts exchange_test_asserts * @{ @ingroup test_utils_c @@ -28,6 +28,7 @@ typedef struct listener_hook_assert_t listener_hook_assert_t; typedef struct listener_message_assert_t listener_message_assert_t; typedef struct listener_message_rule_t listener_message_rule_t; +typedef struct ipsec_sas_assert_t ipsec_sas_assert_t; struct listener_hook_assert_t { @@ -340,4 +341,60 @@ bool exchange_test_asserts_message(listener_t *this, ike_sa_t *ike_sa, exchange_test_helper->add_listener(exchange_test_helper, &_listener.listener); \ }) +/** + * Data used to check IPsec SAs + */ +struct ipsec_sas_assert_t { + + /** + * Original source file + */ + const char *file; + + /** + * Source line + */ + int line; + + /** + * IKE_SA that installed the IPsec SAs + */ + ike_sa_t *ike_sa; + + /** + * SPIs to check + */ + uint32_t *spis; + + /** + * Number of SPIs for IPsec SAs to check + */ + int count; +}; + +/** + * Assert that all given IPsec SAs (and only these) are installed for the given + * IKE_SA. + */ +void exchange_test_asserts_ipsec_sas(ipsec_sas_assert_t *sas); + +/** + * Assert that the IPsec SAs with the given SPIs (and none other) are currently + * installed by the given IKE_SA. + * + * @param sa IKE_SA + * @param ... list of SPIs + */ +#define assert_ipsec_sas_installed(sa, ...) ({ \ + uint32_t _spis[] = { __VA_ARGS__ }; \ + ipsec_sas_assert_t _sas_assert = { \ + .file = __FILE__, \ + .line = __LINE__, \ + .ike_sa = sa, \ + .spis = _spis, \ + .count = countof(_spis), \ + }; \ + exchange_test_asserts_ipsec_sas(&_sas_assert); \ +}) + #endif /** EXCHANGE_TEST_ASSERTS_H_ @}*/ diff --git a/src/libcharon/tests/utils/mock_ipsec.c b/src/libcharon/tests/utils/mock_ipsec.c index d57a26a87..d6172f5bd 100644 --- a/src/libcharon/tests/utils/mock_ipsec.c +++ b/src/libcharon/tests/utils/mock_ipsec.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Tobias Brunner + * Copyright (C) 2016-2017 Tobias Brunner * Copyright (C) 2008 Martin Willi * HSR Hochschule fuer Technik Rapperswil * @@ -16,6 +16,12 @@ #include "mock_ipsec.h" +#include <daemon.h> +#include <collections/hashtable.h> +#include <collections/array.h> + +#include <assert.h> + typedef struct private_kernel_ipsec_t private_kernel_ipsec_t; /** @@ -29,16 +35,80 @@ struct private_kernel_ipsec_t { kernel_ipsec_t public; /** + * Rekey listener + */ + listener_t listener; + + /** * Allocated SPI */ refcount_t spi; + + /** + * Installed SAs + */ + hashtable_t *sas; }; +/** + * Global instance + */ +static private_kernel_ipsec_t *instance; + +/** + * Data about installed IPsec SAs + */ +typedef struct { + /** + * SPI of the SA + */ + uint32_t spi; + + /** + * Associated IKE_SA + */ + ike_sa_t *ike_sa; + + /** + * TRUE if this was an allocated SPI + */ + bool alloc; + +} entry_t; + +/** + * Hash an IPsec SA entry + */ +static u_int entry_hash(const void *key) +{ + entry_t *entry = (entry_t*)key; + return chunk_hash_inc(chunk_from_thing(entry->spi), + chunk_hash(chunk_from_thing(entry->ike_sa))); +} + +/** + * Compare an IPsec SA entry + */ +static bool entry_equals(const void *key, const void *other_key) +{ + entry_t *a = (entry_t*)key, *b = (entry_t*)other_key; + return a->spi == b->spi && a->ike_sa == b->ike_sa; +} + METHOD(kernel_ipsec_t, get_spi, status_t, private_kernel_ipsec_t *this, host_t *src, host_t *dst, uint8_t protocol, uint32_t *spi) { + entry_t *entry; + *spi = (uint32_t)ref_get(&this->spi); + INIT(entry, + .spi = *spi, + .ike_sa = charon->bus->get_sa(charon->bus), + .alloc = TRUE, + ); + entry = this->sas->put(this->sas, entry, entry); + assert(!entry); return SUCCESS; } @@ -52,6 +122,23 @@ METHOD(kernel_ipsec_t, add_sa, status_t, private_kernel_ipsec_t *this, kernel_ipsec_sa_id_t *id, kernel_ipsec_add_sa_t *data) { + entry_t *entry; + + INIT(entry, + .spi = id->spi, + .ike_sa = charon->bus->get_sa(charon->bus), + ); + if (data->inbound) + { + entry = this->sas->put(this->sas, entry, entry); + assert(entry && entry->alloc); + free(entry); + } + else + { + entry = this->sas->put(this->sas, entry, entry); + assert(!entry); + } return SUCCESS; } @@ -74,9 +161,47 @@ METHOD(kernel_ipsec_t, del_sa, status_t, private_kernel_ipsec_t *this, kernel_ipsec_sa_id_t *id, kernel_ipsec_del_sa_t *data) { + entry_t *entry, lookup = { + .spi = id->spi, + .ike_sa = charon->bus->get_sa(charon->bus), + }; + + entry = this->sas->remove(this->sas, &lookup); + assert(entry); + free(entry); return SUCCESS; } +METHOD(listener_t, ike_rekey, bool, + listener_t *listener, ike_sa_t *old, ike_sa_t *new) +{ + enumerator_t *enumerator; + array_t *sas = NULL; + entry_t *entry; + + enumerator = instance->sas->create_enumerator(instance->sas); + while (enumerator->enumerate(enumerator, &entry, NULL)) + { + if (entry->ike_sa == old) + { + instance->sas->remove_at(instance->sas, enumerator); + array_insert_create(&sas, ARRAY_TAIL, entry); + } + } + enumerator->destroy(enumerator); + enumerator = array_create_enumerator(sas); + while (enumerator->enumerate(enumerator, &entry)) + { + array_remove_at(sas, enumerator); + entry->ike_sa = new; + entry = instance->sas->put(instance->sas, entry, entry); + assert(!entry); + } + enumerator->destroy(enumerator); + array_destroy(sas); + return TRUE; +} + METHOD(kernel_ipsec_t, add_policy, status_t, private_kernel_ipsec_t *this, kernel_ipsec_policy_id_t *id, kernel_ipsec_manage_policy_t *data) @@ -99,6 +224,14 @@ METHOD(kernel_ipsec_t, del_policy, status_t, return SUCCESS; } +METHOD(kernel_ipsec_t, destroy, void, + private_kernel_ipsec_t *this) +{ + charon->bus->remove_listener(charon->bus, &this->listener); + this->sas->destroy(this->sas); + free(this); +} + /* * Described in header */ @@ -121,8 +254,50 @@ kernel_ipsec_t *mock_ipsec_create() .flush_policies = (void*)return_failed, .bypass_socket = (void*)return_true, .enable_udp_decap = (void*)return_true, - .destroy = (void*)free, + .destroy = _destroy, + }, + .listener = { + .ike_rekey = _ike_rekey, }, + .sas = hashtable_create(entry_hash, entry_equals, 8), ); + + instance = this; + + charon->bus->add_listener(charon->bus, &this->listener); + return &this->public; } + + +CALLBACK(filter_sas, bool, + void *data, enumerator_t *orig, va_list args) +{ + entry_t *entry; + ike_sa_t **ike_sa; + uint32_t *spi; + + VA_ARGS_VGET(args, ike_sa, spi); + + while (orig->enumerate(orig, &entry, NULL)) + { + if (entry->alloc) + { + continue; + } + *ike_sa = entry->ike_sa; + *spi = entry->spi; + return TRUE; + } + return FALSE; +} + +/* + * Described in header + */ +enumerator_t *mock_ipsec_create_sa_enumerator() +{ + return enumerator_create_filter( + instance->sas->create_enumerator(instance->sas), + filter_sas, NULL, NULL); +} diff --git a/src/libcharon/tests/utils/mock_ipsec.h b/src/libcharon/tests/utils/mock_ipsec.h index cbf21524a..95038a561 100644 --- a/src/libcharon/tests/utils/mock_ipsec.h +++ b/src/libcharon/tests/utils/mock_ipsec.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Tobias Brunner + * Copyright (C) 2016-2017 Tobias Brunner * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -15,7 +15,7 @@ /** * kernel_ipsec_t implementation used for exchange unit tests. Currently - * returns sequential SPIs, all other methods are noops. + * returns sequential SPIs, and keeps track of installed SAs. * * @defgroup mock_ipsec mock_ipsec * @{ @ingroup test_utils_c @@ -33,4 +33,11 @@ */ kernel_ipsec_t *mock_ipsec_create(); +/** + * Enumerate the installed SAs + * + * @return enumerator over (ike_sa_t*, uint32_t) + */ +enumerator_t *mock_ipsec_create_sa_enumerator(); + #endif /** MOCK_IPSEC_H_ @}*/ diff --git a/src/libcharon/tests/utils/sa_asserts.h b/src/libcharon/tests/utils/sa_asserts.h index 7afa3b55b..d23f724f1 100644 --- a/src/libcharon/tests/utils/sa_asserts.h +++ b/src/libcharon/tests/utils/sa_asserts.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Tobias Brunner + * Copyright (C) 2016-2017 Tobias Brunner * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -82,13 +82,38 @@ }) /** + * Check if the CHILD_SA with the given SPI is in the expected state, optionally + * check the state of the outbound SA. + */ +#define assert_child_sa_state(...) VA_ARGS_DISPATCH(assert_child_sa_state, __VA_ARGS__)(__VA_ARGS__) + +/** * Check if the CHILD_SA with the given SPI is in the expected state. */ -#define assert_child_sa_state(ike_sa, spi, state) \ +#define assert_child_sa_state3(ike_sa, spi, state) \ +({ \ + typeof(ike_sa) _sa = ike_sa; \ + typeof(spi) _spi = spi; \ + typeof(state) _state = state; \ + child_sa_t *_child = _sa->get_child_sa(_sa, PROTO_ESP, _spi, TRUE) ?: \ + _sa->get_child_sa(_sa, PROTO_ESP, _spi, FALSE); \ + test_assert_msg(_child, "CHILD_SA with SPI %.8x does not exist", \ + ntohl(_spi)); \ + test_assert_msg(_state == _child->get_state(_child), "%N != %N", \ + child_sa_state_names, _state, \ + child_sa_state_names, _child->get_state(_child)); \ +}) + +/** + * Check if the outbound SA of a CHILD_SA with the given SPI is in the + * expected state. + */ +#define assert_child_sa_state4(ike_sa, spi, state, outbound) \ ({ \ typeof(ike_sa) _sa = ike_sa; \ typeof(spi) _spi = spi; \ typeof(state) _state = state; \ + typeof(outbound) _outbound = outbound; \ child_sa_t *_child = _sa->get_child_sa(_sa, PROTO_ESP, _spi, TRUE) ?: \ _sa->get_child_sa(_sa, PROTO_ESP, _spi, FALSE); \ test_assert_msg(_child, "CHILD_SA with SPI %.8x does not exist", \ @@ -96,6 +121,9 @@ test_assert_msg(_state == _child->get_state(_child), "%N != %N", \ child_sa_state_names, _state, \ child_sa_state_names, _child->get_state(_child)); \ + test_assert_msg(_outbound == _child->get_outbound_state(_child), "%N != %N", \ + child_sa_outbound_state_names, _outbound, \ + child_sa_outbound_state_names, _child->get_outbound_state(_child)); \ }) /** diff --git a/src/libfast/Makefile.in b/src/libfast/Makefile.in index c3512b62c..8adf068e2 100644 --- a/src/libfast/Makefile.in +++ b/src/libfast/Makefile.in @@ -361,6 +361,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -383,6 +384,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libimcv/Makefile.in b/src/libimcv/Makefile.in index b0b55fbdc..e361f20f6 100644 --- a/src/libimcv/Makefile.in +++ b/src/libimcv/Makefile.in @@ -530,6 +530,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -552,6 +553,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libimcv/ietf/ietf_attr_installed_packages.c b/src/libimcv/ietf/ietf_attr_installed_packages.c index 7a870ac40..d8e5b3342 100644 --- a/src/libimcv/ietf/ietf_attr_installed_packages.c +++ b/src/libimcv/ietf/ietf_attr_installed_packages.c @@ -179,7 +179,7 @@ METHOD(pa_tnc_attr_t, process, status_t, u_char *pos; if (this->offset == 0) - { + { if (this->length < IETF_INSTALLED_PACKAGES_MIN_SIZE) { DBG1(DBG_TNC, "insufficient data for %N/%N", pen_names, PEN_IETF, @@ -291,15 +291,21 @@ METHOD(ietf_attr_installed_packages_t, add, void, this->packages->insert_last(this->packages, entry); } -/** - * Enumerate package filter entries - */ -static bool package_filter(void *null, package_entry_t **entry, chunk_t *name, - void *i2, chunk_t *version) +CALLBACK(package_filter, bool, + void *null, enumerator_t *orig, va_list args) { - *name = (*entry)->name; - *version = (*entry)->version; - return TRUE; + package_entry_t *entry; + chunk_t *name, *version; + + VA_ARGS_VGET(args, name, version); + + if (orig->enumerate(orig, &entry)) + { + *name = entry->name; + *version = entry->version; + return TRUE; + } + return FALSE; } METHOD(ietf_attr_installed_packages_t, create_enumerator, enumerator_t*, @@ -307,7 +313,7 @@ METHOD(ietf_attr_installed_packages_t, create_enumerator, enumerator_t*, { return enumerator_create_filter( this->packages->create_enumerator(this->packages), - (void*)package_filter, NULL, NULL); + package_filter, NULL, NULL); } METHOD(ietf_attr_installed_packages_t, get_count, uint16_t, diff --git a/src/libimcv/ietf/ietf_attr_op_status.c b/src/libimcv/ietf/ietf_attr_op_status.c index f04c89b96..1f813b3c6 100644 --- a/src/libimcv/ietf/ietf_attr_op_status.c +++ b/src/libimcv/ietf/ietf_attr_op_status.c @@ -170,6 +170,7 @@ METHOD(pa_tnc_attr_t, process, status_t, chunk_t last_use; uint16_t reserved; struct tm t; + char buf[BUF_LEN]; *offset = 0; @@ -208,7 +209,8 @@ METHOD(pa_tnc_attr_t, process, status_t, *offset = 4; /* Conversion from RFC 3339 ASCII string to time_t */ - if (sscanf(last_use.ptr, "%4d-%2d-%2dT%2d:%2d:%2dZ", &t.tm_year, &t.tm_mon, + snprintf(buf, sizeof(buf), "%.*s", (int)last_use.len, last_use.ptr); + if (sscanf(buf, "%4d-%2d-%2dT%2d:%2d:%2dZ", &t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6) { DBG1(DBG_TNC, "invalid last_use time format in IETF operational status"); diff --git a/src/libimcv/ietf/ietf_attr_port_filter.c b/src/libimcv/ietf/ietf_attr_port_filter.c index 05920fdd8..2f7e4452c 100644 --- a/src/libimcv/ietf/ietf_attr_port_filter.c +++ b/src/libimcv/ietf/ietf_attr_port_filter.c @@ -213,24 +213,31 @@ METHOD(ietf_attr_port_filter_t, add_port, void, this->ports->insert_last(this->ports, entry); } -/** - * Enumerate port filter entries - */ -static bool port_filter(void *null, port_entry_t **entry, - bool *blocked, void *i2, uint8_t *protocol, void *i3, - uint16_t *port) +CALLBACK(port_filter, bool, + void *null, enumerator_t *orig, va_list args) { - *blocked = (*entry)->blocked; - *protocol = (*entry)->protocol; - *port = (*entry)->port; - return TRUE; + port_entry_t *entry; + uint16_t *port; + uint8_t *protocol; + bool *blocked; + + VA_ARGS_VGET(args, blocked, protocol, port); + + if (orig->enumerate(orig, &entry)) + { + *blocked = entry->blocked; + *protocol = entry->protocol; + *port = entry->port; + return TRUE; + } + return FALSE; } METHOD(ietf_attr_port_filter_t, create_port_enumerator, enumerator_t*, private_ietf_attr_port_filter_t *this) { return enumerator_create_filter(this->ports->create_enumerator(this->ports), - (void*)port_filter, NULL, NULL); + port_filter, NULL, NULL); } /** diff --git a/src/libimcv/imc/imc_os_info.c b/src/libimcv/imc/imc_os_info.c index 3315c209f..cc23bb250 100644 --- a/src/libimcv/imc/imc_os_info.c +++ b/src/libimcv/imc/imc_os_info.c @@ -283,23 +283,20 @@ typedef struct { } package_enumerator_t; -/** - * Implementation of package_enumerator.destroy. - */ -static void package_enumerator_destroy(package_enumerator_t *this) +METHOD(enumerator_t, package_enumerator_destroy, void, + package_enumerator_t *this) { pclose(this->file); free(this); } -/** - * Implementation of package_enumerator.enumerate - */ -static bool package_enumerator_enumerate(package_enumerator_t *this, ...) +METHOD(enumerator_t, package_enumerator_enumerate, bool, + package_enumerator_t *this, va_list args) { chunk_t *name, *version; u_char *pos; - va_list args; + + VA_ARGS_VGET(args, name, version); while (TRUE) { @@ -319,23 +316,16 @@ static bool package_enumerator_enumerate(package_enumerator_t *this, ...) { continue; } - va_start(args, this); - - name = va_arg(args, chunk_t*); name->ptr = pos; pos = strchr(pos, '\t'); if (!pos) { - va_end(args); return FALSE; } name->len = pos++ - name->ptr; - version = va_arg(args, chunk_t*); version->ptr = pos; version->len = strlen(pos) - 1; - - va_end(args); return TRUE; } } @@ -354,7 +344,7 @@ METHOD(imc_os_info_t, create_package_enumerator, enumerator_t*, return NULL; } - /* Open a pipe stream for reading the output of the dpkg-query commmand */ + /* Open a pipe stream for reading the output of the dpkg-query command */ file = popen(command, "r"); if (!file) { @@ -362,12 +352,14 @@ METHOD(imc_os_info_t, create_package_enumerator, enumerator_t*, return NULL; } - /* Create a package enumerator instance */ - enumerator = malloc_thing(package_enumerator_t); - enumerator->public.enumerate = (void*)package_enumerator_enumerate; - enumerator->public.destroy = (void*)package_enumerator_destroy; - enumerator->file = file; - + INIT(enumerator, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _package_enumerator_enumerate, + .destroy = _package_enumerator_destroy, + }, + .file = file, + ); return (enumerator_t*)enumerator; } diff --git a/src/libimcv/imv/imv_agent.c b/src/libimcv/imv/imv_agent.c index d0508624d..e96faa77e 100644 --- a/src/libimcv/imv/imv_agent.c +++ b/src/libimcv/imv/imv_agent.c @@ -626,22 +626,13 @@ typedef struct { } language_enumerator_t; -/** - * Implementation of language_enumerator.destroy. - */ -static void language_enumerator_destroy(language_enumerator_t *this) -{ - free(this); -} - -/** - * Implementation of language_enumerator.enumerate - */ -static bool language_enumerator_enumerate(language_enumerator_t *this, ...) +METHOD(enumerator_t, language_enumerator_enumerate, bool, + language_enumerator_t *this, va_list args) { char *pos, *cur_lang, **lang; TNC_UInt32 len; - va_list args; + + VA_ARGS_VGET(args, lang); if (!this->lang_len) { @@ -676,11 +667,7 @@ static bool language_enumerator_enumerate(language_enumerator_t *this, ...) } cur_lang[len] = '\0'; - va_start(args, this); - lang = va_arg(args, char**); *lang = cur_lang; - va_end(args); - return TRUE; } @@ -689,10 +676,13 @@ METHOD(imv_agent_t, create_language_enumerator, enumerator_t*, { language_enumerator_t *e; - /* Create a language enumerator instance */ - e = malloc_thing(language_enumerator_t); - e->public.enumerate = (void*)language_enumerator_enumerate; - e->public.destroy = (void*)language_enumerator_destroy; + INIT(e, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _language_enumerator_enumerate, + .destroy = (void*)free, + }, + ); if (!this->get_attribute || !this->get_attribute(this->id, state->get_connection_id(state), diff --git a/src/libimcv/ita/ita_attr_settings.c b/src/libimcv/ita/ita_attr_settings.c index c7c968a26..b0907789e 100644 --- a/src/libimcv/ita/ita_attr_settings.c +++ b/src/libimcv/ita/ita_attr_settings.c @@ -262,22 +262,29 @@ METHOD(ita_attr_settings_t, add, void, this->list->insert_last(this->list, entry); } -/** - * Enumerate name/value pairs - */ -static bool entry_filter(void *null, entry_t **entry, char **name, - void *i2, chunk_t *value) +CALLBACK(entry_filter, bool, + void *null, enumerator_t *orig, va_list args) { - *name = (*entry)->name; - *value = (*entry)->value; - return TRUE; + entry_t *entry; + chunk_t *value; + char **name; + + VA_ARGS_VGET(args, name, value); + + while (orig->enumerate(orig, &entry)) + { + *name = entry->name; + *value = entry->value; + return TRUE; + } + return FALSE; } METHOD(ita_attr_settings_t, create_enumerator, enumerator_t*, private_ita_attr_settings_t *this) { return enumerator_create_filter(this->list->create_enumerator(this->list), - (void*)entry_filter, NULL, NULL); + entry_filter, NULL, NULL); } /** diff --git a/src/libimcv/plugins/imc_attestation/Makefile.in b/src/libimcv/plugins/imc_attestation/Makefile.in index 0475cee50..d67050f0d 100644 --- a/src/libimcv/plugins/imc_attestation/Makefile.in +++ b/src/libimcv/plugins/imc_attestation/Makefile.in @@ -356,6 +356,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -378,6 +379,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libimcv/plugins/imc_hcd/Makefile.in b/src/libimcv/plugins/imc_hcd/Makefile.in index e2f1dc5fb..981af3964 100644 --- a/src/libimcv/plugins/imc_hcd/Makefile.in +++ b/src/libimcv/plugins/imc_hcd/Makefile.in @@ -353,6 +353,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -375,6 +376,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libimcv/plugins/imc_os/Makefile.in b/src/libimcv/plugins/imc_os/Makefile.in index 0fa0d196b..aa0c49aeb 100644 --- a/src/libimcv/plugins/imc_os/Makefile.in +++ b/src/libimcv/plugins/imc_os/Makefile.in @@ -353,6 +353,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -375,6 +376,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libimcv/plugins/imc_scanner/Makefile.in b/src/libimcv/plugins/imc_scanner/Makefile.in index 1b776b2c1..63b43154c 100644 --- a/src/libimcv/plugins/imc_scanner/Makefile.in +++ b/src/libimcv/plugins/imc_scanner/Makefile.in @@ -354,6 +354,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -376,6 +377,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libimcv/plugins/imc_scanner/imc_scanner.c b/src/libimcv/plugins/imc_scanner/imc_scanner.c index bf2479cf5..93ed4271b 100644 --- a/src/libimcv/plugins/imc_scanner/imc_scanner.c +++ b/src/libimcv/plugins/imc_scanner/imc_scanner.c @@ -116,7 +116,7 @@ static bool do_netstat(ietf_attr_port_filter_t *attr) const char loopback_v4[] = "127.0.0.1"; const char loopback_v6[] = "::1"; - /* Open a pipe stream for reading the output of the netstat commmand */ + /* Open a pipe stream for reading the output of the netstat command */ file = popen("/bin/netstat -n -l -p -4 -6 --inet", "r"); if (!file) { diff --git a/src/libimcv/plugins/imc_swid/Makefile.in b/src/libimcv/plugins/imc_swid/Makefile.in index 13d1924d4..02bc2bfef 100644 --- a/src/libimcv/plugins/imc_swid/Makefile.in +++ b/src/libimcv/plugins/imc_swid/Makefile.in @@ -356,6 +356,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -378,6 +379,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libimcv/plugins/imc_test/Makefile.in b/src/libimcv/plugins/imc_test/Makefile.in index 7a4149e70..93c074853 100644 --- a/src/libimcv/plugins/imc_test/Makefile.in +++ b/src/libimcv/plugins/imc_test/Makefile.in @@ -353,6 +353,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -375,6 +376,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libimcv/plugins/imc_test/imc_test_state.h b/src/libimcv/plugins/imc_test/imc_test_state.h index 5f9ee2537..365caff7c 100644 --- a/src/libimcv/plugins/imc_test/imc_test_state.h +++ b/src/libimcv/plugins/imc_test/imc_test_state.h @@ -42,14 +42,14 @@ struct imc_test_state_t { /** * get the command to send to IMV * - * @return commmand to send to IMV + * @return command to send to IMV */ char* (*get_command)(imc_test_state_t *this); /** * set the command to send to IMV * - * @param command commmand to send to IMV + * @param command command to send to IMV */ void (*set_command)(imc_test_state_t *this, char *command); diff --git a/src/libimcv/plugins/imv_attestation/Makefile.in b/src/libimcv/plugins/imv_attestation/Makefile.in index 9782757e0..02bd5f510 100644 --- a/src/libimcv/plugins/imv_attestation/Makefile.in +++ b/src/libimcv/plugins/imv_attestation/Makefile.in @@ -367,6 +367,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -389,6 +390,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation_state.c b/src/libimcv/plugins/imv_attestation/imv_attestation_state.c index 1c3b91aeb..d63940797 100644 --- a/src/libimcv/plugins/imv_attestation/imv_attestation_state.c +++ b/src/libimcv/plugins/imv_attestation/imv_attestation_state.c @@ -418,24 +418,24 @@ METHOD(imv_attestation_state_t, create_component, pts_component_t*, } } -/** - * Enumerate file measurement entries - */ -static bool entry_filter(void *null, func_comp_t **entry, uint8_t *flags, - void *i2, uint32_t *depth, - void *i3, pts_comp_func_name_t **comp_name) +CALLBACK(entry_filter, bool, + void *null, enumerator_t *orig, va_list args) { - pts_component_t *comp; - pts_comp_func_name_t *name; - - comp = (*entry)->comp; - name = (*entry)->name; + func_comp_t *entry; + pts_comp_func_name_t **comp_name; + uint32_t *depth; + uint8_t *flags; - *flags = comp->get_evidence_flags(comp); - *depth = comp->get_depth(comp); - *comp_name = name; + VA_ARGS_VGET(args, flags, depth, comp_name); - return TRUE; + if (orig->enumerate(orig, &entry)) + { + *flags = entry->comp->get_evidence_flags(entry->comp); + *depth = entry->comp->get_depth(entry->comp); + *comp_name = entry->name; + return TRUE; + } + return FALSE; } METHOD(imv_attestation_state_t, create_component_enumerator, enumerator_t*, @@ -443,7 +443,7 @@ METHOD(imv_attestation_state_t, create_component_enumerator, enumerator_t*, { return enumerator_create_filter( this->components->create_enumerator(this->components), - (void*)entry_filter, NULL, NULL); + entry_filter, NULL, NULL); } METHOD(imv_attestation_state_t, get_component, pts_component_t*, diff --git a/src/libimcv/plugins/imv_hcd/Makefile.in b/src/libimcv/plugins/imv_hcd/Makefile.in index 62bd827f9..b19cb4a41 100644 --- a/src/libimcv/plugins/imv_hcd/Makefile.in +++ b/src/libimcv/plugins/imv_hcd/Makefile.in @@ -353,6 +353,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -375,6 +376,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libimcv/plugins/imv_os/Makefile.in b/src/libimcv/plugins/imv_os/Makefile.in index efefdc87b..f2804f3fc 100644 --- a/src/libimcv/plugins/imv_os/Makefile.in +++ b/src/libimcv/plugins/imv_os/Makefile.in @@ -361,6 +361,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -383,6 +384,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libimcv/plugins/imv_scanner/Makefile.in b/src/libimcv/plugins/imv_scanner/Makefile.in index 535e28f1b..6cc107edb 100644 --- a/src/libimcv/plugins/imv_scanner/Makefile.in +++ b/src/libimcv/plugins/imv_scanner/Makefile.in @@ -355,6 +355,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -377,6 +378,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libimcv/plugins/imv_swid/Makefile.in b/src/libimcv/plugins/imv_swid/Makefile.in index 1150f12f9..3560752ed 100644 --- a/src/libimcv/plugins/imv_swid/Makefile.in +++ b/src/libimcv/plugins/imv_swid/Makefile.in @@ -356,6 +356,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -378,6 +379,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libimcv/plugins/imv_swid/imv_swid_rest.c b/src/libimcv/plugins/imv_swid/imv_swid_rest.c index 143b0b239..0fe96edef 100644 --- a/src/libimcv/plugins/imv_swid/imv_swid_rest.c +++ b/src/libimcv/plugins/imv_swid/imv_swid_rest.c @@ -70,27 +70,29 @@ METHOD(imv_swid_rest_t, post, status_t, FETCH_END); free(uri); - if (status == SUCCESS) + if (status != SUCCESS) { - return SUCCESS; - } - - if (code != HTTP_STATUS_CODE_PRECONDITION_FAILED || !response.ptr) - { - DBG2(DBG_IMV, "REST http request failed with status code: %d", code); - return FAILED; - } - - if (jresponse) - { - /* Parse HTTP response into a JSON object */ - tokener = json_tokener_new(); - *jresponse = json_tokener_parse_ex(tokener, response.ptr, response.len); - json_tokener_free(tokener); + if (code != HTTP_STATUS_CODE_PRECONDITION_FAILED || !response.ptr) + { + DBG2(DBG_IMV, "REST http request failed with status code: %d", code); + status = FAILED; + } + else + { + if (jresponse) + { + /* Parse HTTP response into a JSON object */ + tokener = json_tokener_new(); + *jresponse = json_tokener_parse_ex(tokener, response.ptr, + response.len); + json_tokener_free(tokener); + } + status = NEED_MORE; + } } free(response.ptr); - return NEED_MORE; + return status; } METHOD(imv_swid_rest_t, destroy, void, diff --git a/src/libimcv/plugins/imv_test/Makefile.in b/src/libimcv/plugins/imv_test/Makefile.in index 055d6fdce..9aebfef67 100644 --- a/src/libimcv/plugins/imv_test/Makefile.in +++ b/src/libimcv/plugins/imv_test/Makefile.in @@ -354,6 +354,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -376,6 +377,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libimcv/plugins/imv_test/imv_test_agent.c b/src/libimcv/plugins/imv_test/imv_test_agent.c index 5e4b4866a..fc14359d5 100644 --- a/src/libimcv/plugins/imv_test/imv_test_agent.c +++ b/src/libimcv/plugins/imv_test/imv_test_agent.c @@ -188,6 +188,8 @@ static TNC_Result receive_msg(private_imv_test_agent_t *this, imv_state_t *state if (retry) { test_state->set_rounds(test_state, rounds); + out_msg->destroy(out_msg); + return this->agent->request_handshake_retry( this->agent->get_id(this->agent), state->get_connection_id(state), diff --git a/src/libimcv/pts/pts_file_meas.c b/src/libimcv/pts/pts_file_meas.c index 6cfb86cb3..92f513a2d 100644 --- a/src/libimcv/pts/pts_file_meas.c +++ b/src/libimcv/pts/pts_file_meas.c @@ -94,22 +94,29 @@ METHOD(pts_file_meas_t, add, void, this->list->insert_last(this->list, entry); } -/** - * Enumerate file measurement entries - */ -static bool entry_filter(void *null, entry_t **entry, char **filename, - void *i2, chunk_t *measurement) +CALLBACK(entry_filter, bool, + void *null, enumerator_t *orig, va_list args) { - *filename = (*entry)->filename; - *measurement = (*entry)->measurement; - return TRUE; + entry_t *entry; + chunk_t *measurement; + char **filename; + + VA_ARGS_VGET(args, filename, measurement); + + if (orig->enumerate(orig, &entry)) + { + *filename = entry->filename; + *measurement = entry->measurement; + return TRUE; + } + return FALSE; } METHOD(pts_file_meas_t, create_enumerator, enumerator_t*, private_pts_file_meas_t *this) { return enumerator_create_filter(this->list->create_enumerator(this->list), - (void*)entry_filter, NULL, NULL); + entry_filter, NULL, NULL); } METHOD(pts_file_meas_t, check, bool, diff --git a/src/libimcv/pts/pts_pcr.c b/src/libimcv/pts/pts_pcr.c index d514532c5..9f098c08e 100644 --- a/src/libimcv/pts/pts_pcr.c +++ b/src/libimcv/pts/pts_pcr.c @@ -111,17 +111,12 @@ typedef struct { private_pts_pcr_t *pcrs; } pcr_enumerator_t; -/** - * Implementation of enumerator.enumerate - */ -static bool pcr_enumerator_enumerate(pcr_enumerator_t *this, ...) +METHOD(enumerator_t, pcr_enumerator_enumerate, bool, + pcr_enumerator_t *this, va_list args) { - uint32_t *pcr, i, f; - va_list args; + uint32_t i, f, *pcr; - va_start(args, this); - pcr = va_arg(args, uint32_t*); - va_end(args); + VA_ARGS_VGET(args, pcr); while (this->pcr <= this->pcrs->pcr_max) { @@ -148,7 +143,8 @@ METHOD(pts_pcr_t, create_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)pcr_enumerator_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _pcr_enumerator_enumerate, .destroy = (void*)free, }, .pcrs = this, diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_req_func_comp_evid.c b/src/libimcv/tcg/pts/tcg_pts_attr_req_func_comp_evid.c index da21003e3..0d8486756 100644 --- a/src/libimcv/tcg/pts/tcg_pts_attr_req_func_comp_evid.c +++ b/src/libimcv/tcg/pts/tcg_pts_attr_req_func_comp_evid.c @@ -115,18 +115,24 @@ struct entry_t { pts_comp_func_name_t *name; }; -/** - * Enumerate functional component entries - */ -static bool entry_filter(void *null, entry_t **entry, uint8_t *flags, - void *i2, uint32_t *depth, void *i3, - pts_comp_func_name_t **name) +CALLBACK(entry_filter, bool, + void *null, enumerator_t *orig, va_list args) { - *flags = (*entry)->flags; - *depth = (*entry)->depth; - *name = (*entry)->name; + entry_t *entry; + pts_comp_func_name_t **name; + uint32_t *depth; + uint8_t *flags; - return TRUE; + VA_ARGS_VGET(args, flags, depth, name); + + if (orig->enumerate(orig, &entry)) + { + *flags = entry->flags; + *depth = entry->depth; + *name = entry->name; + return TRUE; + } + return FALSE; } /** @@ -318,7 +324,7 @@ METHOD(tcg_pts_attr_req_func_comp_evid_t, create_enumerator, enumerator_t*, private_tcg_pts_attr_req_func_comp_evid_t *this) { return enumerator_create_filter(this->list->create_enumerator(this->list), - (void*)entry_filter, NULL, NULL); + entry_filter, NULL, NULL); } /** diff --git a/src/libimcv/tcg/pts/tcg_pts_attr_simple_comp_evid.c b/src/libimcv/tcg/pts/tcg_pts_attr_simple_comp_evid.c index c249ca151..9438fa062 100644 --- a/src/libimcv/tcg/pts/tcg_pts_attr_simple_comp_evid.c +++ b/src/libimcv/tcg/pts/tcg_pts_attr_simple_comp_evid.c @@ -263,13 +263,15 @@ bool measurement_time_from_utc(time_t *measurement_time, chunk_t utc_time) { int tm_year, tm_mon, tm_day, tm_days, tm_hour, tm_min, tm_sec, tm_secs; int tm_leap_4, tm_leap_100, tm_leap_400, tm_leap; + char buf[BUF_LEN]; if (memeq(utc_undefined_time_str, utc_time.ptr, utc_time.len)) { *measurement_time = 0; return TRUE; } - if (sscanf(utc_time.ptr, "%4d-%2d-%2dT%2d:%2d:%2dZ", + snprintf(buf, sizeof(buf), "%.*s", (int)utc_time.len, utc_time.ptr); + if (sscanf(buf, "%4d-%2d-%2dT%2d:%2d:%2dZ", &tm_year, &tm_mon, &tm_day, &tm_hour, &tm_min, &tm_sec) != 6) { return FALSE; diff --git a/src/libipsec/Makefile.in b/src/libipsec/Makefile.in index 7d514fd6e..55d1d58b5 100644 --- a/src/libipsec/Makefile.in +++ b/src/libipsec/Makefile.in @@ -398,6 +398,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -420,6 +421,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libipsec/ipsec_sa_mgr.c b/src/libipsec/ipsec_sa_mgr.c index a1fa23e28..957d930f2 100644 --- a/src/libipsec/ipsec_sa_mgr.c +++ b/src/libipsec/ipsec_sa_mgr.c @@ -224,42 +224,60 @@ static void flush_entries(private_ipsec_sa_mgr_t *this) enumerator->destroy(enumerator); } -/* - * Different match functions to find SAs in the linked list - */ -static bool match_entry_by_ptr(ipsec_sa_entry_t *item, ipsec_sa_entry_t *entry) +CALLBACK(match_entry_by_sa_ptr, bool, + ipsec_sa_entry_t *item, va_list args) { - return item == entry; -} + ipsec_sa_t *sa; -static bool match_entry_by_sa_ptr(ipsec_sa_entry_t *item, ipsec_sa_t *sa) -{ + VA_ARGS_VGET(args, sa); return item->sa == sa; } -static bool match_entry_by_spi_inbound(ipsec_sa_entry_t *item, uint32_t *spi, - bool *inbound) +CALLBACK(match_entry_by_spi_inbound, bool, + ipsec_sa_entry_t *item, va_list args) { - return item->sa->get_spi(item->sa) == *spi && - item->sa->is_inbound(item->sa) == *inbound; + uint32_t spi; + int inbound; + + VA_ARGS_VGET(args, spi, inbound); + return item->sa->get_spi(item->sa) == spi && + item->sa->is_inbound(item->sa) == inbound; } -static bool match_entry_by_spi_src_dst(ipsec_sa_entry_t *item, uint32_t *spi, +static bool match_entry_by_spi_src_dst(ipsec_sa_entry_t *item, uint32_t spi, host_t *src, host_t *dst) { - return item->sa->match_by_spi_src_dst(item->sa, *spi, src, dst); + return item->sa->match_by_spi_src_dst(item->sa, spi, src, dst); } -static bool match_entry_by_reqid_inbound(ipsec_sa_entry_t *item, - uint32_t *reqid, bool *inbound) +CALLBACK(match_entry_by_spi_src_dst_cb, bool, + ipsec_sa_entry_t *item, va_list args) { - return item->sa->match_by_reqid(item->sa, *reqid, *inbound); + host_t *src, *dst; + uint32_t spi; + + VA_ARGS_VGET(args, spi, src, dst); + return match_entry_by_spi_src_dst(item, spi, src, dst); +} + +CALLBACK(match_entry_by_reqid_inbound, bool, + ipsec_sa_entry_t *item, va_list args) +{ + uint32_t reqid; + int inbound; + + VA_ARGS_VGET(args, reqid, inbound); + return item->sa->match_by_reqid(item->sa, reqid, inbound); } -static bool match_entry_by_spi_dst(ipsec_sa_entry_t *item, uint32_t *spi, - host_t *dst) +CALLBACK(match_entry_by_spi_dst, bool, + ipsec_sa_entry_t *item, va_list args) { - return item->sa->match_by_spi_dst(item->sa, *spi, dst); + host_t *dst; + uint32_t spi; + + VA_ARGS_VGET(args, spi, dst); + return item->sa->match_by_spi_dst(item->sa, spi, dst); } /** @@ -296,8 +314,7 @@ static job_requeue_t sa_expired(ipsec_sa_expired_t *expired) private_ipsec_sa_mgr_t *this = expired->manager; this->mutex->lock(this->mutex); - if (this->sas->find_first(this->sas, (void*)match_entry_by_ptr, - NULL, expired->entry) == SUCCESS) + if (this->sas->find_first(this->sas, NULL, (void**)&expired->entry)) { uint32_t hard_offset; @@ -383,8 +400,8 @@ static bool allocate_spi(private_ipsec_sa_mgr_t *this, uint32_t spi) uint32_t *spi_alloc; if (this->allocated_spis->get(this->allocated_spis, &spi) || - this->sas->find_first(this->sas, (void*)match_entry_by_spi_inbound, - NULL, &spi, TRUE) == SUCCESS) + this->sas->find_first(this->sas, match_entry_by_spi_inbound, + NULL, spi, TRUE)) { return FALSE; } @@ -484,8 +501,8 @@ METHOD(ipsec_sa_mgr_t, add_sa, status_t, free(spi_alloc); } - if (this->sas->find_first(this->sas, (void*)match_entry_by_spi_src_dst, - NULL, &spi, src, dst) == SUCCESS) + if (this->sas->find_first(this->sas, match_entry_by_spi_src_dst_cb, NULL, + spi, src, dst)) { this->mutex->unlock(this->mutex); DBG1(DBG_ESP, "failed to install SAD entry: already installed"); @@ -519,8 +536,8 @@ METHOD(ipsec_sa_mgr_t, update_sa, status_t, } this->mutex->lock(this->mutex); - if (this->sas->find_first(this->sas, (void*)match_entry_by_spi_src_dst, - (void**)&entry, &spi, src, dst) == SUCCESS && + if (this->sas->find_first(this->sas, match_entry_by_spi_src_dst_cb, + (void**)&entry, spi, src, dst) && wait_for_entry(this, entry)) { entry->sa->set_source(entry->sa, new_src); @@ -547,8 +564,8 @@ METHOD(ipsec_sa_mgr_t, query_sa, status_t, ipsec_sa_entry_t *entry = NULL; this->mutex->lock(this->mutex); - if (this->sas->find_first(this->sas, (void*)match_entry_by_spi_src_dst, - (void**)&entry, &spi, src, dst) == SUCCESS && + if (this->sas->find_first(this->sas, match_entry_by_spi_src_dst_cb, + (void**)&entry, spi, src, dst) && wait_for_entry(this, entry)) { entry->sa->get_usestats(entry->sa, bytes, packets, time); @@ -572,7 +589,7 @@ METHOD(ipsec_sa_mgr_t, del_sa, status_t, enumerator = this->sas->create_enumerator(this->sas); while (enumerator->enumerate(enumerator, (void**)¤t)) { - if (match_entry_by_spi_src_dst(current, &spi, src, dst)) + if (match_entry_by_spi_src_dst(current, spi, src, dst)) { if (wait_remove_entry(this, current)) { @@ -602,8 +619,8 @@ METHOD(ipsec_sa_mgr_t, checkout_by_reqid, ipsec_sa_t*, ipsec_sa_t *sa = NULL; this->mutex->lock(this->mutex); - if (this->sas->find_first(this->sas, (void*)match_entry_by_reqid_inbound, - (void**)&entry, &reqid, &inbound) == SUCCESS && + if (this->sas->find_first(this->sas, match_entry_by_reqid_inbound, + (void**)&entry, reqid, inbound) && wait_for_entry(this, entry)) { sa = entry->sa; @@ -619,8 +636,8 @@ METHOD(ipsec_sa_mgr_t, checkout_by_spi, ipsec_sa_t*, ipsec_sa_t *sa = NULL; this->mutex->lock(this->mutex); - if (this->sas->find_first(this->sas, (void*)match_entry_by_spi_dst, - (void**)&entry, &spi, dst) == SUCCESS && + if (this->sas->find_first(this->sas, match_entry_by_spi_dst, + (void**)&entry, spi, dst) && wait_for_entry(this, entry)) { sa = entry->sa; @@ -635,8 +652,8 @@ METHOD(ipsec_sa_mgr_t, checkin, void, ipsec_sa_entry_t *entry; this->mutex->lock(this->mutex); - if (this->sas->find_first(this->sas, (void*)match_entry_by_sa_ptr, - (void**)&entry, sa) == SUCCESS) + if (this->sas->find_first(this->sas, match_entry_by_sa_ptr, + (void**)&entry, sa)) { if (entry->locked) { diff --git a/src/libipsec/tests/Makefile.in b/src/libipsec/tests/Makefile.in index e81d6fc9f..b1fdea499 100644 --- a/src/libipsec/tests/Makefile.in +++ b/src/libipsec/tests/Makefile.in @@ -351,6 +351,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -373,6 +374,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libpttls/Makefile.in b/src/libpttls/Makefile.in index fd3e76391..803d68722 100644 --- a/src/libpttls/Makefile.in +++ b/src/libpttls/Makefile.in @@ -356,6 +356,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -378,6 +379,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libpttls/sasl/sasl_mechanism.c b/src/libpttls/sasl/sasl_mechanism.c index 05a02e56d..4e54de314 100644 --- a/src/libpttls/sasl/sasl_mechanism.c +++ b/src/libpttls/sasl/sasl_mechanism.c @@ -59,8 +59,11 @@ typedef struct { } mech_enumerator_t; METHOD(enumerator_t, mech_enumerate, bool, - mech_enumerator_t *this, char **name) + mech_enumerator_t *this, va_list args) { + char **name; + + VA_ARGS_VGET(args, name); while (this->i < countof(mechs)) { if (mechs[this->i].server == this->server) @@ -83,7 +86,8 @@ enumerator_t* sasl_mechanism_create_enumerator(bool server) INIT(enumerator, .public = { - .enumerate = (void*)_mech_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _mech_enumerate, .destroy = (void*)free, }, .server = server, diff --git a/src/libradius/Makefile.in b/src/libradius/Makefile.in index 8f91275c7..9e7b7372b 100644 --- a/src/libradius/Makefile.in +++ b/src/libradius/Makefile.in @@ -351,6 +351,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -373,6 +374,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libradius/radius_message.c b/src/libradius/radius_message.c index 9705d3b53..51135fbea 100644 --- a/src/libradius/radius_message.c +++ b/src/libradius/radius_message.c @@ -244,8 +244,12 @@ typedef struct { } attribute_enumerator_t; METHOD(enumerator_t, attribute_enumerate, bool, - attribute_enumerator_t *this, int *type, chunk_t *data) + attribute_enumerator_t *this, va_list args) { + chunk_t *data; + int *type; + + VA_ARGS_VGET(args, type, data); if (this->left == 0) { return FALSE; @@ -275,7 +279,8 @@ METHOD(radius_message_t, create_enumerator, enumerator_t*, } INIT(e, .public = { - .enumerate = (void*)_attribute_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _attribute_enumerate, .destroy = (void*)free, }, .next = (rattr_t*)this->msg->attributes, @@ -299,12 +304,14 @@ typedef struct { } vendor_enumerator_t; METHOD(enumerator_t, vendor_enumerate, bool, - vendor_enumerator_t *this, int *vendor, int *type, chunk_t *data) + vendor_enumerator_t *this, va_list args) { - chunk_t inner_data; - int inner_type; + chunk_t inner_data, *data; + int inner_type, *vendor, *type; uint8_t type8, len; + VA_ARGS_VGET(args, vendor, type, data); + while (TRUE) { if (this->reader) @@ -354,7 +361,8 @@ METHOD(radius_message_t, create_vendor_enumerator, enumerator_t*, INIT(e, .public = { - .enumerate = (void*)_vendor_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _vendor_enumerate, .destroy = _vendor_destroy, }, .inner = create_enumerator(this), diff --git a/src/libsimaka/Makefile.in b/src/libsimaka/Makefile.in index 6af66e324..6ecbaecaa 100644 --- a/src/libsimaka/Makefile.in +++ b/src/libsimaka/Makefile.in @@ -354,6 +354,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -376,6 +377,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libsimaka/simaka_message.c b/src/libsimaka/simaka_message.c index 234d7ef2a..6827c1795 100644 --- a/src/libsimaka/simaka_message.c +++ b/src/libsimaka/simaka_message.c @@ -222,17 +222,22 @@ METHOD(simaka_message_t, get_type, eap_type_t, return this->hdr->type; } -/** - * convert attr_t to type and data enumeration - */ -static bool attr_enum_filter(void *null, attr_t **in, simaka_attribute_t *type, - void *dummy, chunk_t *data) +CALLBACK(attr_enum_filter, bool, + void *null, enumerator_t *orig, va_list args) { - attr_t *attr = *in; + attr_t *attr; + simaka_attribute_t *type; + chunk_t *data; - *type = attr->type; - *data = chunk_create(attr->data, attr->len); - return TRUE; + VA_ARGS_VGET(args, type, data); + + if (orig->enumerate(orig, &attr)) + { + *type = attr->type; + *data = chunk_create(attr->data, attr->len); + return TRUE; + } + return FALSE; } METHOD(simaka_message_t, create_attribute_enumerator, enumerator_t*, @@ -240,7 +245,7 @@ METHOD(simaka_message_t, create_attribute_enumerator, enumerator_t*, { return enumerator_create_filter( this->attributes->create_enumerator(this->attributes), - (void*)attr_enum_filter, NULL, NULL); + attr_enum_filter, NULL, NULL); } METHOD(simaka_message_t, add_attribute, void, diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index f6d6f5465..b4d8452f1 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -195,6 +195,7 @@ endif EXTRA_DIST = \ asn1/oid.txt asn1/oid.pl \ crypto/proposal/proposal_keywords_static.txt \ +plugins/plugin_constructors.py \ Android.mk BUILT_SOURCES = \ @@ -220,6 +221,15 @@ $(srcdir)/crypto/proposal/proposal_keywords_static.c: $(srcdir)/crypto/proposal/ $(GPERF) -N proposal_get_token_static -m 10 -C -G -c -t -D < \ $(srcdir)/crypto/proposal/proposal_keywords_static.txt > $@ +if STATIC_PLUGIN_CONSTRUCTORS +BUILT_SOURCES += $(srcdir)/plugin_constructors.c +CLEANFILES = $(srcdir)/plugin_constructors.c + +$(srcdir)/plugin_constructors.c: $(srcdir)/plugins/plugin_constructors.py + $(AM_V_GEN) \ + $(PYTHON) $(srcdir)/plugins/plugin_constructors.py ${s_plugins} > $@ +endif + if MONOLITHIC SUBDIRS = else diff --git a/src/libstrongswan/Makefile.in b/src/libstrongswan/Makefile.in index 99bb1158c..9b1c26b35 100644 --- a/src/libstrongswan/Makefile.in +++ b/src/libstrongswan/Makefile.in @@ -123,128 +123,129 @@ host_triplet = @host@ @USE_BUILTIN_PRINTF_TRUE@am__append_15 = -lm @USE_BUILTIN_PRINTF_FALSE@@USE_VSTR_FALSE@am__append_16 = utils/printf_hook/printf_hook_glibc.c @USE_LIBCAP_TRUE@am__append_17 = -lcap +@STATIC_PLUGIN_CONSTRUCTORS_TRUE@am__append_18 = $(srcdir)/plugin_constructors.c # build libnttfft used by some plugins ###################################### -@USE_LIBNTTFFT_TRUE@am__append_18 = math/libnttfft +@USE_LIBNTTFFT_TRUE@am__append_19 = math/libnttfft # build plugins with their own Makefile ####################################### -@USE_AF_ALG_TRUE@am__append_19 = plugins/af_alg -@MONOLITHIC_TRUE@@USE_AF_ALG_TRUE@am__append_20 = plugins/af_alg/libstrongswan-af-alg.la -@USE_AES_TRUE@am__append_21 = plugins/aes -@MONOLITHIC_TRUE@@USE_AES_TRUE@am__append_22 = plugins/aes/libstrongswan-aes.la -@USE_DES_TRUE@am__append_23 = plugins/des -@MONOLITHIC_TRUE@@USE_DES_TRUE@am__append_24 = plugins/des/libstrongswan-des.la -@USE_BLOWFISH_TRUE@am__append_25 = plugins/blowfish -@MONOLITHIC_TRUE@@USE_BLOWFISH_TRUE@am__append_26 = plugins/blowfish/libstrongswan-blowfish.la -@USE_RC2_TRUE@am__append_27 = plugins/rc2 -@MONOLITHIC_TRUE@@USE_RC2_TRUE@am__append_28 = plugins/rc2/libstrongswan-rc2.la -@USE_MD4_TRUE@am__append_29 = plugins/md4 -@MONOLITHIC_TRUE@@USE_MD4_TRUE@am__append_30 = plugins/md4/libstrongswan-md4.la -@USE_MD5_TRUE@am__append_31 = plugins/md5 -@MONOLITHIC_TRUE@@USE_MD5_TRUE@am__append_32 = plugins/md5/libstrongswan-md5.la -@USE_SHA1_TRUE@am__append_33 = plugins/sha1 -@MONOLITHIC_TRUE@@USE_SHA1_TRUE@am__append_34 = plugins/sha1/libstrongswan-sha1.la -@USE_SHA2_TRUE@am__append_35 = plugins/sha2 -@MONOLITHIC_TRUE@@USE_SHA2_TRUE@am__append_36 = plugins/sha2/libstrongswan-sha2.la -@USE_SHA3_TRUE@am__append_37 = plugins/sha3 -@MONOLITHIC_TRUE@@USE_SHA3_TRUE@am__append_38 = plugins/sha3/libstrongswan-sha3.la -@USE_GMP_TRUE@am__append_39 = plugins/gmp -@MONOLITHIC_TRUE@@USE_GMP_TRUE@am__append_40 = plugins/gmp/libstrongswan-gmp.la -@USE_CURVE25519_TRUE@am__append_41 = plugins/curve25519 -@MONOLITHIC_TRUE@@USE_CURVE25519_TRUE@am__append_42 = plugins/curve25519/libstrongswan-curve25519.la -@USE_RDRAND_TRUE@am__append_43 = plugins/rdrand -@MONOLITHIC_TRUE@@USE_RDRAND_TRUE@am__append_44 = plugins/rdrand/libstrongswan-rdrand.la -@USE_AESNI_TRUE@am__append_45 = plugins/aesni -@MONOLITHIC_TRUE@@USE_AESNI_TRUE@am__append_46 = plugins/aesni/libstrongswan-aesni.la -@USE_RANDOM_TRUE@am__append_47 = plugins/random -@MONOLITHIC_TRUE@@USE_RANDOM_TRUE@am__append_48 = plugins/random/libstrongswan-random.la -@USE_NONCE_TRUE@am__append_49 = plugins/nonce -@MONOLITHIC_TRUE@@USE_NONCE_TRUE@am__append_50 = plugins/nonce/libstrongswan-nonce.la -@USE_HMAC_TRUE@am__append_51 = plugins/hmac -@MONOLITHIC_TRUE@@USE_HMAC_TRUE@am__append_52 = plugins/hmac/libstrongswan-hmac.la -@USE_CMAC_TRUE@am__append_53 = plugins/cmac -@MONOLITHIC_TRUE@@USE_CMAC_TRUE@am__append_54 = plugins/cmac/libstrongswan-cmac.la -@USE_XCBC_TRUE@am__append_55 = plugins/xcbc -@MONOLITHIC_TRUE@@USE_XCBC_TRUE@am__append_56 = plugins/xcbc/libstrongswan-xcbc.la -@USE_X509_TRUE@am__append_57 = plugins/x509 -@MONOLITHIC_TRUE@@USE_X509_TRUE@am__append_58 = plugins/x509/libstrongswan-x509.la -@USE_REVOCATION_TRUE@am__append_59 = plugins/revocation -@MONOLITHIC_TRUE@@USE_REVOCATION_TRUE@am__append_60 = plugins/revocation/libstrongswan-revocation.la -@USE_CONSTRAINTS_TRUE@am__append_61 = plugins/constraints -@MONOLITHIC_TRUE@@USE_CONSTRAINTS_TRUE@am__append_62 = plugins/constraints/libstrongswan-constraints.la -@USE_ACERT_TRUE@am__append_63 = plugins/acert -@MONOLITHIC_TRUE@@USE_ACERT_TRUE@am__append_64 = plugins/acert/libstrongswan-acert.la -@USE_PUBKEY_TRUE@am__append_65 = plugins/pubkey -@MONOLITHIC_TRUE@@USE_PUBKEY_TRUE@am__append_66 = plugins/pubkey/libstrongswan-pubkey.la -@USE_PKCS1_TRUE@am__append_67 = plugins/pkcs1 -@MONOLITHIC_TRUE@@USE_PKCS1_TRUE@am__append_68 = plugins/pkcs1/libstrongswan-pkcs1.la -@USE_PKCS7_TRUE@am__append_69 = plugins/pkcs7 -@MONOLITHIC_TRUE@@USE_PKCS7_TRUE@am__append_70 = plugins/pkcs7/libstrongswan-pkcs7.la -@USE_PKCS8_TRUE@am__append_71 = plugins/pkcs8 -@MONOLITHIC_TRUE@@USE_PKCS8_TRUE@am__append_72 = plugins/pkcs8/libstrongswan-pkcs8.la -@USE_PKCS12_TRUE@am__append_73 = plugins/pkcs12 -@MONOLITHIC_TRUE@@USE_PKCS12_TRUE@am__append_74 = plugins/pkcs12/libstrongswan-pkcs12.la -@USE_PGP_TRUE@am__append_75 = plugins/pgp -@MONOLITHIC_TRUE@@USE_PGP_TRUE@am__append_76 = plugins/pgp/libstrongswan-pgp.la -@USE_DNSKEY_TRUE@am__append_77 = plugins/dnskey -@MONOLITHIC_TRUE@@USE_DNSKEY_TRUE@am__append_78 = plugins/dnskey/libstrongswan-dnskey.la -@USE_SSHKEY_TRUE@am__append_79 = plugins/sshkey -@MONOLITHIC_TRUE@@USE_SSHKEY_TRUE@am__append_80 = plugins/sshkey/libstrongswan-sshkey.la -@USE_PEM_TRUE@am__append_81 = plugins/pem -@MONOLITHIC_TRUE@@USE_PEM_TRUE@am__append_82 = plugins/pem/libstrongswan-pem.la -@USE_CURL_TRUE@am__append_83 = plugins/curl -@MONOLITHIC_TRUE@@USE_CURL_TRUE@am__append_84 = plugins/curl/libstrongswan-curl.la -@USE_FILES_TRUE@am__append_85 = plugins/files -@MONOLITHIC_TRUE@@USE_FILES_TRUE@am__append_86 = plugins/files/libstrongswan-files.la -@USE_WINHTTP_TRUE@am__append_87 = plugins/winhttp -@MONOLITHIC_TRUE@@USE_WINHTTP_TRUE@am__append_88 = plugins/winhttp/libstrongswan-winhttp.la -@USE_UNBOUND_TRUE@am__append_89 = plugins/unbound -@MONOLITHIC_TRUE@@USE_UNBOUND_TRUE@am__append_90 = plugins/unbound/libstrongswan-unbound.la -@USE_SOUP_TRUE@am__append_91 = plugins/soup -@MONOLITHIC_TRUE@@USE_SOUP_TRUE@am__append_92 = plugins/soup/libstrongswan-soup.la -@USE_LDAP_TRUE@am__append_93 = plugins/ldap -@MONOLITHIC_TRUE@@USE_LDAP_TRUE@am__append_94 = plugins/ldap/libstrongswan-ldap.la -@USE_MYSQL_TRUE@am__append_95 = plugins/mysql -@MONOLITHIC_TRUE@@USE_MYSQL_TRUE@am__append_96 = plugins/mysql/libstrongswan-mysql.la -@USE_SQLITE_TRUE@am__append_97 = plugins/sqlite -@MONOLITHIC_TRUE@@USE_SQLITE_TRUE@am__append_98 = plugins/sqlite/libstrongswan-sqlite.la -@USE_PADLOCK_TRUE@am__append_99 = plugins/padlock -@MONOLITHIC_TRUE@@USE_PADLOCK_TRUE@am__append_100 = plugins/padlock/libstrongswan-padlock.la -@USE_OPENSSL_TRUE@am__append_101 = plugins/openssl -@MONOLITHIC_TRUE@@USE_OPENSSL_TRUE@am__append_102 = plugins/openssl/libstrongswan-openssl.la -@USE_GCRYPT_TRUE@am__append_103 = plugins/gcrypt -@MONOLITHIC_TRUE@@USE_GCRYPT_TRUE@am__append_104 = plugins/gcrypt/libstrongswan-gcrypt.la -@USE_FIPS_PRF_TRUE@am__append_105 = plugins/fips_prf -@MONOLITHIC_TRUE@@USE_FIPS_PRF_TRUE@am__append_106 = plugins/fips_prf/libstrongswan-fips-prf.la -@USE_AGENT_TRUE@am__append_107 = plugins/agent -@MONOLITHIC_TRUE@@USE_AGENT_TRUE@am__append_108 = plugins/agent/libstrongswan-agent.la -@USE_KEYCHAIN_TRUE@am__append_109 = plugins/keychain -@MONOLITHIC_TRUE@@USE_KEYCHAIN_TRUE@am__append_110 = plugins/keychain/libstrongswan-keychain.la -@USE_PKCS11_TRUE@am__append_111 = plugins/pkcs11 -@MONOLITHIC_TRUE@@USE_PKCS11_TRUE@am__append_112 = plugins/pkcs11/libstrongswan-pkcs11.la -@USE_CHAPOLY_TRUE@am__append_113 = plugins/chapoly -@MONOLITHIC_TRUE@@USE_CHAPOLY_TRUE@am__append_114 = plugins/chapoly/libstrongswan-chapoly.la -@USE_CTR_TRUE@am__append_115 = plugins/ctr -@MONOLITHIC_TRUE@@USE_CTR_TRUE@am__append_116 = plugins/ctr/libstrongswan-ctr.la -@USE_CCM_TRUE@am__append_117 = plugins/ccm -@MONOLITHIC_TRUE@@USE_CCM_TRUE@am__append_118 = plugins/ccm/libstrongswan-ccm.la -@USE_GCM_TRUE@am__append_119 = plugins/gcm -@MONOLITHIC_TRUE@@USE_GCM_TRUE@am__append_120 = plugins/gcm/libstrongswan-gcm.la -@USE_MGF1_TRUE@am__append_121 = plugins/mgf1 -@MONOLITHIC_TRUE@@USE_MGF1_TRUE@am__append_122 = plugins/mgf1/libstrongswan-mgf1.la -@USE_NTRU_TRUE@am__append_123 = plugins/ntru -@MONOLITHIC_TRUE@@USE_NTRU_TRUE@am__append_124 = plugins/ntru/libstrongswan-ntru.la -@USE_BLISS_TRUE@am__append_125 = plugins/bliss -@MONOLITHIC_TRUE@@USE_BLISS_TRUE@am__append_126 = plugins/bliss/libstrongswan-bliss.la -@USE_NEWHOPE_TRUE@am__append_127 = plugins/newhope -@MONOLITHIC_TRUE@@USE_NEWHOPE_TRUE@am__append_128 = plugins/newhope/libstrongswan-newhope.la -@USE_TEST_VECTORS_TRUE@am__append_129 = plugins/test_vectors -@MONOLITHIC_TRUE@@USE_TEST_VECTORS_TRUE@am__append_130 = plugins/test_vectors/libstrongswan-test-vectors.la -@USE_LIBNTTFFT_TRUE@am__append_131 = math/libnttfft/tests -@USE_BLISS_TRUE@am__append_132 = plugins/bliss/tests -@USE_NEWHOPE_TRUE@am__append_133 = plugins/newhope/tests +@USE_AF_ALG_TRUE@am__append_20 = plugins/af_alg +@MONOLITHIC_TRUE@@USE_AF_ALG_TRUE@am__append_21 = plugins/af_alg/libstrongswan-af-alg.la +@USE_AES_TRUE@am__append_22 = plugins/aes +@MONOLITHIC_TRUE@@USE_AES_TRUE@am__append_23 = plugins/aes/libstrongswan-aes.la +@USE_DES_TRUE@am__append_24 = plugins/des +@MONOLITHIC_TRUE@@USE_DES_TRUE@am__append_25 = plugins/des/libstrongswan-des.la +@USE_BLOWFISH_TRUE@am__append_26 = plugins/blowfish +@MONOLITHIC_TRUE@@USE_BLOWFISH_TRUE@am__append_27 = plugins/blowfish/libstrongswan-blowfish.la +@USE_RC2_TRUE@am__append_28 = plugins/rc2 +@MONOLITHIC_TRUE@@USE_RC2_TRUE@am__append_29 = plugins/rc2/libstrongswan-rc2.la +@USE_MD4_TRUE@am__append_30 = plugins/md4 +@MONOLITHIC_TRUE@@USE_MD4_TRUE@am__append_31 = plugins/md4/libstrongswan-md4.la +@USE_MD5_TRUE@am__append_32 = plugins/md5 +@MONOLITHIC_TRUE@@USE_MD5_TRUE@am__append_33 = plugins/md5/libstrongswan-md5.la +@USE_SHA1_TRUE@am__append_34 = plugins/sha1 +@MONOLITHIC_TRUE@@USE_SHA1_TRUE@am__append_35 = plugins/sha1/libstrongswan-sha1.la +@USE_SHA2_TRUE@am__append_36 = plugins/sha2 +@MONOLITHIC_TRUE@@USE_SHA2_TRUE@am__append_37 = plugins/sha2/libstrongswan-sha2.la +@USE_SHA3_TRUE@am__append_38 = plugins/sha3 +@MONOLITHIC_TRUE@@USE_SHA3_TRUE@am__append_39 = plugins/sha3/libstrongswan-sha3.la +@USE_GMP_TRUE@am__append_40 = plugins/gmp +@MONOLITHIC_TRUE@@USE_GMP_TRUE@am__append_41 = plugins/gmp/libstrongswan-gmp.la +@USE_CURVE25519_TRUE@am__append_42 = plugins/curve25519 +@MONOLITHIC_TRUE@@USE_CURVE25519_TRUE@am__append_43 = plugins/curve25519/libstrongswan-curve25519.la +@USE_RDRAND_TRUE@am__append_44 = plugins/rdrand +@MONOLITHIC_TRUE@@USE_RDRAND_TRUE@am__append_45 = plugins/rdrand/libstrongswan-rdrand.la +@USE_AESNI_TRUE@am__append_46 = plugins/aesni +@MONOLITHIC_TRUE@@USE_AESNI_TRUE@am__append_47 = plugins/aesni/libstrongswan-aesni.la +@USE_RANDOM_TRUE@am__append_48 = plugins/random +@MONOLITHIC_TRUE@@USE_RANDOM_TRUE@am__append_49 = plugins/random/libstrongswan-random.la +@USE_NONCE_TRUE@am__append_50 = plugins/nonce +@MONOLITHIC_TRUE@@USE_NONCE_TRUE@am__append_51 = plugins/nonce/libstrongswan-nonce.la +@USE_HMAC_TRUE@am__append_52 = plugins/hmac +@MONOLITHIC_TRUE@@USE_HMAC_TRUE@am__append_53 = plugins/hmac/libstrongswan-hmac.la +@USE_CMAC_TRUE@am__append_54 = plugins/cmac +@MONOLITHIC_TRUE@@USE_CMAC_TRUE@am__append_55 = plugins/cmac/libstrongswan-cmac.la +@USE_XCBC_TRUE@am__append_56 = plugins/xcbc +@MONOLITHIC_TRUE@@USE_XCBC_TRUE@am__append_57 = plugins/xcbc/libstrongswan-xcbc.la +@USE_X509_TRUE@am__append_58 = plugins/x509 +@MONOLITHIC_TRUE@@USE_X509_TRUE@am__append_59 = plugins/x509/libstrongswan-x509.la +@USE_REVOCATION_TRUE@am__append_60 = plugins/revocation +@MONOLITHIC_TRUE@@USE_REVOCATION_TRUE@am__append_61 = plugins/revocation/libstrongswan-revocation.la +@USE_CONSTRAINTS_TRUE@am__append_62 = plugins/constraints +@MONOLITHIC_TRUE@@USE_CONSTRAINTS_TRUE@am__append_63 = plugins/constraints/libstrongswan-constraints.la +@USE_ACERT_TRUE@am__append_64 = plugins/acert +@MONOLITHIC_TRUE@@USE_ACERT_TRUE@am__append_65 = plugins/acert/libstrongswan-acert.la +@USE_PUBKEY_TRUE@am__append_66 = plugins/pubkey +@MONOLITHIC_TRUE@@USE_PUBKEY_TRUE@am__append_67 = plugins/pubkey/libstrongswan-pubkey.la +@USE_PKCS1_TRUE@am__append_68 = plugins/pkcs1 +@MONOLITHIC_TRUE@@USE_PKCS1_TRUE@am__append_69 = plugins/pkcs1/libstrongswan-pkcs1.la +@USE_PKCS7_TRUE@am__append_70 = plugins/pkcs7 +@MONOLITHIC_TRUE@@USE_PKCS7_TRUE@am__append_71 = plugins/pkcs7/libstrongswan-pkcs7.la +@USE_PKCS8_TRUE@am__append_72 = plugins/pkcs8 +@MONOLITHIC_TRUE@@USE_PKCS8_TRUE@am__append_73 = plugins/pkcs8/libstrongswan-pkcs8.la +@USE_PKCS12_TRUE@am__append_74 = plugins/pkcs12 +@MONOLITHIC_TRUE@@USE_PKCS12_TRUE@am__append_75 = plugins/pkcs12/libstrongswan-pkcs12.la +@USE_PGP_TRUE@am__append_76 = plugins/pgp +@MONOLITHIC_TRUE@@USE_PGP_TRUE@am__append_77 = plugins/pgp/libstrongswan-pgp.la +@USE_DNSKEY_TRUE@am__append_78 = plugins/dnskey +@MONOLITHIC_TRUE@@USE_DNSKEY_TRUE@am__append_79 = plugins/dnskey/libstrongswan-dnskey.la +@USE_SSHKEY_TRUE@am__append_80 = plugins/sshkey +@MONOLITHIC_TRUE@@USE_SSHKEY_TRUE@am__append_81 = plugins/sshkey/libstrongswan-sshkey.la +@USE_PEM_TRUE@am__append_82 = plugins/pem +@MONOLITHIC_TRUE@@USE_PEM_TRUE@am__append_83 = plugins/pem/libstrongswan-pem.la +@USE_CURL_TRUE@am__append_84 = plugins/curl +@MONOLITHIC_TRUE@@USE_CURL_TRUE@am__append_85 = plugins/curl/libstrongswan-curl.la +@USE_FILES_TRUE@am__append_86 = plugins/files +@MONOLITHIC_TRUE@@USE_FILES_TRUE@am__append_87 = plugins/files/libstrongswan-files.la +@USE_WINHTTP_TRUE@am__append_88 = plugins/winhttp +@MONOLITHIC_TRUE@@USE_WINHTTP_TRUE@am__append_89 = plugins/winhttp/libstrongswan-winhttp.la +@USE_UNBOUND_TRUE@am__append_90 = plugins/unbound +@MONOLITHIC_TRUE@@USE_UNBOUND_TRUE@am__append_91 = plugins/unbound/libstrongswan-unbound.la +@USE_SOUP_TRUE@am__append_92 = plugins/soup +@MONOLITHIC_TRUE@@USE_SOUP_TRUE@am__append_93 = plugins/soup/libstrongswan-soup.la +@USE_LDAP_TRUE@am__append_94 = plugins/ldap +@MONOLITHIC_TRUE@@USE_LDAP_TRUE@am__append_95 = plugins/ldap/libstrongswan-ldap.la +@USE_MYSQL_TRUE@am__append_96 = plugins/mysql +@MONOLITHIC_TRUE@@USE_MYSQL_TRUE@am__append_97 = plugins/mysql/libstrongswan-mysql.la +@USE_SQLITE_TRUE@am__append_98 = plugins/sqlite +@MONOLITHIC_TRUE@@USE_SQLITE_TRUE@am__append_99 = plugins/sqlite/libstrongswan-sqlite.la +@USE_PADLOCK_TRUE@am__append_100 = plugins/padlock +@MONOLITHIC_TRUE@@USE_PADLOCK_TRUE@am__append_101 = plugins/padlock/libstrongswan-padlock.la +@USE_OPENSSL_TRUE@am__append_102 = plugins/openssl +@MONOLITHIC_TRUE@@USE_OPENSSL_TRUE@am__append_103 = plugins/openssl/libstrongswan-openssl.la +@USE_GCRYPT_TRUE@am__append_104 = plugins/gcrypt +@MONOLITHIC_TRUE@@USE_GCRYPT_TRUE@am__append_105 = plugins/gcrypt/libstrongswan-gcrypt.la +@USE_FIPS_PRF_TRUE@am__append_106 = plugins/fips_prf +@MONOLITHIC_TRUE@@USE_FIPS_PRF_TRUE@am__append_107 = plugins/fips_prf/libstrongswan-fips-prf.la +@USE_AGENT_TRUE@am__append_108 = plugins/agent +@MONOLITHIC_TRUE@@USE_AGENT_TRUE@am__append_109 = plugins/agent/libstrongswan-agent.la +@USE_KEYCHAIN_TRUE@am__append_110 = plugins/keychain +@MONOLITHIC_TRUE@@USE_KEYCHAIN_TRUE@am__append_111 = plugins/keychain/libstrongswan-keychain.la +@USE_PKCS11_TRUE@am__append_112 = plugins/pkcs11 +@MONOLITHIC_TRUE@@USE_PKCS11_TRUE@am__append_113 = plugins/pkcs11/libstrongswan-pkcs11.la +@USE_CHAPOLY_TRUE@am__append_114 = plugins/chapoly +@MONOLITHIC_TRUE@@USE_CHAPOLY_TRUE@am__append_115 = plugins/chapoly/libstrongswan-chapoly.la +@USE_CTR_TRUE@am__append_116 = plugins/ctr +@MONOLITHIC_TRUE@@USE_CTR_TRUE@am__append_117 = plugins/ctr/libstrongswan-ctr.la +@USE_CCM_TRUE@am__append_118 = plugins/ccm +@MONOLITHIC_TRUE@@USE_CCM_TRUE@am__append_119 = plugins/ccm/libstrongswan-ccm.la +@USE_GCM_TRUE@am__append_120 = plugins/gcm +@MONOLITHIC_TRUE@@USE_GCM_TRUE@am__append_121 = plugins/gcm/libstrongswan-gcm.la +@USE_MGF1_TRUE@am__append_122 = plugins/mgf1 +@MONOLITHIC_TRUE@@USE_MGF1_TRUE@am__append_123 = plugins/mgf1/libstrongswan-mgf1.la +@USE_NTRU_TRUE@am__append_124 = plugins/ntru +@MONOLITHIC_TRUE@@USE_NTRU_TRUE@am__append_125 = plugins/ntru/libstrongswan-ntru.la +@USE_BLISS_TRUE@am__append_126 = plugins/bliss +@MONOLITHIC_TRUE@@USE_BLISS_TRUE@am__append_127 = plugins/bliss/libstrongswan-bliss.la +@USE_NEWHOPE_TRUE@am__append_128 = plugins/newhope +@MONOLITHIC_TRUE@@USE_NEWHOPE_TRUE@am__append_129 = plugins/newhope/libstrongswan-newhope.la +@USE_TEST_VECTORS_TRUE@am__append_130 = plugins/test_vectors +@MONOLITHIC_TRUE@@USE_TEST_VECTORS_TRUE@am__append_131 = plugins/test_vectors/libstrongswan-test-vectors.la +@USE_LIBNTTFFT_TRUE@am__append_132 = math/libnttfft/tests +@USE_BLISS_TRUE@am__append_133 = plugins/bliss/tests +@USE_NEWHOPE_TRUE@am__append_134 = plugins/newhope/tests subdir = src/libstrongswan ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/config/libtool.m4 \ @@ -304,26 +305,26 @@ libstrongswan_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) $(am__append_20) \ - $(am__append_22) $(am__append_24) $(am__append_26) \ - $(am__append_28) $(am__append_30) $(am__append_32) \ - $(am__append_34) $(am__append_36) $(am__append_38) \ - $(am__append_40) $(am__append_42) $(am__append_44) \ - $(am__append_46) $(am__append_48) $(am__append_50) \ - $(am__append_52) $(am__append_54) $(am__append_56) \ - $(am__append_58) $(am__append_60) $(am__append_62) \ - $(am__append_64) $(am__append_66) $(am__append_68) \ - $(am__append_70) $(am__append_72) $(am__append_74) \ - $(am__append_76) $(am__append_78) $(am__append_80) \ - $(am__append_82) $(am__append_84) $(am__append_86) \ - $(am__append_88) $(am__append_90) $(am__append_92) \ - $(am__append_94) $(am__append_96) $(am__append_98) \ - $(am__append_100) $(am__append_102) $(am__append_104) \ - $(am__append_106) $(am__append_108) $(am__append_110) \ - $(am__append_112) $(am__append_114) $(am__append_116) \ - $(am__append_118) $(am__append_120) $(am__append_122) \ - $(am__append_124) $(am__append_126) $(am__append_128) \ - $(am__append_130) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) $(am__append_21) \ + $(am__append_23) $(am__append_25) $(am__append_27) \ + $(am__append_29) $(am__append_31) $(am__append_33) \ + $(am__append_35) $(am__append_37) $(am__append_39) \ + $(am__append_41) $(am__append_43) $(am__append_45) \ + $(am__append_47) $(am__append_49) $(am__append_51) \ + $(am__append_53) $(am__append_55) $(am__append_57) \ + $(am__append_59) $(am__append_61) $(am__append_63) \ + $(am__append_65) $(am__append_67) $(am__append_69) \ + $(am__append_71) $(am__append_73) $(am__append_75) \ + $(am__append_77) $(am__append_79) $(am__append_81) \ + $(am__append_83) $(am__append_85) $(am__append_87) \ + $(am__append_89) $(am__append_91) $(am__append_93) \ + $(am__append_95) $(am__append_97) $(am__append_99) \ + $(am__append_101) $(am__append_103) $(am__append_105) \ + $(am__append_107) $(am__append_109) $(am__append_111) \ + $(am__append_113) $(am__append_115) $(am__append_117) \ + $(am__append_119) $(am__append_121) $(am__append_123) \ + $(am__append_125) $(am__append_127) $(am__append_129) \ + $(am__append_131) am__libstrongswan_la_SOURCES_DIST = library.c asn1/asn1.c \ asn1/asn1_parser.c asn1/oid.c bio/bio_reader.c \ bio/bio_writer.c collections/blocking_queue.c \ @@ -830,6 +831,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -852,6 +854,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ @@ -1037,26 +1040,26 @@ settings/settings_types.h libstrongswan_la_LIBADD = $(DLLIB) $(ATOMICLIB) $(BTLIB) $(SOCKLIB) \ $(RTLIB) $(BFDLIB) $(UNWINDLIB) $(am__append_2) \ $(am__append_4) $(am__append_5) $(am__append_13) \ - $(am__append_15) $(am__append_17) $(am__append_20) \ - $(am__append_22) $(am__append_24) $(am__append_26) \ - $(am__append_28) $(am__append_30) $(am__append_32) \ - $(am__append_34) $(am__append_36) $(am__append_38) \ - $(am__append_40) $(am__append_42) $(am__append_44) \ - $(am__append_46) $(am__append_48) $(am__append_50) \ - $(am__append_52) $(am__append_54) $(am__append_56) \ - $(am__append_58) $(am__append_60) $(am__append_62) \ - $(am__append_64) $(am__append_66) $(am__append_68) \ - $(am__append_70) $(am__append_72) $(am__append_74) \ - $(am__append_76) $(am__append_78) $(am__append_80) \ - $(am__append_82) $(am__append_84) $(am__append_86) \ - $(am__append_88) $(am__append_90) $(am__append_92) \ - $(am__append_94) $(am__append_96) $(am__append_98) \ - $(am__append_100) $(am__append_102) $(am__append_104) \ - $(am__append_106) $(am__append_108) $(am__append_110) \ - $(am__append_112) $(am__append_114) $(am__append_116) \ - $(am__append_118) $(am__append_120) $(am__append_122) \ - $(am__append_124) $(am__append_126) $(am__append_128) \ - $(am__append_130) + $(am__append_15) $(am__append_17) $(am__append_21) \ + $(am__append_23) $(am__append_25) $(am__append_27) \ + $(am__append_29) $(am__append_31) $(am__append_33) \ + $(am__append_35) $(am__append_37) $(am__append_39) \ + $(am__append_41) $(am__append_43) $(am__append_45) \ + $(am__append_47) $(am__append_49) $(am__append_51) \ + $(am__append_53) $(am__append_55) $(am__append_57) \ + $(am__append_59) $(am__append_61) $(am__append_63) \ + $(am__append_65) $(am__append_67) $(am__append_69) \ + $(am__append_71) $(am__append_73) $(am__append_75) \ + $(am__append_77) $(am__append_79) $(am__append_81) \ + $(am__append_83) $(am__append_85) $(am__append_87) \ + $(am__append_89) $(am__append_91) $(am__append_93) \ + $(am__append_95) $(am__append_97) $(am__append_99) \ + $(am__append_101) $(am__append_103) $(am__append_105) \ + $(am__append_107) $(am__append_109) $(am__append_111) \ + $(am__append_113) $(am__append_115) $(am__append_117) \ + $(am__append_119) $(am__append_121) $(am__append_123) \ + $(am__append_125) $(am__append_127) $(am__append_129) \ + $(am__append_131) AM_CPPFLAGS = -I$(top_srcdir)/src/libstrongswan \ -DIPSEC_DIR=\"${ipsecdir}\" -DIPSEC_LIB_DIR=\"${ipseclibdir}\" \ -DPLUGINDIR=\"${plugindir}\" \ @@ -1072,83 +1075,83 @@ AM_YFLAGS = -v -d EXTRA_DIST = \ asn1/oid.txt asn1/oid.pl \ crypto/proposal/proposal_keywords_static.txt \ +plugins/plugin_constructors.py \ Android.mk -BUILT_SOURCES = \ -$(srcdir)/asn1/oid.c $(srcdir)/asn1/oid.h \ -$(srcdir)/crypto/proposal/proposal_keywords_static.c \ -settings/settings_parser.h - +BUILT_SOURCES = $(srcdir)/asn1/oid.c $(srcdir)/asn1/oid.h \ + $(srcdir)/crypto/proposal/proposal_keywords_static.c \ + settings/settings_parser.h $(am__append_18) MAINTAINERCLEANFILES = \ $(srcdir)/asn1/oid.c $(srcdir)/asn1/oid.h \ $(srcdir)/crypto/proposal/proposal_keywords_static.c +@STATIC_PLUGIN_CONSTRUCTORS_TRUE@CLEANFILES = $(srcdir)/plugin_constructors.c # build unit tests ################## -@MONOLITHIC_FALSE@SUBDIRS = . $(am__append_18) $(am__append_19) \ -@MONOLITHIC_FALSE@ $(am__append_21) $(am__append_23) \ -@MONOLITHIC_FALSE@ $(am__append_25) $(am__append_27) \ -@MONOLITHIC_FALSE@ $(am__append_29) $(am__append_31) \ -@MONOLITHIC_FALSE@ $(am__append_33) $(am__append_35) \ -@MONOLITHIC_FALSE@ $(am__append_37) $(am__append_39) \ -@MONOLITHIC_FALSE@ $(am__append_41) $(am__append_43) \ -@MONOLITHIC_FALSE@ $(am__append_45) $(am__append_47) \ -@MONOLITHIC_FALSE@ $(am__append_49) $(am__append_51) \ -@MONOLITHIC_FALSE@ $(am__append_53) $(am__append_55) \ -@MONOLITHIC_FALSE@ $(am__append_57) $(am__append_59) \ -@MONOLITHIC_FALSE@ $(am__append_61) $(am__append_63) \ -@MONOLITHIC_FALSE@ $(am__append_65) $(am__append_67) \ -@MONOLITHIC_FALSE@ $(am__append_69) $(am__append_71) \ -@MONOLITHIC_FALSE@ $(am__append_73) $(am__append_75) \ -@MONOLITHIC_FALSE@ $(am__append_77) $(am__append_79) \ -@MONOLITHIC_FALSE@ $(am__append_81) $(am__append_83) \ -@MONOLITHIC_FALSE@ $(am__append_85) $(am__append_87) \ -@MONOLITHIC_FALSE@ $(am__append_89) $(am__append_91) \ -@MONOLITHIC_FALSE@ $(am__append_93) $(am__append_95) \ -@MONOLITHIC_FALSE@ $(am__append_97) $(am__append_99) \ -@MONOLITHIC_FALSE@ $(am__append_101) $(am__append_103) \ -@MONOLITHIC_FALSE@ $(am__append_105) $(am__append_107) \ -@MONOLITHIC_FALSE@ $(am__append_109) $(am__append_111) \ -@MONOLITHIC_FALSE@ $(am__append_113) $(am__append_115) \ -@MONOLITHIC_FALSE@ $(am__append_117) $(am__append_119) \ -@MONOLITHIC_FALSE@ $(am__append_121) $(am__append_123) \ -@MONOLITHIC_FALSE@ $(am__append_125) $(am__append_127) \ -@MONOLITHIC_FALSE@ $(am__append_129) tests $(am__append_131) \ -@MONOLITHIC_FALSE@ $(am__append_132) $(am__append_133) +@MONOLITHIC_FALSE@SUBDIRS = . $(am__append_19) $(am__append_20) \ +@MONOLITHIC_FALSE@ $(am__append_22) $(am__append_24) \ +@MONOLITHIC_FALSE@ $(am__append_26) $(am__append_28) \ +@MONOLITHIC_FALSE@ $(am__append_30) $(am__append_32) \ +@MONOLITHIC_FALSE@ $(am__append_34) $(am__append_36) \ +@MONOLITHIC_FALSE@ $(am__append_38) $(am__append_40) \ +@MONOLITHIC_FALSE@ $(am__append_42) $(am__append_44) \ +@MONOLITHIC_FALSE@ $(am__append_46) $(am__append_48) \ +@MONOLITHIC_FALSE@ $(am__append_50) $(am__append_52) \ +@MONOLITHIC_FALSE@ $(am__append_54) $(am__append_56) \ +@MONOLITHIC_FALSE@ $(am__append_58) $(am__append_60) \ +@MONOLITHIC_FALSE@ $(am__append_62) $(am__append_64) \ +@MONOLITHIC_FALSE@ $(am__append_66) $(am__append_68) \ +@MONOLITHIC_FALSE@ $(am__append_70) $(am__append_72) \ +@MONOLITHIC_FALSE@ $(am__append_74) $(am__append_76) \ +@MONOLITHIC_FALSE@ $(am__append_78) $(am__append_80) \ +@MONOLITHIC_FALSE@ $(am__append_82) $(am__append_84) \ +@MONOLITHIC_FALSE@ $(am__append_86) $(am__append_88) \ +@MONOLITHIC_FALSE@ $(am__append_90) $(am__append_92) \ +@MONOLITHIC_FALSE@ $(am__append_94) $(am__append_96) \ +@MONOLITHIC_FALSE@ $(am__append_98) $(am__append_100) \ +@MONOLITHIC_FALSE@ $(am__append_102) $(am__append_104) \ +@MONOLITHIC_FALSE@ $(am__append_106) $(am__append_108) \ +@MONOLITHIC_FALSE@ $(am__append_110) $(am__append_112) \ +@MONOLITHIC_FALSE@ $(am__append_114) $(am__append_116) \ +@MONOLITHIC_FALSE@ $(am__append_118) $(am__append_120) \ +@MONOLITHIC_FALSE@ $(am__append_122) $(am__append_124) \ +@MONOLITHIC_FALSE@ $(am__append_126) $(am__append_128) \ +@MONOLITHIC_FALSE@ $(am__append_130) tests $(am__append_132) \ +@MONOLITHIC_FALSE@ $(am__append_133) $(am__append_134) # build unit tests ################## -@MONOLITHIC_TRUE@SUBDIRS = $(am__append_18) $(am__append_19) \ -@MONOLITHIC_TRUE@ $(am__append_21) $(am__append_23) \ -@MONOLITHIC_TRUE@ $(am__append_25) $(am__append_27) \ -@MONOLITHIC_TRUE@ $(am__append_29) $(am__append_31) \ -@MONOLITHIC_TRUE@ $(am__append_33) $(am__append_35) \ -@MONOLITHIC_TRUE@ $(am__append_37) $(am__append_39) \ -@MONOLITHIC_TRUE@ $(am__append_41) $(am__append_43) \ -@MONOLITHIC_TRUE@ $(am__append_45) $(am__append_47) \ -@MONOLITHIC_TRUE@ $(am__append_49) $(am__append_51) \ -@MONOLITHIC_TRUE@ $(am__append_53) $(am__append_55) \ -@MONOLITHIC_TRUE@ $(am__append_57) $(am__append_59) \ -@MONOLITHIC_TRUE@ $(am__append_61) $(am__append_63) \ -@MONOLITHIC_TRUE@ $(am__append_65) $(am__append_67) \ -@MONOLITHIC_TRUE@ $(am__append_69) $(am__append_71) \ -@MONOLITHIC_TRUE@ $(am__append_73) $(am__append_75) \ -@MONOLITHIC_TRUE@ $(am__append_77) $(am__append_79) \ -@MONOLITHIC_TRUE@ $(am__append_81) $(am__append_83) \ -@MONOLITHIC_TRUE@ $(am__append_85) $(am__append_87) \ -@MONOLITHIC_TRUE@ $(am__append_89) $(am__append_91) \ -@MONOLITHIC_TRUE@ $(am__append_93) $(am__append_95) \ -@MONOLITHIC_TRUE@ $(am__append_97) $(am__append_99) \ -@MONOLITHIC_TRUE@ $(am__append_101) $(am__append_103) \ -@MONOLITHIC_TRUE@ $(am__append_105) $(am__append_107) \ -@MONOLITHIC_TRUE@ $(am__append_109) $(am__append_111) \ -@MONOLITHIC_TRUE@ $(am__append_113) $(am__append_115) \ -@MONOLITHIC_TRUE@ $(am__append_117) $(am__append_119) \ -@MONOLITHIC_TRUE@ $(am__append_121) $(am__append_123) \ -@MONOLITHIC_TRUE@ $(am__append_125) $(am__append_127) \ -@MONOLITHIC_TRUE@ $(am__append_129) . tests $(am__append_131) \ -@MONOLITHIC_TRUE@ $(am__append_132) $(am__append_133) +@MONOLITHIC_TRUE@SUBDIRS = $(am__append_19) $(am__append_20) \ +@MONOLITHIC_TRUE@ $(am__append_22) $(am__append_24) \ +@MONOLITHIC_TRUE@ $(am__append_26) $(am__append_28) \ +@MONOLITHIC_TRUE@ $(am__append_30) $(am__append_32) \ +@MONOLITHIC_TRUE@ $(am__append_34) $(am__append_36) \ +@MONOLITHIC_TRUE@ $(am__append_38) $(am__append_40) \ +@MONOLITHIC_TRUE@ $(am__append_42) $(am__append_44) \ +@MONOLITHIC_TRUE@ $(am__append_46) $(am__append_48) \ +@MONOLITHIC_TRUE@ $(am__append_50) $(am__append_52) \ +@MONOLITHIC_TRUE@ $(am__append_54) $(am__append_56) \ +@MONOLITHIC_TRUE@ $(am__append_58) $(am__append_60) \ +@MONOLITHIC_TRUE@ $(am__append_62) $(am__append_64) \ +@MONOLITHIC_TRUE@ $(am__append_66) $(am__append_68) \ +@MONOLITHIC_TRUE@ $(am__append_70) $(am__append_72) \ +@MONOLITHIC_TRUE@ $(am__append_74) $(am__append_76) \ +@MONOLITHIC_TRUE@ $(am__append_78) $(am__append_80) \ +@MONOLITHIC_TRUE@ $(am__append_82) $(am__append_84) \ +@MONOLITHIC_TRUE@ $(am__append_86) $(am__append_88) \ +@MONOLITHIC_TRUE@ $(am__append_90) $(am__append_92) \ +@MONOLITHIC_TRUE@ $(am__append_94) $(am__append_96) \ +@MONOLITHIC_TRUE@ $(am__append_98) $(am__append_100) \ +@MONOLITHIC_TRUE@ $(am__append_102) $(am__append_104) \ +@MONOLITHIC_TRUE@ $(am__append_106) $(am__append_108) \ +@MONOLITHIC_TRUE@ $(am__append_110) $(am__append_112) \ +@MONOLITHIC_TRUE@ $(am__append_114) $(am__append_116) \ +@MONOLITHIC_TRUE@ $(am__append_118) $(am__append_120) \ +@MONOLITHIC_TRUE@ $(am__append_122) $(am__append_124) \ +@MONOLITHIC_TRUE@ $(am__append_126) $(am__append_128) \ +@MONOLITHIC_TRUE@ $(am__append_130) . tests $(am__append_132) \ +@MONOLITHIC_TRUE@ $(am__append_133) $(am__append_134) all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-recursive @@ -2184,6 +2187,7 @@ install-strip: mostlyclean-generic: clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) @@ -2382,6 +2386,10 @@ $(srcdir)/crypto/proposal/proposal_keywords_static.c: $(srcdir)/crypto/proposal/ $(GPERF) -N proposal_get_token_static -m 10 -C -G -c -t -D < \ $(srcdir)/crypto/proposal/proposal_keywords_static.txt > $@ +@STATIC_PLUGIN_CONSTRUCTORS_TRUE@$(srcdir)/plugin_constructors.c: $(srcdir)/plugins/plugin_constructors.py +@STATIC_PLUGIN_CONSTRUCTORS_TRUE@ $(AM_V_GEN) \ +@STATIC_PLUGIN_CONSTRUCTORS_TRUE@ $(PYTHON) $(srcdir)/plugins/plugin_constructors.py ${s_plugins} > $@ + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/src/libstrongswan/asn1/asn1.c b/src/libstrongswan/asn1/asn1.c index 5ce840325..8b9dc1c48 100644 --- a/src/libstrongswan/asn1/asn1.c +++ b/src/libstrongswan/asn1/asn1.c @@ -350,13 +350,15 @@ time_t asn1_to_time(const chunk_t *utctime, asn1_t type) int tm_leap_4, tm_leap_100, tm_leap_400, tm_leap; int tz_hour, tz_min, tz_offset; time_t tm_days, tm_secs; - u_char *eot = NULL; + char buf[BUF_LEN], *eot = NULL; - if ((eot = memchr(utctime->ptr, 'Z', utctime->len)) != NULL) + snprintf(buf, sizeof(buf), "%.*s", (int)utctime->len, utctime->ptr); + + if ((eot = strchr(buf, 'Z')) != NULL) { tz_offset = 0; /* Zulu time with a zero time zone offset */ } - else if ((eot = memchr(utctime->ptr, '+', utctime->len)) != NULL) + else if ((eot = strchr(buf, '+')) != NULL) { if (sscanf(eot+1, "%2d%2d", &tz_hour, &tz_min) != 2) { @@ -364,7 +366,7 @@ time_t asn1_to_time(const chunk_t *utctime, asn1_t type) } tz_offset = 3600*tz_hour + 60*tz_min; /* positive time zone offset */ } - else if ((eot = memchr(utctime->ptr, '-', utctime->len)) != NULL) + else if ((eot = strchr(buf, '-')) != NULL) { if (sscanf(eot+1, "%2d%2d", &tz_hour, &tz_min) != 2) { @@ -382,15 +384,15 @@ time_t asn1_to_time(const chunk_t *utctime, asn1_t type) const char* format = (type == ASN1_UTCTIME)? "%2d%2d%2d%2d%2d": "%4d%2d%2d%2d%2d"; - if (sscanf(utctime->ptr, format, &tm_year, &tm_mon, &tm_day, - &tm_hour, &tm_min) != 5) + if (sscanf(buf, format, &tm_year, &tm_mon, &tm_day, + &tm_hour, &tm_min) != 5) { return 0; /* error in [yy]yymmddhhmm time format */ } } /* is there a seconds field? */ - if ((eot - utctime->ptr) == ((type == ASN1_UTCTIME)?12:14)) + if ((eot - buf) == ((type == ASN1_UTCTIME)?12:14)) { if (sscanf(eot-2, "%2d", &tm_sec) != 1) { diff --git a/src/libstrongswan/asn1/asn1_parser.c b/src/libstrongswan/asn1/asn1_parser.c index e7b7a428d..4d5f799b7 100644 --- a/src/libstrongswan/asn1/asn1_parser.c +++ b/src/libstrongswan/asn1/asn1_parser.c @@ -1,8 +1,7 @@ /* * Copyright (C) 2006 Martin Will - * Copyright (C) 2000-2008 Andreas Steffen - * - * Hochschule fuer Technik Rapperswil + * Copyright (C) 2000-2017 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 @@ -76,12 +75,18 @@ struct private_asn1_parser_t { * Current parsing pointer for each level */ chunk_t blobs[ASN1_MAX_LEVEL + 2]; + + /** + * Parsing a CHOICE on the current level ? + */ + bool choice[ASN1_MAX_LEVEL + 2]; + }; METHOD(asn1_parser_t, iterate, bool, private_asn1_parser_t *this, int *objectID, chunk_t *object) { - chunk_t *blob, *blob1; + chunk_t *blob, *blob1, blob_ori; u_char *start_ptr; u_int level; asn1Object_t obj; @@ -97,7 +102,7 @@ METHOD(asn1_parser_t, iterate, bool, return FALSE; } - if (obj.flags & ASN1_END) /* end of loop or option found */ + if (obj.flags & ASN1_END) /* end of loop or choice or option found */ { if (this->loopAddr[obj.level] && this->blobs[obj.level+1].len > 0) { @@ -106,13 +111,42 @@ METHOD(asn1_parser_t, iterate, bool, } else { - this->loopAddr[obj.level] = 0; /* exit loop or option*/ + this->loopAddr[obj.level] = 0; /* exit loop */ + + if (obj.flags & ASN1_CHOICE) /* end of choices */ + { + if (this->choice[obj.level+1]) + { + DBG1(DBG_ASN, "L%d - %s: incorrect choice encoding", + this->level0 + obj.level, obj.name); + this->success = FALSE; + goto end; + } + } + + if (obj.flags & ASN1_CH) /* end of choice */ + { + /* parsed a valid choice */ + this->choice[obj.level] = FALSE; + + /* advance to end of choices */ + do + { + this->line++; + } + while (!((this->objects[this->line].flags & ASN1_END) && + (this->objects[this->line].flags & ASN1_CHOICE) && + (this->objects[this->line].level == obj.level-1))); + this->line--; + } + goto end; } } level = this->level0 + obj.level; blob = this->blobs + obj.level; + blob_ori = *blob; blob1 = blob + 1; start_ptr = blob->ptr; @@ -129,7 +163,6 @@ METHOD(asn1_parser_t, iterate, bool, } /* handle ASN.1 options */ - if ((obj.flags & ASN1_OPT) && (blob->len == 0 || *start_ptr != obj.type)) { @@ -144,7 +177,6 @@ METHOD(asn1_parser_t, iterate, bool, } /* an ASN.1 object must possess at least a tag and length field */ - if (blob->len < 2) { DBG1(DBG_ASN, "L%d - %s: ASN.1 object smaller than 2 octets", @@ -167,8 +199,16 @@ METHOD(asn1_parser_t, iterate, bool, blob->ptr += blob1->len; blob->len -= blob1->len; - /* return raw ASN.1 object without prior type checking */ + /* handle ASN.1 choice without explicit context encoding */ + if ((obj.flags & ASN1_CHOICE) && obj.type == ASN1_EOC) + { + DBG2(DBG_ASN, "L%d - %s:", level, obj.name); + this->choice[obj.level+1] = TRUE; + *blob1 = blob_ori; + goto end; + } + /* return raw ASN.1 object without prior type checking */ if (obj.flags & ASN1_RAW) { DBG2(DBG_ASN, "L%d - %s:", level, obj.name); @@ -209,6 +249,18 @@ METHOD(asn1_parser_t, iterate, bool, } } + /* In case of a "CHOICE" start to scan for exactly one valid choice */ + if (obj.flags & ASN1_CHOICE) + { + if (blob1->len == 0) + { + DBG1(DBG_ASN, "L%d - %s: contains no choice", level, obj.name); + this->success = FALSE; + goto end; + } + this->choice[obj.level+1] = TRUE; + } + if (obj.flags & ASN1_OBJ) { object->ptr = start_ptr; diff --git a/src/libstrongswan/asn1/asn1_parser.h b/src/libstrongswan/asn1/asn1_parser.h index 0edc22c23..2ee1e892f 100644 --- a/src/libstrongswan/asn1/asn1_parser.h +++ b/src/libstrongswan/asn1/asn1_parser.h @@ -1,8 +1,7 @@ /* * Copyright (C) 2006 Martin Will - * Copyright (C) 2000-2008 Andreas Steffen - * - * Hochschule fuer Technik Rapperswil + * Copyright (C) 2000-2017 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 @@ -32,15 +31,17 @@ /** * Definition of ASN.1 flags */ -#define ASN1_NONE 0x00 -#define ASN1_DEF 0x01 -#define ASN1_OPT 0x02 -#define ASN1_LOOP 0x04 -#define ASN1_END 0x08 -#define ASN1_OBJ 0x10 -#define ASN1_BODY 0x20 -#define ASN1_RAW 0x40 -#define ASN1_EXIT 0x80 +#define ASN1_NONE 0x0000 +#define ASN1_DEF 0x0001 +#define ASN1_OPT 0x0002 +#define ASN1_LOOP 0x0004 +#define ASN1_CHOICE 0x0008 +#define ASN1_CH 0x0010 +#define ASN1_END 0x0020 +#define ASN1_OBJ 0x0040 +#define ASN1_BODY 0x0080 +#define ASN1_RAW 0x0100 +#define ASN1_EXIT 0x0200 typedef struct asn1Object_t asn1Object_t; @@ -51,7 +52,7 @@ struct asn1Object_t{ u_int level; const u_char *name; asn1_t type; - u_char flags; + uint16_t flags; }; typedef struct asn1_parser_t asn1_parser_t; diff --git a/src/libstrongswan/collections/array.c b/src/libstrongswan/collections/array.c index 69e7df99e..c3dd6e0e9 100644 --- a/src/libstrongswan/collections/array.c +++ b/src/libstrongswan/collections/array.c @@ -214,9 +214,11 @@ typedef struct { } array_enumerator_t; METHOD(enumerator_t, enumerate, bool, - array_enumerator_t *this, void **out) + array_enumerator_t *this, va_list args) { - void *pos; + void *pos, **out; + + VA_ARGS_VGET(args, out); if (this->idx >= this->array->count) { @@ -250,7 +252,8 @@ enumerator_t* array_create_enumerator(array_t *array) INIT(enumerator, .public = { - .enumerate = (void*)_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate, .destroy = (void*)free, }, .array = array, diff --git a/src/libstrongswan/collections/enumerator.c b/src/libstrongswan/collections/enumerator.c index fa277e7c8..52c9e1cd5 100644 --- a/src/libstrongswan/collections/enumerator.c +++ b/src/libstrongswan/collections/enumerator.c @@ -1,7 +1,7 @@ /* - * Copyright (C) 2008-2013 Tobias Brunner + * Copyright (C) 2008-2017 Tobias Brunner * Copyright (C) 2007 Martin Willi - * Hochschule fuer Technik Rapperswil + * 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 @@ -31,22 +31,43 @@ #include <utils/debug.h> -/** - * Implementation of enumerator_create_empty().enumerate +/* + * Described in header. */ -static bool enumerate_empty(enumerator_t *enumerator, ...) +bool enumerator_enumerate_default(enumerator_t *enumerator, ...) +{ + va_list args; + bool result; + + if (!enumerator->venumerate) + { + DBG1(DBG_LIB, "!!! ENUMERATE DEFAULT: venumerate() missing !!!"); + return FALSE; + } + va_start(args, enumerator); + result = enumerator->venumerate(enumerator, args); + va_end(args); + return result; +} + +METHOD(enumerator_t, enumerate_empty, bool, + enumerator_t *enumerator, va_list args) { return FALSE; } -/** - * See header +/* + * Described in header */ enumerator_t* enumerator_create_empty() { - enumerator_t *this = malloc_thing(enumerator_t); - this->enumerate = enumerate_empty; - this->destroy = (void*)free; + enumerator_t *this; + + INIT(this, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_empty, + .destroy = (void*)free, + ); return this; } @@ -64,32 +85,31 @@ typedef struct { char *full_end; } dir_enum_t; -/** - * Implementation of enumerator_create_directory().destroy - */ -static void destroy_dir_enum(dir_enum_t *this) +METHOD(enumerator_t, destroy_dir_enum, void, + dir_enum_t *this) { closedir(this->dir); free(this); } -/** - * Implementation of enumerator_create_directory().enumerate - */ -static bool enumerate_dir_enum(dir_enum_t *this, char **relative, - char **absolute, struct stat *st) +METHOD(enumerator_t, enumerate_dir_enum, bool, + dir_enum_t *this, va_list args) { struct dirent *entry = readdir(this->dir); + struct stat *st; size_t remaining; + char **relative, **absolute; int len; + VA_ARGS_VGET(args, relative, absolute, st); + if (!entry) { return FALSE; } if (streq(entry->d_name, ".") || streq(entry->d_name, "..")) { - return enumerate_dir_enum(this, relative, absolute, st); + return this->public.enumerate(&this->public, relative, absolute, st); } if (relative) { @@ -122,15 +142,21 @@ static bool enumerate_dir_enum(dir_enum_t *this, char **relative, return TRUE; } -/** - * See header +/* + * Described in header */ enumerator_t* enumerator_create_directory(const char *path) { + dir_enum_t *this; int len; - dir_enum_t *this = malloc_thing(dir_enum_t); - this->public.enumerate = (void*)enumerate_dir_enum; - this->public.destroy = (void*)destroy_dir_enum; + + INIT(this, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_dir_enum, + .destroy = _destroy_dir_enum, + }, + ); if (*path == '\0') { @@ -152,9 +178,10 @@ enumerator_t* enumerator_create_directory(const char *path) this->full_end = &this->full[len]; this->dir = opendir(path); - if (this->dir == NULL) + if (!this->dir) { - DBG1(DBG_LIB, "opening directory '%s' failed: %s", path, strerror(errno)); + DBG1(DBG_LIB, "opening directory '%s' failed: %s", path, + strerror(errno)); free(this); return NULL; } @@ -177,21 +204,21 @@ typedef struct { char full[PATH_MAX]; } glob_enum_t; -/** - * Implementation of enumerator_create_glob().destroy - */ -static void destroy_glob_enum(glob_enum_t *this) +METHOD(enumerator_t, destroy_glob_enum, void, + glob_enum_t *this) { globfree(&this->glob); free(this); } -/** - * Implementation of enumerator_create_glob().enumerate - */ -static bool enumerate_glob_enum(glob_enum_t *this, char **file, struct stat *st) +METHOD(enumerator_t, enumerate_glob_enum, bool, + glob_enum_t *this, va_list args) { + struct stat *st; char *match; + char **file; + + VA_ARGS_VGET(args, file, st); if (this->pos >= this->glob.gl_pathc) { @@ -202,20 +229,17 @@ static bool enumerate_glob_enum(glob_enum_t *this, char **file, struct stat *st) { *file = match; } - if (st) + if (st && stat(match, st)) { - if (stat(match, st)) - { - DBG1(DBG_LIB, "stat() on '%s' failed: %s", match, - strerror(errno)); - return FALSE; - } + DBG1(DBG_LIB, "stat() on '%s' failed: %s", match, + strerror(errno)); + return FALSE; } return TRUE; } -/** - * See header +/* + * Described in header */ enumerator_t* enumerator_create_glob(const char *pattern) { @@ -229,8 +253,9 @@ enumerator_t* enumerator_create_glob(const char *pattern) INIT(this, .public = { - .enumerate = (void*)enumerate_glob_enum, - .destroy = (void*)destroy_glob_enum, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_glob_enum, + .destroy = _destroy_glob_enum, }, ); @@ -272,24 +297,22 @@ typedef struct { const char *trim; } token_enum_t; -/** - * Implementation of enumerator_create_token().destroy - */ -static void destroy_token_enum(token_enum_t *this) +METHOD(enumerator_t, destroy_token_enum, void, + token_enum_t *this) { free(this->string); free(this); } -/** - * Implementation of enumerator_create_token().enumerate - */ -static bool enumerate_token_enum(token_enum_t *this, char **token) +METHOD(enumerator_t, enumerate_token_enum, bool, + token_enum_t *this, va_list args) { const char *sep, *trim; - char *pos = NULL, *tmp; + char *pos = NULL, *tmp, **token; bool last = FALSE; + VA_ARGS_VGET(args, token); + /* trim leading characters/separators */ while (*this->pos) { @@ -390,52 +413,48 @@ static bool enumerate_token_enum(token_enum_t *this, char **token) return FALSE; } -/** - * See header +/* + * Described in header */ enumerator_t* enumerator_create_token(const char *string, const char *sep, const char *trim) { - token_enum_t *enumerator = malloc_thing(token_enum_t); + token_enum_t *this; - enumerator->public.enumerate = (void*)enumerate_token_enum; - enumerator->public.destroy = (void*)destroy_token_enum; - enumerator->string = strdup(string); - enumerator->pos = enumerator->string; - enumerator->sep = sep; - enumerator->trim = trim; + INIT(this, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_token_enum, + .destroy = _destroy_token_enum, + }, + .string = strdup(string), + .sep = sep, + .trim = trim, + ); + this->pos = this->string; - return &enumerator->public; + return &this->public; } /** - * enumerator for nested enumerations + * Enumerator for nested enumerations */ typedef struct { - /* implements enumerator_t */ enumerator_t public; - /* outer enumerator */ enumerator_t *outer; - /* inner enumerator */ enumerator_t *inner; - /* constructor for inner enumerator */ enumerator_t *(*create_inner)(void *outer, void *data); - /* data to pass to constructor above */ void *data; - /* destructor for data */ - void (*destroy_data)(void *data); + void (*destructor)(void *data); } nested_enumerator_t; -/** - * Implementation of enumerator_create_nested().enumerate() - */ -static bool enumerate_nested(nested_enumerator_t *this, void *v1, void *v2, - void *v3, void *v4, void *v5) +METHOD(enumerator_t, enumerate_nested, bool, + nested_enumerator_t *this, va_list args) { while (TRUE) { - while (this->inner == NULL) + while (!this->inner) { void *outer; @@ -444,8 +463,13 @@ static bool enumerate_nested(nested_enumerator_t *this, void *v1, void *v2, return FALSE; } this->inner = this->create_inner(outer, this->data); + if (this->inner && !this->inner->venumerate) + { + DBG1(DBG_LIB, "!!! ENUMERATE NESTED: venumerate() missing !!!"); + return FALSE; + } } - if (this->inner->enumerate(this->inner, v1, v2, v3, v4, v5)) + if (this->inner->venumerate(this->inner, args)) { return TRUE; } @@ -454,103 +478,100 @@ static bool enumerate_nested(nested_enumerator_t *this, void *v1, void *v2, } } -/** - * Implementation of enumerator_create_nested().destroy() - **/ -static void destroy_nested(nested_enumerator_t *this) +METHOD(enumerator_t, destroy_nested, void, + nested_enumerator_t *this) { - if (this->destroy_data) + if (this->destructor) { - this->destroy_data(this->data); + this->destructor(this->data); } DESTROY_IF(this->inner); this->outer->destroy(this->outer); free(this); } -/** - * See header +/* + * Described in header */ enumerator_t *enumerator_create_nested(enumerator_t *outer, enumerator_t *(inner_constructor)(void *outer, void *data), - void *data, void (*destroy_data)(void *data)) + void *data, void (*destructor)(void *data)) { - nested_enumerator_t *enumerator = malloc_thing(nested_enumerator_t); + nested_enumerator_t *this; - enumerator->public.enumerate = (void*)enumerate_nested; - enumerator->public.destroy = (void*)destroy_nested; - enumerator->outer = outer; - enumerator->inner = NULL; - enumerator->create_inner = (void*)inner_constructor; - enumerator->data = data; - enumerator->destroy_data = destroy_data; - - return &enumerator->public; + INIT(this, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_nested, + .destroy = _destroy_nested, + }, + .outer = outer, + .create_inner = inner_constructor, + .data = data, + .destructor = destructor, + ); + return &this->public; } /** - * enumerator for filtered enumerator + * Enumerator for filtered enumerator */ typedef struct { enumerator_t public; - enumerator_t *unfiltered; + enumerator_t *orig; void *data; - bool (*filter)(void *data, ...); + bool (*filter)(void*,enumerator_t*,va_list); void (*destructor)(void *data); } filter_enumerator_t; -/** - * Implementation of enumerator_create_filter().destroy - */ -static void destroy_filter(filter_enumerator_t *this) +METHOD(enumerator_t, destroy_filter, void, + filter_enumerator_t *this) { if (this->destructor) { this->destructor(this->data); } - this->unfiltered->destroy(this->unfiltered); + this->orig->destroy(this->orig); free(this); } -/** - * Implementation of enumerator_create_filter().enumerate - */ -static bool enumerate_filter(filter_enumerator_t *this, void *o1, void *o2, - void *o3, void *o4, void *o5) +METHOD(enumerator_t, enumerate_filter, bool, + filter_enumerator_t *this, va_list args) { - void *i1, *i2, *i3, *i4, *i5; + bool result = FALSE; - while (this->unfiltered->enumerate(this->unfiltered, &i1, &i2, &i3, &i4, &i5)) + if (this->filter(this->data, this->orig, args)) { - if (this->filter(this->data, &i1, o1, &i2, o2, &i3, o3, &i4, o4, &i5, o5)) - { - return TRUE; - } + result = TRUE; } - return FALSE; + return result; } -/** - * see header +/* + * Described in header */ -enumerator_t *enumerator_create_filter(enumerator_t *unfiltered, - bool (*filter)(void *data, ...), - void *data, void (*destructor)(void *data)) +enumerator_t *enumerator_create_filter(enumerator_t *orig, + bool (*filter)(void *data, enumerator_t *orig, va_list args), + void *data, void (*destructor)(void *data)) { - filter_enumerator_t *this = malloc_thing(filter_enumerator_t); - - this->public.enumerate = (void*)enumerate_filter; - this->public.destroy = (void*)destroy_filter; - this->unfiltered = unfiltered; - this->filter = filter; - this->data = data; - this->destructor = destructor; + filter_enumerator_t *this; + INIT(this, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_filter, + .destroy = _destroy_filter, + }, + .orig = orig, + .filter = filter, + .data = data, + .destructor = destructor, + ); return &this->public; } /** - * enumerator for cleaner enumerator + * Enumerator for cleaner enumerator */ typedef struct { enumerator_t public; @@ -559,44 +580,48 @@ typedef struct { void *data; } cleaner_enumerator_t; -/** - * Implementation of enumerator_create_cleanup().destroy - */ -static void destroy_cleaner(cleaner_enumerator_t *this) +METHOD(enumerator_t, destroy_cleaner, void, + cleaner_enumerator_t *this) { this->cleanup(this->data); this->wrapped->destroy(this->wrapped); free(this); } -/** - * Implementation of enumerator_create_cleaner().enumerate - */ -static bool enumerate_cleaner(cleaner_enumerator_t *this, void *v1, void *v2, - void *v3, void *v4, void *v5) +METHOD(enumerator_t, enumerate_cleaner, bool, + cleaner_enumerator_t *this, va_list args) { - return this->wrapped->enumerate(this->wrapped, v1, v2, v3, v4, v5); + if (!this->wrapped->venumerate) + { + DBG1(DBG_LIB, "!!! CLEANER ENUMERATOR: venumerate() missing !!!"); + return FALSE; + } + return this->wrapped->venumerate(this->wrapped, args); } -/** - * see header +/* + * Described in header */ enumerator_t *enumerator_create_cleaner(enumerator_t *wrapped, void (*cleanup)(void *data), void *data) { - cleaner_enumerator_t *this = malloc_thing(cleaner_enumerator_t); - - this->public.enumerate = (void*)enumerate_cleaner; - this->public.destroy = (void*)destroy_cleaner; - this->wrapped = wrapped; - this->cleanup = cleanup; - this->data = data; + cleaner_enumerator_t *this; + INIT(this, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_cleaner, + .destroy = _destroy_cleaner, + }, + .wrapped = wrapped, + .cleanup = cleanup, + .data = data, + ); return &this->public; } /** - * enumerator for single enumerator + * Enumerator for single enumerator */ typedef struct { enumerator_t public; @@ -605,10 +630,8 @@ typedef struct { bool done; } single_enumerator_t; -/** - * Implementation of enumerator_create_single().destroy - */ -static void destroy_single(single_enumerator_t *this) +METHOD(enumerator_t, destroy_single, void, + single_enumerator_t *this) { if (this->cleanup) { @@ -617,11 +640,12 @@ static void destroy_single(single_enumerator_t *this) free(this); } -/** - * Implementation of enumerator_create_single().enumerate - */ -static bool enumerate_single(single_enumerator_t *this, void **item) +METHOD(enumerator_t, enumerate_single, bool, + single_enumerator_t *this, va_list args) { + void **item; + + VA_ARGS_VGET(args, item); if (this->done) { return FALSE; @@ -631,19 +655,21 @@ static bool enumerate_single(single_enumerator_t *this, void **item) return TRUE; } -/** - * see header +/* + * Described in header */ enumerator_t *enumerator_create_single(void *item, void (*cleanup)(void *item)) { - single_enumerator_t *this = malloc_thing(single_enumerator_t); - - this->public.enumerate = (void*)enumerate_single; - this->public.destroy = (void*)destroy_single; - this->item = item; - this->cleanup = cleanup; - this->done = FALSE; + single_enumerator_t *this; + INIT(this, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_single, + .destroy = _destroy_single, + }, + .item = item, + .cleanup = cleanup, + ); return &this->public; } - diff --git a/src/libstrongswan/collections/enumerator.h b/src/libstrongswan/collections/enumerator.h index 55f8d83e6..99f8847e4 100644 --- a/src/libstrongswan/collections/enumerator.h +++ b/src/libstrongswan/collections/enumerator.h @@ -1,7 +1,7 @@ /* - * Copyright (C) 2013 Tobias Brunner + * Copyright (C) 2013-2017 Tobias Brunner * Copyright (C) 2007 Martin Willi - * Hochschule fuer Technik Rapperswil + * 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 @@ -34,8 +34,11 @@ struct enumerator_t { /** * Enumerate collection. * - * The enumerate function takes a variable argument list containing - * pointers where the enumerated values get written. + * The enumerate() method takes a variable number of pointer arguments + * where the enumerated values get written to. + * + * @note Just assigning the generic enumerator_enumerate_default() function + * that calls the enumerator's venumerate() method is usually enough. * * @param ... variable list of enumerated items, implementation dependent * @return TRUE if pointers returned @@ -43,12 +46,34 @@ struct enumerator_t { bool (*enumerate)(enumerator_t *this, ...); /** - * Destroy a enumerator instance. + * Enumerate collection. + * + * The venumerate() method takes a variable argument list containing + * pointers where the enumerated values get written to. + * + * To simplify the implementation the VA_ARGS_VGET() macro may be used. + * + * @param args variable list of enumerated items, implementation dependent + * @return TRUE if pointers returned + */ + bool (*venumerate)(enumerator_t *this, va_list args); + + /** + * Destroy an enumerator_t instance. */ void (*destroy)(enumerator_t *this); }; /** + * Generic implementation of enumerator_t::enumerate() that simply calls + * the enumerator's venumerate() method. + * + * @param enumerator the enumerator + * @param ... arguments passed to enumerate() + */ +bool enumerator_enumerate_default(enumerator_t *enumerator, ...); + +/** * Create an enumerator which enumerates over nothing * * @return an enumerator over no values @@ -147,38 +172,41 @@ enumerator_t* enumerator_create_token(const char *string, const char *sep, /** * Creates an enumerator which enumerates over enumerated enumerators :-). * - * The variable argument list of enumeration values is limit to 5. + * The outer enumerator is expected to return objects that, when passed to + * inner_contructor, will create a new enumerator that will be enumerated until + * completion (to this enumerator will the pointer arguments that are passed to + * this enumerator be forwarded) at which point a new element from the outer + * enumerator is requested to create a new inner enumerator. * * @param outer outer enumerator - * @param inner_constructor constructor to inner enumerator + * @param inner_constructor constructor to create inner enumerator * @param data data to pass to each inner_constructor call - * @param destroy_data destructor to pass to data + * @param destructor destructor function to clean up data after use * @return the nested enumerator */ enumerator_t *enumerator_create_nested(enumerator_t *outer, enumerator_t *(*inner_constructor)(void *outer, void *data), - void *data, void (*destroy_data)(void *data)); + void *data, void (*destructor)(void *data)); /** - * Creates an enumerator which filters output of another enumerator. + * Creates an enumerator which filters/maps output of another enumerator. * - * The filter function receives the user supplied "data" followed by a - * unfiltered enumeration item, followed by an output pointer where to write - * the filtered data. Then the next input/output pair follows. - * It returns TRUE to deliver the - * values to the caller of enumerate(), FALSE to filter this enumeration. + * The filter function receives the user supplied "data" followed by the + * original enumerator, followed by the arguments passed to the outer + * enumerator. It returns TRUE to deliver the values assigned to these + * arguments to the caller of enumerate() and FALSE to end the enumeration. + * Filtering items is simple as the filter function may just skip enumerated + * items from the original enumerator. * - * The variable argument list of enumeration values is limit to 5. - * - * @param unfiltered unfiltered enumerator to wrap, gets destroyed + * @param orig original enumerator to wrap, gets destroyed * @param filter filter function * @param data user data to supply to filter * @param destructor destructor function to clean up data after use * @return the filtered enumerator */ -enumerator_t *enumerator_create_filter(enumerator_t *unfiltered, - bool (*filter)(void *data, ...), - void *data, void (*destructor)(void *data)); +enumerator_t *enumerator_create_filter(enumerator_t *orig, + bool (*filter)(void *data, enumerator_t *orig, va_list args), + void *data, void (*destructor)(void *data)); /** * Create an enumerator wrapper which does a cleanup on destroy. diff --git a/src/libstrongswan/collections/hashtable.c b/src/libstrongswan/collections/hashtable.c index 2b77a37cc..b0eda9e6a 100644 --- a/src/libstrongswan/collections/hashtable.c +++ b/src/libstrongswan/collections/hashtable.c @@ -379,8 +379,13 @@ METHOD(hashtable_t, get_count, u_int, } METHOD(enumerator_t, enumerate, bool, - private_enumerator_t *this, const void **key, void **value) + private_enumerator_t *this, va_list args) { + const void **key; + void **value; + + VA_ARGS_VGET(args, key, value); + while (this->count && this->row < this->table->capacity) { this->prev = this->current; @@ -417,7 +422,8 @@ METHOD(hashtable_t, create_enumerator, enumerator_t*, INIT(enumerator, .enumerator = { - .enumerate = (void*)_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate, .destroy = (void*)free, }, .table = this, diff --git a/src/libstrongswan/collections/linked_list.c b/src/libstrongswan/collections/linked_list.c index b8fe81578..f877be5a6 100644 --- a/src/libstrongswan/collections/linked_list.c +++ b/src/libstrongswan/collections/linked_list.c @@ -47,6 +47,17 @@ struct element_t { element_t *next; }; +/* + * Described in header + */ +bool linked_list_match_str(void *item, va_list args) +{ + char *a = item, *b; + + VA_ARGS_VGET(args, b); + return streq(a, b); +} + /** * Creates an empty linked list object. */ @@ -119,8 +130,12 @@ struct private_enumerator_t { }; METHOD(enumerator_t, enumerate, bool, - private_enumerator_t *this, void **item) + private_enumerator_t *this, va_list args) { + void **item; + + VA_ARGS_VGET(args, item); + if (this->finished) { return FALSE; @@ -152,7 +167,8 @@ METHOD(linked_list_t, create_enumerator, enumerator_t*, INIT(enumerator, .enumerator = { - .enumerate = (void*)_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate, .destroy = (void*)free, }, .list = this, @@ -366,52 +382,68 @@ METHOD(linked_list_t, remove_at, void, } } -METHOD(linked_list_t, find_first, status_t, - private_linked_list_t *this, linked_list_match_t match, - void **item, void *d1, void *d2, void *d3, void *d4, void *d5) +METHOD(linked_list_t, find_first, bool, + private_linked_list_t *this, linked_list_match_t match, void **item, ...) { element_t *current = this->first; + va_list args; + bool matched = FALSE; + + if (!match && !item) + { + return FALSE; + } while (current) { - if ((match && match(current->value, d1, d2, d3, d4, d5)) || - (!match && item && current->value == *item)) + if (match) + { + va_start(args, item); + matched = match(current->value, args); + va_end(args); + } + else + { + matched = current->value == *item; + } + if (matched) { if (item != NULL) { *item = current->value; } - return SUCCESS; + return TRUE; } current = current->next; } - return NOT_FOUND; + return FALSE; } METHOD(linked_list_t, invoke_offset, void, - private_linked_list_t *this, size_t offset, - void *d1, void *d2, void *d3, void *d4, void *d5) + private_linked_list_t *this, size_t offset) { element_t *current = this->first; - linked_list_invoke_t *method; + void (**method)(void*); while (current) { method = current->value + offset; - (*method)(current->value, d1, d2, d3, d4, d5); + (*method)(current->value); current = current->next; } } METHOD(linked_list_t, invoke_function, void, - private_linked_list_t *this, linked_list_invoke_t fn, - void *d1, void *d2, void *d3, void *d4, void *d5) + private_linked_list_t *this, linked_list_invoke_t fn, ...) { element_t *current = this->first; + va_list args; while (current) { - fn(current->value, d1, d2, d3, d4, d5); + va_start(args, fn); + fn(current->value, args); + va_end(args); current = current->next; } } @@ -542,7 +574,7 @@ linked_list_t *linked_list_create() .reset_enumerator = (void*)_reset_enumerator, .get_first = _get_first, .get_last = _get_last, - .find_first = (void*)_find_first, + .find_first = _find_first, .insert_first = _insert_first, .insert_last = _insert_last, .insert_before = (void*)_insert_before, @@ -550,8 +582,8 @@ linked_list_t *linked_list_create() .remove_last = _remove_last, .remove = _remove_, .remove_at = (void*)_remove_at, - .invoke_offset = (void*)_invoke_offset, - .invoke_function = (void*)_invoke_function, + .invoke_offset = _invoke_offset, + .invoke_function = _invoke_function, .clone_offset = _clone_offset, .equals_offset = _equals_offset, .equals_function = _equals_function, diff --git a/src/libstrongswan/collections/linked_list.h b/src/libstrongswan/collections/linked_list.h index 0b73079d3..246b9a5c5 100644 --- a/src/libstrongswan/collections/linked_list.h +++ b/src/libstrongswan/collections/linked_list.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2015 Tobias Brunner + * Copyright (C) 2007-2017 Tobias Brunner * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -28,23 +28,30 @@ typedef struct linked_list_t linked_list_t; #include <collections/enumerator.h> /** - * Method to match elements in a linked list (used in find_* functions) + * Function to match elements in a linked list * * @param item current list item - * @param ... user supplied data (only pointers, at most 5) + * @param args user supplied data + * @return TRUE, if the item matched, FALSE otherwise + */ +typedef bool (*linked_list_match_t)(void *item, va_list args); + +/** + * Helper function to match a string in a linked list of strings + * + * @param item list item (char*) + * @param args user supplied data (char*) * @return - * - TRUE, if the item matched - * - FALSE, otherwise */ -typedef bool (*linked_list_match_t)(void *item, ...); +bool linked_list_match_str(void *item, va_list args); /** - * Method to be invoked on elements in a linked list (used in invoke_* functions) + * Function to be invoked on elements in a linked list * * @param item current list item - * @param ... user supplied data (only pointers, at most 5) + * @param args user supplied data */ -typedef void (*linked_list_invoke_t)(void *item, ...); +typedef void (*linked_list_invoke_t)(void *item, va_list args); /** * Class implementing a double linked list. @@ -167,21 +174,20 @@ struct linked_list_t { * * The first object passed to the match function is the current list item, * followed by the user supplied data. - * If the supplied function returns TRUE this function returns SUCCESS, and - * the current object is returned in the third parameter, otherwise, + * If the supplied function returns TRUE so does this function, and the + * current object is returned in the third parameter (if given), otherwise, * the next item is checked. * * If match is NULL, *item and the current object are compared. * - * @warning Only use pointers as user supplied data. - * * @param match comparison function to call on each object, or NULL - * @param item the list item, if found - * @param ... user data to supply to match function (limited to 5 arguments) - * @return SUCCESS if found, NOT_FOUND otherwise + * @param item the list item, if found, or NULL + * @param ... user data to supply to match function + * @return TRUE if found, FALSE otherwise (or if neither match, + * nor item is supplied) */ - status_t (*find_first) (linked_list_t *this, linked_list_match_t match, - void **item, ...); + bool (*find_first)(linked_list_t *this, linked_list_match_t match, + void **item, ...); /** * Invoke a method on all of the contained objects. @@ -192,22 +198,18 @@ struct linked_list_t { * which can be evalutated at compile time using the offsetof * macro, e.g.: list->invoke(list, offsetof(object_t, method)); * - * @warning Only use pointers as user supplied data. - * * @param offset offset of the method to invoke on objects - * @param ... user data to supply to called function (limited to 5 arguments) */ - void (*invoke_offset) (linked_list_t *this, size_t offset, ...); + void (*invoke_offset)(linked_list_t *this, size_t offset); /** * Invoke a function on all of the contained objects. * - * @warning Only use pointers as user supplied data. - * - * @param function offset of the method to invoke on objects - * @param ... user data to supply to called function (limited to 5 arguments) + * @param function function to call for each object + * @param ... user data to supply to called function */ - void (*invoke_function) (linked_list_t *this, linked_list_invoke_t function, ...); + void (*invoke_function)(linked_list_t *this, linked_list_invoke_t function, + ...); /** * Clones a list and its objects using the objects' clone method. diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c index 8a3e659fd..a9c8b3904 100644 --- a/src/libstrongswan/credentials/auth_cfg.c +++ b/src/libstrongswan/credentials/auth_cfg.c @@ -146,12 +146,14 @@ typedef struct { bool enumerated[AUTH_RULE_MAX]; } entry_enumerator_t; -/** - * enumerate function for item_enumerator_t - */ -static bool enumerate(entry_enumerator_t *this, auth_rule_t *type, void **value) +METHOD(enumerator_t, enumerate, bool, + entry_enumerator_t *this, va_list args) { + auth_rule_t *type; entry_t *entry; + void **value; + + VA_ARGS_VGET(args, type, value); while (this->inner->enumerate(this->inner, &entry)) { @@ -174,10 +176,8 @@ static bool enumerate(entry_enumerator_t *this, auth_rule_t *type, void **value) return FALSE; } -/** - * destroy function for item_enumerator_t - */ -static void entry_enumerator_destroy(entry_enumerator_t *this) +METHOD(enumerator_t, entry_enumerator_destroy, void, + entry_enumerator_t *this) { this->inner->destroy(this->inner); free(this); @@ -190,8 +190,9 @@ METHOD(auth_cfg_t, create_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)enumerate, - .destroy = (void*)entry_enumerator_destroy, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate, + .destroy = _entry_enumerator_destroy, }, .inner = array_create_enumerator(this->entries), ); diff --git a/src/libstrongswan/credentials/credential_factory.c b/src/libstrongswan/credentials/credential_factory.c index 94c7820e1..07e6ea343 100644 --- a/src/libstrongswan/credentials/credential_factory.c +++ b/src/libstrongswan/credentials/credential_factory.c @@ -163,17 +163,23 @@ METHOD(credential_factory_t, create, void*, return construct; } -/** - * Filter function for builder enumerator - */ -static bool builder_filter(void *null, entry_t **entry, credential_type_t *type, - void *dummy1, int *subtype) +CALLBACK(builder_filter, bool, + void *null, enumerator_t *orig, va_list args) { - if ((*entry)->final) + entry_t *entry; + credential_type_t *type; + int *subtype; + + VA_ARGS_VGET(args, type, subtype); + + while (orig->enumerate(orig, &entry)) { - *type = (*entry)->type; - *subtype = (*entry)->subtype; - return TRUE; + if (entry->final) + { + *type = entry->type; + *subtype = entry->subtype; + return TRUE; + } } return FALSE; } @@ -184,7 +190,7 @@ METHOD(credential_factory_t, create_builder_enumerator, enumerator_t*, this->lock->read_lock(this->lock); return enumerator_create_filter( this->constructors->create_enumerator(this->constructors), - (void*)builder_filter, this->lock, (void*)this->lock->unlock); + builder_filter, this->lock, (void*)this->lock->unlock); } METHOD(credential_factory_t, destroy, void, diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c index 95c5cd777..0a8d3d101 100644 --- a/src/libstrongswan/credentials/credential_manager.c +++ b/src/libstrongswan/credentials/credential_manager.c @@ -155,8 +155,12 @@ METHOD(credential_manager_t, call_hook, void, } METHOD(enumerator_t, sets_enumerate, bool, - sets_enumerator_t *this, credential_set_t **set) + sets_enumerator_t *this, va_list args) { + credential_set_t **set; + + VA_ARGS_VGET(args, set); + if (this->exclusive) { if (this->exclusive->enumerate(this->exclusive, set)) @@ -166,19 +170,19 @@ METHOD(enumerator_t, sets_enumerate, bool, return TRUE; } } - if (this->global) + if (this->local) { - if (this->global->enumerate(this->global, set)) + if (this->local->enumerate(this->local, set)) { return TRUE; } - /* end of global sets, look for local */ - this->global->destroy(this->global); - this->global = NULL; + /* end of local sets, look for global */ + this->local->destroy(this->local); + this->local = NULL; } - if (this->local) + if (this->global) { - return this->local->enumerate(this->local, set); + return this->global->enumerate(this->global, set); } return FALSE; } @@ -202,7 +206,8 @@ static enumerator_t *create_sets_enumerator(private_credential_manager_t *this) INIT(enumerator, .public = { - .enumerate = (void*)_sets_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _sets_enumerate, .destroy = _sets_destroy, }, ); @@ -807,11 +812,12 @@ static bool verify_trust_chain(private_credential_manager_t *this, return trusted; } -/** - * List find match function for certificates - */ -static bool cert_equals(certificate_t *a, certificate_t *b) +CALLBACK(cert_equals, bool, + certificate_t *a, va_list args) { + certificate_t *b; + + VA_ARGS_VGET(args, b); return a->equals(a, b); } @@ -840,9 +846,12 @@ typedef struct { } trusted_enumerator_t; METHOD(enumerator_t, trusted_enumerate, bool, - trusted_enumerator_t *this, certificate_t **cert, auth_cfg_t **auth) + trusted_enumerator_t *this, va_list args) { - certificate_t *current; + certificate_t *current, **cert; + auth_cfg_t **auth; + + VA_ARGS_VGET(args, cert, auth); DESTROY_IF(this->auth); this->auth = auth_cfg_create(); @@ -888,8 +897,7 @@ METHOD(enumerator_t, trusted_enumerate, bool, continue; } - if (this->failed->find_first(this->failed, (void*)cert_equals, - NULL, current) == SUCCESS) + if (this->failed->find_first(this->failed, cert_equals, NULL, current)) { /* check each candidate only once */ continue; } @@ -931,7 +939,8 @@ METHOD(credential_manager_t, create_trusted_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_trusted_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _trusted_enumerate, .destroy = _trusted_destroy, }, .this = this, @@ -960,9 +969,13 @@ typedef struct { } public_enumerator_t; METHOD(enumerator_t, public_enumerate, bool, - public_enumerator_t *this, public_key_t **key, auth_cfg_t **auth) + public_enumerator_t *this, va_list args) { certificate_t *cert; + public_key_t **key; + auth_cfg_t **auth; + + VA_ARGS_VGET(args, key, auth); while (this->inner->enumerate(this->inner, &cert, auth)) { @@ -1001,7 +1014,8 @@ METHOD(credential_manager_t, create_public_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_public_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _public_enumerate, .destroy = _public_destroy, }, .inner = create_trusted_enumerator(this, type, id, online), diff --git a/src/libstrongswan/credentials/keys/public_key.c b/src/libstrongswan/credentials/keys/public_key.c index 2c76ad680..87f7e6664 100644 --- a/src/libstrongswan/credentials/keys/public_key.c +++ b/src/libstrongswan/credentials/keys/public_key.c @@ -272,8 +272,12 @@ typedef struct { } private_enumerator_t; METHOD(enumerator_t, signature_schemes_enumerate, bool, - private_enumerator_t *this, signature_scheme_t *scheme) + private_enumerator_t *this, va_list args) { + signature_scheme_t *scheme; + + VA_ARGS_VGET(args, scheme); + while (++this->index < countof(scheme_map)) { if (this->type == scheme_map[this->index].type && @@ -296,7 +300,8 @@ enumerator_t *signature_schemes_for_key(key_type_t type, int size) INIT(this, .public = { - .enumerate = (void*)_signature_schemes_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _signature_schemes_enumerate, .destroy = (void*)free, }, .index = -1, diff --git a/src/libstrongswan/credentials/sets/auth_cfg_wrapper.c b/src/libstrongswan/credentials/sets/auth_cfg_wrapper.c index 8393d5b18..1cd4b9d03 100644 --- a/src/libstrongswan/credentials/sets/auth_cfg_wrapper.c +++ b/src/libstrongswan/credentials/sets/auth_cfg_wrapper.c @@ -112,15 +112,15 @@ static bool fetch_cert(wrapper_enumerator_t *enumerator, return TRUE; } -/** - * enumerate function for wrapper_enumerator_t - */ -static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert) +METHOD(enumerator_t, enumerate, bool, + wrapper_enumerator_t *this, va_list args) { auth_rule_t rule; - certificate_t *current; + certificate_t *current, **cert; public_key_t *public; + VA_ARGS_VGET(args, cert); + while (this->inner->enumerate(this->inner, &rule, ¤t)) { if (rule == AUTH_HELPER_IM_HASH_URL || @@ -164,10 +164,8 @@ static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert) return FALSE; } -/** - * destroy function for wrapper_enumerator_t - */ -static void wrapper_enumerator_destroy(wrapper_enumerator_t *this) +METHOD(enumerator_t, wrapper_enumerator_destroy, void, + wrapper_enumerator_t *this) { this->inner->destroy(this->inner); free(this); @@ -183,14 +181,18 @@ METHOD(credential_set_t, create_enumerator, enumerator_t*, { return NULL; } - enumerator = malloc_thing(wrapper_enumerator_t); - enumerator->auth = this->auth; - enumerator->cert = cert; - enumerator->key = key; - enumerator->id = id; - enumerator->inner = this->auth->create_enumerator(this->auth); - enumerator->public.enumerate = (void*)enumerate; - enumerator->public.destroy = (void*)wrapper_enumerator_destroy; + INIT(enumerator, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate, + .destroy = _wrapper_enumerator_destroy, + }, + .auth = this->auth, + .cert = cert, + .key = key, + .id = id, + .inner = this->auth->create_enumerator(this->auth), + ); return &enumerator->public; } diff --git a/src/libstrongswan/credentials/sets/callback_cred.c b/src/libstrongswan/credentials/sets/callback_cred.c index bff33f029..0d72452da 100644 --- a/src/libstrongswan/credentials/sets/callback_cred.c +++ b/src/libstrongswan/credentials/sets/callback_cred.c @@ -60,9 +60,12 @@ typedef struct { } shared_enumerator_t; METHOD(enumerator_t, shared_enumerate, bool, - shared_enumerator_t *this, shared_key_t **out, - id_match_t *match_me, id_match_t *match_other) + shared_enumerator_t *this, va_list args) { + shared_key_t **out; + id_match_t *match_me, *match_other; + + VA_ARGS_VGET(args, out, match_me, match_other); DESTROY_IF(this->current); this->current = this->this->cb.shared(this->this->data, this->type, this->me, this->other, match_me, match_other); @@ -89,7 +92,8 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_shared_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _shared_enumerate, .destroy = _shared_destroy, }, .this = this, diff --git a/src/libstrongswan/credentials/sets/cert_cache.c b/src/libstrongswan/credentials/sets/cert_cache.c index 24fdb194b..92d5efdc6 100644 --- a/src/libstrongswan/credentials/sets/cert_cache.c +++ b/src/libstrongswan/credentials/sets/cert_cache.c @@ -252,13 +252,14 @@ typedef struct { int locked; } cert_enumerator_t; -/** - * filter function for certs enumerator - */ -static bool cert_enumerate(cert_enumerator_t *this, certificate_t **out) +METHOD(enumerator_t, cert_enumerate, bool, + cert_enumerator_t *this, va_list args) { public_key_t *public; relation_t *rel; + certificate_t **out; + + VA_ARGS_VGET(args, out); if (this->locked >= 0) { @@ -311,10 +312,8 @@ static bool cert_enumerate(cert_enumerator_t *this, certificate_t **out) return FALSE; } -/** - * clean up enumeration data - */ -static void cert_enumerator_destroy(cert_enumerator_t *this) +METHOD(enumerator_t, cert_enumerator_destroy, void, + cert_enumerator_t *this) { relation_t *rel; @@ -336,16 +335,19 @@ METHOD(credential_set_t, create_enumerator, enumerator_t*, { return NULL; } - enumerator = malloc_thing(cert_enumerator_t); - enumerator->public.enumerate = (void*)cert_enumerate; - enumerator->public.destroy = (void*)cert_enumerator_destroy; - enumerator->cert = cert; - enumerator->key = key; - enumerator->id = id; - enumerator->relations = this->relations; - enumerator->index = -1; - enumerator->locked = -1; - + INIT(enumerator, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _cert_enumerate, + .destroy = _cert_enumerator_destroy, + }, + .cert = cert, + .key = key, + .id = id, + .relations = this->relations, + .index = -1, + .locked = -1, + ); return &enumerator->public; } diff --git a/src/libstrongswan/credentials/sets/mem_cred.c b/src/libstrongswan/credentials/sets/mem_cred.c index 53e035f98..4d594e439 100644 --- a/src/libstrongswan/credentials/sets/mem_cred.c +++ b/src/libstrongswan/credentials/sets/mem_cred.c @@ -74,25 +74,27 @@ typedef struct { identification_t *id; } cert_data_t; -/** - * destroy cert_data - */ -static void cert_data_destroy(cert_data_t *data) +CALLBACK(cert_data_destroy, void, + cert_data_t *data) { data->lock->unlock(data->lock); free(data); } -/** - * filter function for certs enumerator - */ -static bool certs_filter(cert_data_t *data, certificate_t **in, certificate_t **out) +CALLBACK(certs_filter, bool, + cert_data_t *data, enumerator_t *orig, va_list args) { public_key_t *public; - certificate_t *cert = *in; + certificate_t *cert, **out; + + VA_ARGS_VGET(args, out); - if (data->cert == CERT_ANY || data->cert == cert->get_type(cert)) + while (orig->enumerate(orig, &cert)) { + if (data->cert != CERT_ANY && data->cert != cert->get_type(cert)) + { + continue; + } public = cert->get_public_key(cert); if (public) { @@ -102,7 +104,7 @@ static bool certs_filter(cert_data_t *data, certificate_t **in, certificate_t ** data->id->get_encoding(data->id))) { public->destroy(public); - *out = *in; + *out = cert; return TRUE; } } @@ -110,11 +112,11 @@ static bool certs_filter(cert_data_t *data, certificate_t **in, certificate_t ** } else if (data->key != KEY_ANY) { - return FALSE; + continue; } - if (data->id == NULL || cert->has_subject(cert, data->id)) + if (!data->id || cert->has_subject(cert, data->id)) { - *out = *in; + *out = cert; return TRUE; } } @@ -143,12 +145,16 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, { enumerator = this->untrusted->create_enumerator(this->untrusted); } - return enumerator_create_filter(enumerator, (void*)certs_filter, data, - (void*)cert_data_destroy); + return enumerator_create_filter(enumerator, certs_filter, data, + cert_data_destroy); } -static bool certificate_equals(certificate_t *item, certificate_t *cert) +CALLBACK(certificate_equals, bool, + certificate_t *item, va_list args) { + certificate_t *cert; + + VA_ARGS_VGET(args, cert); return item->equals(item, cert); } @@ -161,9 +167,8 @@ static certificate_t *add_cert_internal(private_mem_cred_t *this, bool trusted, { certificate_t *cached; this->lock->write_lock(this->lock); - if (this->untrusted->find_first(this->untrusted, - (linked_list_match_t)certificate_equals, - (void**)&cached, cert) == SUCCESS) + if (this->untrusted->find_first(this->untrusted, certificate_equals, + (void**)&cached, cert)) { cert->destroy(cert); cert = cached->get_ref(cached); @@ -199,9 +204,8 @@ METHOD(mem_cred_t, get_cert_ref, certificate_t*, certificate_t *cached; this->lock->read_lock(this->lock); - if (this->untrusted->find_first(this->untrusted, - (linked_list_match_t)certificate_equals, - (void**)&cached, cert) == SUCCESS) + if (this->untrusted->find_first(this->untrusted, certificate_equals, + (void**)&cached, cert)) { cert->destroy(cert); cert = cached->get_ref(cached); @@ -301,30 +305,30 @@ typedef struct { identification_t *id; } key_data_t; -/** - * Destroy key enumerator data - */ -static void key_data_destroy(key_data_t *data) +CALLBACK(key_data_destroy, void, + key_data_t *data) { data->lock->unlock(data->lock); free(data); } -/** - * filter function for private key enumerator - */ -static bool key_filter(key_data_t *data, private_key_t **in, private_key_t **out) +CALLBACK(key_filter, bool, + key_data_t *data, enumerator_t *orig, va_list args) { - private_key_t *key; + private_key_t *key, **out; + + VA_ARGS_VGET(args, out); - key = *in; - if (data->type == KEY_ANY || data->type == key->get_type(key)) + while (orig->enumerate(orig, &key)) { - if (data->id == NULL || - key->has_fingerprint(key, data->id->get_encoding(data->id))) + if (data->type == KEY_ANY || data->type == key->get_type(key)) { - *out = key; - return TRUE; + if (data->id == NULL || + key->has_fingerprint(key, data->id->get_encoding(data->id))) + { + *out = key; + return TRUE; + } } } return FALSE; @@ -342,7 +346,7 @@ METHOD(credential_set_t, create_private_enumerator, enumerator_t*, ); this->lock->read_lock(this->lock); return enumerator_create_filter(this->keys->create_enumerator(this->keys), - (void*)key_filter, data, (void*)key_data_destroy); + key_filter, data, key_data_destroy); } METHOD(mem_cred_t, add_key, void, @@ -468,10 +472,8 @@ typedef struct { shared_key_type_t type; } shared_data_t; -/** - * free shared key enumerator data and unlock list - */ -static void shared_data_destroy(shared_data_t *data) +CALLBACK(shared_data_destroy, void, + shared_data_t *data) { data->lock->unlock(data->lock); free(data); @@ -499,44 +501,47 @@ static id_match_t has_owner(shared_entry_t *entry, identification_t *owner) return best; } -/** - * enumerator filter function for shared entries - */ -static bool shared_filter(shared_data_t *data, - shared_entry_t **in, shared_key_t **out, - void **unused1, id_match_t *me, - void **unused2, id_match_t *other) +CALLBACK(shared_filter, bool, + shared_data_t *data, enumerator_t *orig, va_list args) { id_match_t my_match = ID_MATCH_NONE, other_match = ID_MATCH_NONE; - shared_entry_t *entry = *in; + shared_entry_t *entry; + shared_key_t **out; + id_match_t *me, *other; - if (data->type != SHARED_ANY && - entry->shared->get_type(entry->shared) != data->type) - { - return FALSE; - } - if (data->me) - { - my_match = has_owner(entry, data->me); - } - if (data->other) - { - other_match = has_owner(entry, data->other); - } - if ((data->me || data->other) && (!my_match && !other_match)) - { - return FALSE; - } - *out = entry->shared; - if (me) - { - *me = my_match; - } - if (other) + VA_ARGS_VGET(args, out, me, other); + + while (orig->enumerate(orig, &entry)) { - *other = other_match; + if (data->type != SHARED_ANY && + entry->shared->get_type(entry->shared) != data->type) + { + continue; + } + if (data->me) + { + my_match = has_owner(entry, data->me); + } + if (data->other) + { + other_match = has_owner(entry, data->other); + } + if ((data->me || data->other) && (!my_match && !other_match)) + { + continue; + } + *out = entry->shared; + if (me) + { + *me = my_match; + } + if (other) + { + *other = other_match; + } + return TRUE; } - return TRUE; + return FALSE; } METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, @@ -554,7 +559,7 @@ METHOD(credential_set_t, create_shared_enumerator, enumerator_t*, data->lock->read_lock(data->lock); return enumerator_create_filter( this->shared->create_enumerator(this->shared), - (void*)shared_filter, data, (void*)shared_data_destroy); + shared_filter, data, shared_data_destroy); } METHOD(mem_cred_t, add_shared_unique, void, @@ -648,23 +653,27 @@ METHOD(mem_cred_t, remove_shared_unique, void, this->lock->unlock(this->lock); } -/** - * Filter unique ids of shared keys (ingore secrets without unique id) - */ -static bool unique_filter(void *unused, - shared_entry_t **in, char **id) +CALLBACK(unique_filter, bool, + void *unused, enumerator_t *orig, va_list args) { - shared_entry_t *entry = *in; + shared_entry_t *entry; + char **id; - if (!entry->id) - { - return FALSE; - } - if (id) + VA_ARGS_VGET(args, id); + + while (orig->enumerate(orig, &entry)) { - *id = entry->id; + if (!entry->id) + { + continue; + } + if (id) + { + *id = entry->id; + } + return TRUE; } - return TRUE; + return FALSE; } METHOD(mem_cred_t, create_unique_shared_enumerator, enumerator_t*, @@ -673,7 +682,7 @@ METHOD(mem_cred_t, create_unique_shared_enumerator, enumerator_t*, this->lock->read_lock(this->lock); return enumerator_create_filter( this->shared->create_enumerator(this->shared), - (void*)unique_filter, this->lock, + unique_filter, this->lock, (void*)this->lock->unlock); } @@ -721,30 +730,35 @@ typedef struct { rwlock_t *lock; } cdp_data_t; -/** - * Clean up CDP enumerator data - */ -static void cdp_data_destroy(cdp_data_t *data) +CALLBACK(cdp_data_destroy, void, + cdp_data_t *data) { data->lock->unlock(data->lock); free(data); } -/** - * CDP enumerator filter - */ -static bool cdp_filter(cdp_data_t *data, cdp_t **cdp, char **uri) +CALLBACK(cdp_filter, bool, + cdp_data_t *data, enumerator_t *orig, va_list args) { - if (data->type != CERT_ANY && data->type != (*cdp)->type) - { - return FALSE; - } - if (data->id && !(*cdp)->id->matches((*cdp)->id, data->id)) + cdp_t *cdp; + char **uri; + + VA_ARGS_VGET(args, uri); + + while (orig->enumerate(orig, &cdp)) { - return FALSE; + if (data->type != CERT_ANY && data->type != cdp->type) + { + continue; + } + if (data->id && !cdp->id->matches(cdp->id, data->id)) + { + continue; + } + *uri = cdp->uri; + return TRUE; } - *uri = (*cdp)->uri; - return TRUE; + return FALSE; } METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*, @@ -759,7 +773,7 @@ METHOD(credential_set_t, create_cdp_enumerator, enumerator_t*, ); this->lock->read_lock(this->lock); return enumerator_create_filter(this->cdps->create_enumerator(this->cdps), - (void*)cdp_filter, data, (void*)cdp_data_destroy); + cdp_filter, data, cdp_data_destroy); } diff --git a/src/libstrongswan/credentials/sets/mem_cred.h b/src/libstrongswan/credentials/sets/mem_cred.h index 135515260..f55c3ccdf 100644 --- a/src/libstrongswan/credentials/sets/mem_cred.h +++ b/src/libstrongswan/credentials/sets/mem_cred.h @@ -62,7 +62,7 @@ struct mem_cred_t { /** * Get an existing reference to the same certificate. * - * Searches for the same certficate in the set, and returns a reference + * Searches for the same certificate in the set, and returns a reference * to it, destroying the passed certificate. If the passed certificate * is not found, it is just returned. * diff --git a/src/libstrongswan/credentials/sets/ocsp_response_wrapper.c b/src/libstrongswan/credentials/sets/ocsp_response_wrapper.c index 151d69216..12d3f8156 100644 --- a/src/libstrongswan/credentials/sets/ocsp_response_wrapper.c +++ b/src/libstrongswan/credentials/sets/ocsp_response_wrapper.c @@ -49,14 +49,15 @@ typedef struct { identification_t *id; } wrapper_enumerator_t; -/** - * enumerate function wrapper_enumerator_t - */ -static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert) +METHOD(enumerator_t, enumerate, bool, + wrapper_enumerator_t *this, va_list args) { - certificate_t *current; + certificate_t *current, **cert; public_key_t *public; + + VA_ARGS_VGET(args, cert); + while (this->inner->enumerate(this->inner, ¤t)) { if (this->cert != CERT_ANY && this->cert != current->get_type(current)) @@ -85,10 +86,8 @@ static bool enumerate(wrapper_enumerator_t *this, certificate_t **cert) return FALSE; } -/** - * destroy function for wrapper_enumerator_t - */ -static void enumerator_destroy(wrapper_enumerator_t *this) +METHOD(enumerator_t, enumerator_destroy, void, + wrapper_enumerator_t *this) { this->inner->destroy(this->inner); free(this); @@ -105,13 +104,17 @@ METHOD(credential_set_t, create_enumerator, enumerator_t*, return NULL; } - enumerator = malloc_thing(wrapper_enumerator_t); - enumerator->cert = cert; - enumerator->key = key; - enumerator->id = id; - enumerator->inner = this->response->create_cert_enumerator(this->response); - enumerator->public.enumerate = (void*)enumerate; - enumerator->public.destroy = (void*)enumerator_destroy; + INIT(enumerator, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate, + .destroy = _enumerator_destroy, + }, + .cert = cert, + .key = key, + .id = id, + .inner = this->response->create_cert_enumerator(this->response), + ); return &enumerator->public; } diff --git a/src/libstrongswan/crypto/crypto_factory.c b/src/libstrongswan/crypto/crypto_factory.c index bab59a06f..096bcbc9c 100644 --- a/src/libstrongswan/crypto/crypto_factory.c +++ b/src/libstrongswan/crypto/crypto_factory.c @@ -811,51 +811,66 @@ METHOD(crypto_factory_t, remove_dh, void, this->lock->unlock(this->lock); } -/** - * match algorithms of an entry? - */ -static bool entry_match(entry_t *a, entry_t *b) +CALLBACK(entry_match, bool, + entry_t *a, va_list args) { + entry_t *b; + + VA_ARGS_VGET(args, b); return a->algo == b->algo; } -/** - * check for uniqueness of an entry - */ -static bool unique_check(linked_list_t *list, entry_t **in, entry_t **out) +CALLBACK(unique_check, bool, + linked_list_t *list, enumerator_t *orig, va_list args) { - if (list->find_first(list, (void*)entry_match, NULL, *in) == SUCCESS) + entry_t *entry, **out; + + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, &entry)) { - return FALSE; + if (list->find_first(list, entry_match, NULL, entry)) + { + continue; + } + *out = entry; + list->insert_last(list, entry); + return TRUE; } - *out = *in; - list->insert_last(list, *in); - return TRUE; + return FALSE; } /** * create an enumerator over entry->algo in list with locking and unique check */ static enumerator_t *create_enumerator(private_crypto_factory_t *this, - linked_list_t *list, void *filter) + linked_list_t *list, + bool (*filter)(void*,enumerator_t*,va_list)) { this->lock->read_lock(this->lock); return enumerator_create_filter( enumerator_create_filter( - list->create_enumerator(list), (void*)unique_check, + list->create_enumerator(list), unique_check, linked_list_create(), (void*)list->destroy), filter, this->lock, (void*)this->lock->unlock); } -/** - * Filter function to enumerate algorithm, not entry - */ -static bool crypter_filter(void *n, entry_t **entry, encryption_algorithm_t *algo, - void *i2, const char **plugin_name) +CALLBACK(crypter_filter, bool, + void *n, enumerator_t *orig, va_list args) { - *algo = (*entry)->algo; - *plugin_name = (*entry)->plugin_name; - return TRUE; + entry_t *entry; + encryption_algorithm_t *algo; + const char **plugin_name; + + VA_ARGS_VGET(args, algo, plugin_name); + + if (orig->enumerate(orig, &entry)) + { + *algo = entry->algo; + *plugin_name = entry->plugin_name; + return TRUE; + } + return FALSE; } METHOD(crypto_factory_t, create_crypter_enumerator, enumerator_t*, @@ -870,15 +885,22 @@ METHOD(crypto_factory_t, create_aead_enumerator, enumerator_t*, return create_enumerator(this, this->aeads, crypter_filter); } -/** - * Filter function to enumerate algorithm, not entry - */ -static bool signer_filter(void *n, entry_t **entry, integrity_algorithm_t *algo, - void *i2, const char **plugin_name) +CALLBACK(signer_filter, bool, + void *n, enumerator_t *orig, va_list args) { - *algo = (*entry)->algo; - *plugin_name = (*entry)->plugin_name; - return TRUE; + entry_t *entry; + integrity_algorithm_t *algo; + const char **plugin_name; + + VA_ARGS_VGET(args, algo, plugin_name); + + if (orig->enumerate(orig, &entry)) + { + *algo = entry->algo; + *plugin_name = entry->plugin_name; + return TRUE; + } + return FALSE; } METHOD(crypto_factory_t, create_signer_enumerator, enumerator_t*, @@ -887,15 +909,22 @@ METHOD(crypto_factory_t, create_signer_enumerator, enumerator_t*, return create_enumerator(this, this->signers, signer_filter); } -/** - * Filter function to enumerate algorithm, not entry - */ -static bool hasher_filter(void *n, entry_t **entry, hash_algorithm_t *algo, - void *i2, const char **plugin_name) +CALLBACK(hasher_filter, bool, + void *n, enumerator_t *orig, va_list args) { - *algo = (*entry)->algo; - *plugin_name = (*entry)->plugin_name; - return TRUE; + entry_t *entry; + hash_algorithm_t *algo; + const char **plugin_name; + + VA_ARGS_VGET(args, algo, plugin_name); + + if (orig->enumerate(orig, &entry)) + { + *algo = entry->algo; + *plugin_name = entry->plugin_name; + return TRUE; + } + return FALSE; } METHOD(crypto_factory_t, create_hasher_enumerator, enumerator_t*, @@ -904,15 +933,22 @@ METHOD(crypto_factory_t, create_hasher_enumerator, enumerator_t*, return create_enumerator(this, this->hashers, hasher_filter); } -/** - * Filter function to enumerate algorithm, not entry - */ -static bool prf_filter(void *n, entry_t **entry, pseudo_random_function_t *algo, - void *i2, const char **plugin_name) +CALLBACK(prf_filter, bool, + void *n, enumerator_t *orig, va_list args) { - *algo = (*entry)->algo; - *plugin_name = (*entry)->plugin_name; - return TRUE; + entry_t *entry; + pseudo_random_function_t *algo; + const char **plugin_name; + + VA_ARGS_VGET(args, algo, plugin_name); + + if (orig->enumerate(orig, &entry)) + { + *algo = entry->algo; + *plugin_name = entry->plugin_name; + return TRUE; + } + return FALSE; } METHOD(crypto_factory_t, create_prf_enumerator, enumerator_t*, @@ -921,15 +957,22 @@ METHOD(crypto_factory_t, create_prf_enumerator, enumerator_t*, return create_enumerator(this, this->prfs, prf_filter); } -/** - * Filter function to enumerate algorithm, not entry - */ -static bool xof_filter(void *n, entry_t **entry, ext_out_function_t *algo, - void *i2, const char **plugin_name) +CALLBACK(xof_filter, bool, + void *n, enumerator_t *orig, va_list args) { - *algo = (*entry)->algo; - *plugin_name = (*entry)->plugin_name; - return TRUE; + entry_t *entry; + ext_out_function_t *algo; + const char **plugin_name; + + VA_ARGS_VGET(args, algo, plugin_name); + + if (orig->enumerate(orig, &entry)) + { + *algo = entry->algo; + *plugin_name = entry->plugin_name; + return TRUE; + } + return FALSE; } METHOD(crypto_factory_t, create_xof_enumerator, enumerator_t*, @@ -938,15 +981,22 @@ METHOD(crypto_factory_t, create_xof_enumerator, enumerator_t*, return create_enumerator(this, this->xofs, xof_filter); } -/** - * Filter function to enumerate group, not entry - */ -static bool dh_filter(void *n, entry_t **entry, diffie_hellman_group_t *group, - void *i2, const char **plugin_name) +CALLBACK(dh_filter, bool, + void *n, enumerator_t *orig, va_list args) { - *group = (*entry)->algo; - *plugin_name = (*entry)->plugin_name; - return TRUE; + entry_t *entry; + diffie_hellman_group_t *algo; + const char **plugin_name; + + VA_ARGS_VGET(args, algo, plugin_name); + + if (orig->enumerate(orig, &entry)) + { + *algo = entry->algo; + *plugin_name = entry->plugin_name; + return TRUE; + } + return FALSE; } METHOD(crypto_factory_t, create_dh_enumerator, enumerator_t*, @@ -955,15 +1005,22 @@ METHOD(crypto_factory_t, create_dh_enumerator, enumerator_t*, return create_enumerator(this, this->dhs, dh_filter); } -/** - * Filter function to enumerate strength, not entry - */ -static bool rng_filter(void *n, entry_t **entry, rng_quality_t *quality, - void *i2, const char **plugin_name) +CALLBACK(rng_filter, bool, + void *n, enumerator_t *orig, va_list args) { - *quality = (*entry)->algo; - *plugin_name = (*entry)->plugin_name; - return TRUE; + entry_t *entry; + rng_quality_t *algo; + const char **plugin_name; + + VA_ARGS_VGET(args, algo, plugin_name); + + if (orig->enumerate(orig, &entry)) + { + *algo = entry->algo; + *plugin_name = entry->plugin_name; + return TRUE; + } + return FALSE; } METHOD(crypto_factory_t, create_rng_enumerator, enumerator_t*, @@ -972,13 +1029,20 @@ METHOD(crypto_factory_t, create_rng_enumerator, enumerator_t*, return create_enumerator(this, this->rngs, rng_filter); } -/** - * Filter function to enumerate plugin name, not entry - */ -static bool nonce_gen_filter(void *n, entry_t **entry, const char **plugin_name) +CALLBACK(nonce_gen_filter, bool, + void *n, enumerator_t *orig, va_list args) { - *plugin_name = (*entry)->plugin_name; - return TRUE; + entry_t *entry; + const char **plugin_name; + + VA_ARGS_VGET(args, plugin_name); + + if (orig->enumerate(orig, &entry)) + { + *plugin_name = entry->plugin_name; + return TRUE; + } + return FALSE; } METHOD(crypto_factory_t, create_nonce_gen_enumerator, enumerator_t*, @@ -1026,9 +1090,14 @@ typedef struct { } verify_enumerator_t; METHOD(enumerator_t, verify_enumerate, bool, - verify_enumerator_t *this, u_int *alg, const char **plugin, bool *valid) + verify_enumerator_t *this, va_list args) { + const char **plugin; entry_t *entry; + u_int *alg; + bool *valid; + + VA_ARGS_VGET(args, alg, plugin, valid); if (!this->inner->enumerate(this->inner, &entry)) { @@ -1123,7 +1192,8 @@ METHOD(crypto_factory_t, create_verify_enumerator, enumerator_t*, } INIT(enumerator, .public = { - .enumerate = (void*)_verify_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _verify_enumerate, .destroy = _verify_destroy, }, .inner = inner, diff --git a/src/libstrongswan/crypto/hashers/hash_algorithm_set.c b/src/libstrongswan/crypto/hashers/hash_algorithm_set.c index 93b67cb13..4087fe1d9 100644 --- a/src/libstrongswan/crypto/hashers/hash_algorithm_set.c +++ b/src/libstrongswan/crypto/hashers/hash_algorithm_set.c @@ -71,17 +71,26 @@ METHOD(hash_algorithm_set_t, count, int, return array_count(this->algorithms); } -static bool hash_filter(void *data, void **in, hash_algorithm_t *out) +CALLBACK(hash_filter, bool, + void *data, enumerator_t *orig, va_list args) { - *out = **(hash_algorithm_t**)in; - return TRUE; + hash_algorithm_t *algo, *out; + + VA_ARGS_VGET(args, out); + + if (orig->enumerate(orig, &algo)) + { + *out = *algo; + return TRUE; + } + return FALSE; } METHOD(hash_algorithm_set_t, create_enumerator, enumerator_t*, private_hash_algorithm_set_t *this) { return enumerator_create_filter(array_create_enumerator(this->algorithms), - (void*)hash_filter, NULL, NULL); + hash_filter, NULL, NULL); } METHOD(hash_algorithm_set_t, destroy, void, diff --git a/src/libstrongswan/library.c b/src/libstrongswan/library.c index 4f79dcc5b..7944b9356 100644 --- a/src/libstrongswan/library.c +++ b/src/libstrongswan/library.c @@ -94,6 +94,13 @@ void library_add_namespace(char *ns) } /** + * Register plugins if built statically + */ +#ifdef STATIC_PLUGIN_CONSTRUCTORS +#include "plugin_constructors.c" +#endif + +/** * library instance */ library_t *lib = NULL; @@ -241,6 +248,8 @@ static bool equals(char *a, char *b) */ #define MEMWIPE_WIPE_WORDS 16 +#ifndef NO_CHECK_MEMWIPE + /** * Write magic to memory, and try to clear it with memwipe() */ @@ -281,6 +290,8 @@ static bool check_memwipe() return TRUE; } +#endif + /* * see header file */ @@ -387,10 +398,12 @@ bool library_init(char *settings, const char *namespace) this->public.streams = stream_manager_create(); this->public.plugins = plugin_loader_create(); +#ifndef NO_CHECK_MEMWIPE if (!check_memwipe()) { return FALSE; } +#endif if (lib->settings->get_bool(lib->settings, "%s.integrity_test", FALSE, lib->ns)) diff --git a/src/libstrongswan/math/libnttfft/Makefile.in b/src/libstrongswan/math/libnttfft/Makefile.in index ff41f9be4..93bd93508 100644 --- a/src/libstrongswan/math/libnttfft/Makefile.in +++ b/src/libstrongswan/math/libnttfft/Makefile.in @@ -349,6 +349,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -371,6 +372,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/math/libnttfft/tests/Makefile.in b/src/libstrongswan/math/libnttfft/tests/Makefile.in index 4f854494b..80ecd3ea7 100644 --- a/src/libstrongswan/math/libnttfft/tests/Makefile.in +++ b/src/libstrongswan/math/libnttfft/tests/Makefile.in @@ -353,6 +353,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -375,6 +376,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/networking/tun_device.c b/src/libstrongswan/networking/tun_device.c index de925553f..86951f1e7 100644 --- a/src/libstrongswan/networking/tun_device.c +++ b/src/libstrongswan/networking/tun_device.c @@ -21,7 +21,16 @@ #include <utils/debug.h> #include <threading/thread.h> -#if !defined(__APPLE__) && !defined(__linux__) && !defined(HAVE_NET_IF_TUN_H) +#if defined(__APPLE__) +#include "TargetConditionals.h" +#if !TARGET_OS_OSX +#define TUN_DEVICE_NOT_SUPPORTED +#endif +#elif !defined(__linux__) && !defined(HAVE_NET_IF_TUN_H) +#define TUN_DEVICE_NOT_SUPPORTED +#endif + +#ifdef TUN_DEVICE_NOT_SUPPORTED tun_device_t *tun_device_create(const char *name_tmpl) { @@ -481,10 +490,25 @@ static bool init_tun(private_tun_device_t *this, const char *name_tmpl) strncpy(this->if_name, ifr.ifr_name, IFNAMSIZ); return TRUE; -#else /* !IFF_TUN */ +#elif defined(__FreeBSD__) + + if (name_tmpl) + { + DBG1(DBG_LIB, "arbitrary naming of TUN devices is not supported"); + } + + this->tunfd = open("/dev/tun", O_RDWR); + if (this->tunfd < 0) + { + DBG1(DBG_LIB, "failed to open /dev/tun: %s", strerror(errno)); + return FALSE; + } + fdevname_r(this->tunfd, this->if_name, IFNAMSIZ); + return TRUE; + +#else /* !__FreeBSD__ */ - /* this works on FreeBSD and might also work on Linux with older TUN - * driver versions (no IFF_TUN) */ + /* this might work on Linux with older TUN driver versions (no IFF_TUN) */ char devname[IFNAMSIZ]; /* the same process is allowed to open a device again, but that's not what * we want (unless we previously closed a device, which we don't know at diff --git a/src/libstrongswan/plugins/acert/Makefile.in b/src/libstrongswan/plugins/acert/Makefile.in index ee69a8914..1dcc0489e 100644 --- a/src/libstrongswan/plugins/acert/Makefile.in +++ b/src/libstrongswan/plugins/acert/Makefile.in @@ -356,6 +356,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -378,6 +379,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/aes/Makefile.in b/src/libstrongswan/plugins/aes/Makefile.in index 0a8046b67..2b16ae7d2 100644 --- a/src/libstrongswan/plugins/aes/Makefile.in +++ b/src/libstrongswan/plugins/aes/Makefile.in @@ -355,6 +355,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -377,6 +378,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/aesni/Makefile.in b/src/libstrongswan/plugins/aesni/Makefile.in index ceb86762e..d32e7f55c 100644 --- a/src/libstrongswan/plugins/aesni/Makefile.in +++ b/src/libstrongswan/plugins/aesni/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/af_alg/Makefile.in b/src/libstrongswan/plugins/af_alg/Makefile.in index bad31cace..e93140279 100644 --- a/src/libstrongswan/plugins/af_alg/Makefile.in +++ b/src/libstrongswan/plugins/af_alg/Makefile.in @@ -359,6 +359,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -381,6 +382,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/af_alg/af_alg_ops.c b/src/libstrongswan/plugins/af_alg/af_alg_ops.c index 7e129300f..2fa68723d 100644 --- a/src/libstrongswan/plugins/af_alg/af_alg_ops.c +++ b/src/libstrongswan/plugins/af_alg/af_alg_ops.c @@ -107,7 +107,7 @@ METHOD(af_alg_ops_t, hash, bool, return TRUE; } -METHOD(af_alg_ops_t, crypt, bool, +METHOD(af_alg_ops_t, crypt_, bool, private_af_alg_ops_t *this, uint32_t type, chunk_t iv, chunk_t data, char *out) { @@ -224,7 +224,7 @@ af_alg_ops_t *af_alg_ops_create(char *type, char *alg) .public = { .hash = _hash, .reset = _reset, - .crypt = _crypt, + .crypt = _crypt_, .set_key = _set_key, .destroy = _destroy, }, diff --git a/src/libstrongswan/plugins/agent/Makefile.in b/src/libstrongswan/plugins/agent/Makefile.in index cd9036b68..a4e7e2931 100644 --- a/src/libstrongswan/plugins/agent/Makefile.in +++ b/src/libstrongswan/plugins/agent/Makefile.in @@ -357,6 +357,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -379,6 +380,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/bliss/Makefile.in b/src/libstrongswan/plugins/bliss/Makefile.in index 918a018f9..a6caf7bdf 100644 --- a/src/libstrongswan/plugins/bliss/Makefile.in +++ b/src/libstrongswan/plugins/bliss/Makefile.in @@ -380,6 +380,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -402,6 +403,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/bliss/tests/Makefile.in b/src/libstrongswan/plugins/bliss/tests/Makefile.in index 1964f199f..5dbaf9b9b 100644 --- a/src/libstrongswan/plugins/bliss/tests/Makefile.in +++ b/src/libstrongswan/plugins/bliss/tests/Makefile.in @@ -359,6 +359,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -381,6 +382,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/blowfish/Makefile.in b/src/libstrongswan/plugins/blowfish/Makefile.in index c2bc5acd9..0876475d0 100644 --- a/src/libstrongswan/plugins/blowfish/Makefile.in +++ b/src/libstrongswan/plugins/blowfish/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/ccm/Makefile.in b/src/libstrongswan/plugins/ccm/Makefile.in index f0065d0b6..5f768ec8c 100644 --- a/src/libstrongswan/plugins/ccm/Makefile.in +++ b/src/libstrongswan/plugins/ccm/Makefile.in @@ -355,6 +355,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -377,6 +378,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/chapoly/Makefile.in b/src/libstrongswan/plugins/chapoly/Makefile.in index 3e1d634c2..12ad6f1b8 100644 --- a/src/libstrongswan/plugins/chapoly/Makefile.in +++ b/src/libstrongswan/plugins/chapoly/Makefile.in @@ -370,6 +370,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -392,6 +393,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/cmac/Makefile.in b/src/libstrongswan/plugins/cmac/Makefile.in index 77d68bd5d..c6bb24a91 100644 --- a/src/libstrongswan/plugins/cmac/Makefile.in +++ b/src/libstrongswan/plugins/cmac/Makefile.in @@ -355,6 +355,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -377,6 +378,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/constraints/Makefile.in b/src/libstrongswan/plugins/constraints/Makefile.in index edd519f12..aa2fd790f 100644 --- a/src/libstrongswan/plugins/constraints/Makefile.in +++ b/src/libstrongswan/plugins/constraints/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/ctr/Makefile.in b/src/libstrongswan/plugins/ctr/Makefile.in index a9d0b2e13..d112676e7 100644 --- a/src/libstrongswan/plugins/ctr/Makefile.in +++ b/src/libstrongswan/plugins/ctr/Makefile.in @@ -355,6 +355,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -377,6 +378,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/curl/Makefile.in b/src/libstrongswan/plugins/curl/Makefile.in index 996d25885..2aedb2f75 100644 --- a/src/libstrongswan/plugins/curl/Makefile.in +++ b/src/libstrongswan/plugins/curl/Makefile.in @@ -355,6 +355,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -377,6 +378,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/curve25519/Makefile.in b/src/libstrongswan/plugins/curve25519/Makefile.in index 1fa2b171b..616f3d83b 100644 --- a/src/libstrongswan/plugins/curve25519/Makefile.in +++ b/src/libstrongswan/plugins/curve25519/Makefile.in @@ -362,6 +362,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -384,6 +385,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/des/Makefile.in b/src/libstrongswan/plugins/des/Makefile.in index b6cedd8e8..c3f3775d2 100644 --- a/src/libstrongswan/plugins/des/Makefile.in +++ b/src/libstrongswan/plugins/des/Makefile.in @@ -355,6 +355,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -377,6 +378,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/dnskey/Makefile.in b/src/libstrongswan/plugins/dnskey/Makefile.in index 347c69739..26c69e239 100644 --- a/src/libstrongswan/plugins/dnskey/Makefile.in +++ b/src/libstrongswan/plugins/dnskey/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/files/Makefile.in b/src/libstrongswan/plugins/files/Makefile.in index 10cbc6e76..d8c7daec4 100644 --- a/src/libstrongswan/plugins/files/Makefile.in +++ b/src/libstrongswan/plugins/files/Makefile.in @@ -356,6 +356,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -378,6 +379,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/fips_prf/Makefile.in b/src/libstrongswan/plugins/fips_prf/Makefile.in index 8b5e162ac..45934d79a 100644 --- a/src/libstrongswan/plugins/fips_prf/Makefile.in +++ b/src/libstrongswan/plugins/fips_prf/Makefile.in @@ -357,6 +357,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -379,6 +380,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/gcm/Makefile.in b/src/libstrongswan/plugins/gcm/Makefile.in index 0f3878fb5..5d6c1a4e9 100644 --- a/src/libstrongswan/plugins/gcm/Makefile.in +++ b/src/libstrongswan/plugins/gcm/Makefile.in @@ -355,6 +355,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -377,6 +378,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/gcrypt/Makefile.in b/src/libstrongswan/plugins/gcrypt/Makefile.in index ef246f99a..26930dced 100644 --- a/src/libstrongswan/plugins/gcrypt/Makefile.in +++ b/src/libstrongswan/plugins/gcrypt/Makefile.in @@ -359,6 +359,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -381,6 +382,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/gmp/Makefile.in b/src/libstrongswan/plugins/gmp/Makefile.in index de8f8fe7a..2fcdce774 100644 --- a/src/libstrongswan/plugins/gmp/Makefile.in +++ b/src/libstrongswan/plugins/gmp/Makefile.in @@ -356,6 +356,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -378,6 +379,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c index 2b2c7f249..32a72ac96 100644 --- a/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c +++ b/src/libstrongswan/plugins/gmp/gmp_rsa_public_key.c @@ -475,7 +475,7 @@ gmp_rsa_public_key_t *gmp_rsa_public_key_load(key_type_t type, va_list args) } break; } - if (!e.ptr || !n.ptr) + if (!e.len || !n.len || (n.ptr[n.len-1] & 0x01) == 0) { return NULL; } @@ -506,5 +506,10 @@ gmp_rsa_public_key_t *gmp_rsa_public_key_load(key_type_t type, va_list args) this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE; + if (!mpz_sgn(this->e)) + { + destroy(this); + return NULL; + } return &this->public; } diff --git a/src/libstrongswan/plugins/hmac/Makefile.in b/src/libstrongswan/plugins/hmac/Makefile.in index 3a87fcc02..aa640156a 100644 --- a/src/libstrongswan/plugins/hmac/Makefile.in +++ b/src/libstrongswan/plugins/hmac/Makefile.in @@ -355,6 +355,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -377,6 +378,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/keychain/Makefile.in b/src/libstrongswan/plugins/keychain/Makefile.in index d113d9ee2..c9e4e40e0 100644 --- a/src/libstrongswan/plugins/keychain/Makefile.in +++ b/src/libstrongswan/plugins/keychain/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/ldap/Makefile.in b/src/libstrongswan/plugins/ldap/Makefile.in index 2005aafb9..1f4d44706 100644 --- a/src/libstrongswan/plugins/ldap/Makefile.in +++ b/src/libstrongswan/plugins/ldap/Makefile.in @@ -355,6 +355,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -377,6 +378,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/md4/Makefile.in b/src/libstrongswan/plugins/md4/Makefile.in index dad532715..eb9426ccc 100644 --- a/src/libstrongswan/plugins/md4/Makefile.in +++ b/src/libstrongswan/plugins/md4/Makefile.in @@ -355,6 +355,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -377,6 +378,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/md5/Makefile.in b/src/libstrongswan/plugins/md5/Makefile.in index 5f1ced2f3..eaafd9fe5 100644 --- a/src/libstrongswan/plugins/md5/Makefile.in +++ b/src/libstrongswan/plugins/md5/Makefile.in @@ -355,6 +355,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -377,6 +378,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/mgf1/Makefile.in b/src/libstrongswan/plugins/mgf1/Makefile.in index 42904a763..991c5421e 100644 --- a/src/libstrongswan/plugins/mgf1/Makefile.in +++ b/src/libstrongswan/plugins/mgf1/Makefile.in @@ -355,6 +355,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -377,6 +378,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/mysql/Makefile.in b/src/libstrongswan/plugins/mysql/Makefile.in index b61755716..d549f2e71 100644 --- a/src/libstrongswan/plugins/mysql/Makefile.in +++ b/src/libstrongswan/plugins/mysql/Makefile.in @@ -357,6 +357,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -379,6 +380,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/mysql/mysql_database.c b/src/libstrongswan/plugins/mysql/mysql_database.c index 871cc59a0..211eba704 100644 --- a/src/libstrongswan/plugins/mysql/mysql_database.c +++ b/src/libstrongswan/plugins/mysql/mysql_database.c @@ -403,10 +403,8 @@ typedef struct { unsigned long *length; } mysql_enumerator_t; -/** - * create a mysql enumerator - */ -static void mysql_enumerator_destroy(mysql_enumerator_t *this) +METHOD(enumerator_t, mysql_enumerator_destroy, void, + mysql_enumerator_t *this) { int columns, i; @@ -434,13 +432,10 @@ static void mysql_enumerator_destroy(mysql_enumerator_t *this) free(this); } -/** - * Implementation of database.query().enumerate - */ -static bool mysql_enumerator_enumerate(mysql_enumerator_t *this, ...) +METHOD(enumerator_t, mysql_enumerator_enumerate, bool, + mysql_enumerator_t *this, va_list args) { int i, columns; - va_list args; columns = mysql_stmt_field_count(this->stmt); @@ -477,7 +472,6 @@ static bool mysql_enumerator_enumerate(mysql_enumerator_t *this, ...) return FALSE; } - va_start(args, this); for (i = 0; i < columns; i++) { switch (this->bind[i].buffer_type) @@ -526,7 +520,6 @@ static bool mysql_enumerator_enumerate(mysql_enumerator_t *this, ...) break; } } - va_end(args); return TRUE; } @@ -552,9 +545,9 @@ METHOD(database_t, query, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)mysql_enumerator_enumerate, - .destroy = (void*)mysql_enumerator_destroy, - + .enumerate = enumerator_enumerate_default, + .venumerate = _mysql_enumerator_enumerate, + .destroy = _mysql_enumerator_destroy, }, .db = this, .stmt = stmt, diff --git a/src/libstrongswan/plugins/newhope/Makefile.in b/src/libstrongswan/plugins/newhope/Makefile.in index 24857b3d6..a884b30b6 100644 --- a/src/libstrongswan/plugins/newhope/Makefile.in +++ b/src/libstrongswan/plugins/newhope/Makefile.in @@ -364,6 +364,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -386,6 +387,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/newhope/tests/Makefile.in b/src/libstrongswan/plugins/newhope/tests/Makefile.in index 884a2eb6b..80fcf4dc5 100644 --- a/src/libstrongswan/plugins/newhope/tests/Makefile.in +++ b/src/libstrongswan/plugins/newhope/tests/Makefile.in @@ -356,6 +356,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -378,6 +379,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/nonce/Makefile.in b/src/libstrongswan/plugins/nonce/Makefile.in index 8e04841cf..783eaf436 100644 --- a/src/libstrongswan/plugins/nonce/Makefile.in +++ b/src/libstrongswan/plugins/nonce/Makefile.in @@ -356,6 +356,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -378,6 +379,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/ntru/Makefile.in b/src/libstrongswan/plugins/ntru/Makefile.in index c47f90bac..41ec4cec4 100644 --- a/src/libstrongswan/plugins/ntru/Makefile.in +++ b/src/libstrongswan/plugins/ntru/Makefile.in @@ -357,6 +357,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -379,6 +380,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/openssl/Makefile.in b/src/libstrongswan/plugins/openssl/Makefile.in index 798ee5f26..9c0523652 100644 --- a/src/libstrongswan/plugins/openssl/Makefile.in +++ b/src/libstrongswan/plugins/openssl/Makefile.in @@ -365,6 +365,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -387,6 +388,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/openssl/openssl_crl.c b/src/libstrongswan/plugins/openssl/openssl_crl.c index 20bac6be5..61cf3e884 100644 --- a/src/libstrongswan/plugins/openssl/openssl_crl.c +++ b/src/libstrongswan/plugins/openssl/openssl_crl.c @@ -142,8 +142,14 @@ typedef struct { METHOD(enumerator_t, crl_enumerate, bool, - crl_enumerator_t *this, chunk_t *serial, time_t *date, crl_reason_t *reason) + crl_enumerator_t *this, va_list args) { + crl_reason_t *reason; + chunk_t *serial; + time_t *date; + + VA_ARGS_VGET(args, serial, date, reason); + if (this->i < this->num) { X509_REVOKED *revoked; @@ -188,7 +194,8 @@ METHOD(crl_t, create_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_crl_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _crl_enumerate, .destroy = (void*)free, }, .stack = X509_CRL_get_REVOKED(this->crl), diff --git a/src/libstrongswan/plugins/openssl/openssl_pkcs7.c b/src/libstrongswan/plugins/openssl/openssl_pkcs7.c index 5752d96de..83ac8df5b 100644 --- a/src/libstrongswan/plugins/openssl/openssl_pkcs7.c +++ b/src/libstrongswan/plugins/openssl/openssl_pkcs7.c @@ -136,8 +136,12 @@ METHOD(enumerator_t, cert_destroy, void, } METHOD(enumerator_t, cert_enumerate, bool, - cert_enumerator_t *this, certificate_t **out) + cert_enumerator_t *this, va_list args) { + certificate_t **out; + + VA_ARGS_VGET(args, out); + if (!this->certs) { return FALSE; @@ -176,7 +180,8 @@ METHOD(pkcs7_t, create_cert_enumerator, enumerator_t*, { INIT(enumerator, .public = { - .enumerate = (void*)_cert_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _cert_enumerate, .destroy = _cert_destroy, }, .certs = CMS_get1_certs(this->cms), @@ -320,8 +325,12 @@ static bool verify_digest(CMS_ContentInfo *cms, CMS_SignerInfo *si, int hash_oid } METHOD(enumerator_t, signature_enumerate, bool, - signature_enumerator_t *this, auth_cfg_t **out) + signature_enumerator_t *this, va_list args) { + auth_cfg_t **out; + + VA_ARGS_VGET(args, out); + if (!this->signers) { return FALSE; @@ -382,7 +391,8 @@ METHOD(container_t, create_signature_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_signature_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _signature_enumerate, .destroy = _signature_destroy, }, .cms = this->cms, diff --git a/src/libstrongswan/plugins/padlock/Makefile.in b/src/libstrongswan/plugins/padlock/Makefile.in index 1fe0e7bb0..b71749589 100644 --- a/src/libstrongswan/plugins/padlock/Makefile.in +++ b/src/libstrongswan/plugins/padlock/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/pem/Makefile.in b/src/libstrongswan/plugins/pem/Makefile.in index e3d7c776a..8ff3dd021 100644 --- a/src/libstrongswan/plugins/pem/Makefile.in +++ b/src/libstrongswan/plugins/pem/Makefile.in @@ -356,6 +356,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -378,6 +379,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/pem/pem_builder.c b/src/libstrongswan/plugins/pem/pem_builder.c index 719a2a69e..ec90fb084 100644 --- a/src/libstrongswan/plugins/pem/pem_builder.c +++ b/src/libstrongswan/plugins/pem/pem_builder.c @@ -61,7 +61,7 @@ static bool find_boundary(char* tag, chunk_t *line) if (!present("-----", line) || !present(tag, line) || - *line->ptr != ' ') + !line->len || *line->ptr != ' ') { return FALSE; } @@ -250,7 +250,7 @@ static status_t pem_to_bin(chunk_t *blob, bool *pgp) { continue; } - if (match("Proc-Type", &name) && *value.ptr == '4') + if (match("Proc-Type", &name) && value.len && *value.ptr == '4') { encrypted = TRUE; } @@ -306,7 +306,7 @@ static status_t pem_to_bin(chunk_t *blob, bool *pgp) } /* check for PGP armor checksum */ - if (*data.ptr == '=') + if (data.len && *data.ptr == '=') { *pgp = TRUE; data.ptr++; diff --git a/src/libstrongswan/plugins/pgp/Makefile.in b/src/libstrongswan/plugins/pgp/Makefile.in index 552340230..3ffafd020 100644 --- a/src/libstrongswan/plugins/pgp/Makefile.in +++ b/src/libstrongswan/plugins/pgp/Makefile.in @@ -356,6 +356,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -378,6 +379,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/pkcs1/Makefile.in b/src/libstrongswan/plugins/pkcs1/Makefile.in index 3cdc73102..cbf227680 100644 --- a/src/libstrongswan/plugins/pkcs1/Makefile.in +++ b/src/libstrongswan/plugins/pkcs1/Makefile.in @@ -357,6 +357,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -379,6 +380,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/pkcs11/Makefile.in b/src/libstrongswan/plugins/pkcs11/Makefile.in index f4fffd3fa..ca7b5a8a9 100644 --- a/src/libstrongswan/plugins/pkcs11/Makefile.in +++ b/src/libstrongswan/plugins/pkcs11/Makefile.in @@ -360,6 +360,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -382,6 +383,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c b/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c index e65f3a06b..b1575540d 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_creds.c @@ -153,30 +153,32 @@ static bool load_certificates(private_pkcs11_creds_t *this) return TRUE; } -/** - * filter function for certs enumerator - */ -static bool certs_filter(identification_t *id, - certificate_t **in, certificate_t **out) +CALLBACK(certs_filter, bool, + identification_t *id, enumerator_t *orig, va_list args) { public_key_t *public; - certificate_t *cert = *in; + certificate_t *cert, **out; - if (id == NULL || cert->has_subject(cert, id)) - { - *out = *in; - return TRUE; - } - public = cert->get_public_key(cert); - if (public) + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, &cert)) { - if (public->has_fingerprint(public, id->get_encoding(id))) + if (id == NULL || cert->has_subject(cert, id)) { - public->destroy(public); - *out = *in; + *out = cert; return TRUE; } - public->destroy(public); + public = cert->get_public_key(cert); + if (public) + { + if (public->has_fingerprint(public, id->get_encoding(id))) + { + public->destroy(public); + *out = cert; + return TRUE; + } + public->destroy(public); + } } return FALSE; } @@ -199,7 +201,7 @@ METHOD(credential_set_t, create_cert_enumerator, enumerator_t*, { inner = this->untrusted->create_enumerator(this->untrusted); } - return enumerator_create_filter(inner, (void*)certs_filter, id, NULL); + return enumerator_create_filter(inner, certs_filter, id, NULL); } METHOD(pkcs11_creds_t, get_library, pkcs11_library_t*, diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c index dc8a1f17a..89ae1969e 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c @@ -719,12 +719,14 @@ static bool get_attributes(object_enumerator_t *this, CK_OBJECT_HANDLE object) } METHOD(enumerator_t, object_enumerate, bool, - object_enumerator_t *this, CK_OBJECT_HANDLE *out) + object_enumerator_t *this, va_list args) { - CK_OBJECT_HANDLE object; + CK_OBJECT_HANDLE object, *out; CK_ULONG found; CK_RV rv; + VA_ARGS_VGET(args, out); + if (!this->object) { rv = this->lib->f->C_FindObjects(this->session, &object, 1, &found); @@ -786,7 +788,8 @@ METHOD(pkcs11_library_t, create_object_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_object_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _object_enumerate, .destroy = _object_destroy, }, .session = session, @@ -806,7 +809,8 @@ METHOD(pkcs11_library_t, create_object_attr_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_object_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _object_enumerate, .destroy = _object_destroy, }, .session = session, @@ -838,11 +842,14 @@ typedef struct { } mechanism_enumerator_t; METHOD(enumerator_t, enumerate_mech, bool, - mechanism_enumerator_t *this, CK_MECHANISM_TYPE* type, - CK_MECHANISM_INFO *info) + mechanism_enumerator_t *this, va_list args) { + CK_MECHANISM_INFO *info; + CK_MECHANISM_TYPE *type; CK_RV rv; + VA_ARGS_VGET(args, type, info); + if (this->current >= this->count) { return FALSE; @@ -876,7 +883,8 @@ METHOD(pkcs11_library_t, create_mechanism_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_enumerate_mech, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_mech, .destroy = _destroy_mech, }, .lib = &this->public, diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c index 96c4a180d..31bcb0d25 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c @@ -265,8 +265,13 @@ typedef struct { } token_enumerator_t; METHOD(enumerator_t, enumerate_token, bool, - token_enumerator_t *this, pkcs11_library_t **out, CK_SLOT_ID *slot) + token_enumerator_t *this, va_list args) { + pkcs11_library_t **out; + CK_SLOT_ID *slot; + + VA_ARGS_VGET(args, out, slot); + if (this->current >= this->count) { free(this->slots); @@ -301,7 +306,8 @@ METHOD(pkcs11_manager_t, create_token_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_enumerate_token, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate_token, .destroy = _destroy_token, }, .inner = this->libs->create_enumerator(this->libs), diff --git a/src/libstrongswan/plugins/pkcs12/Makefile.in b/src/libstrongswan/plugins/pkcs12/Makefile.in index 72996f164..73f15d26c 100644 --- a/src/libstrongswan/plugins/pkcs12/Makefile.in +++ b/src/libstrongswan/plugins/pkcs12/Makefile.in @@ -357,6 +357,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -379,6 +380,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/pkcs7/Makefile.in b/src/libstrongswan/plugins/pkcs7/Makefile.in index 6224b1b92..3bf44de30 100644 --- a/src/libstrongswan/plugins/pkcs7/Makefile.in +++ b/src/libstrongswan/plugins/pkcs7/Makefile.in @@ -359,6 +359,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -381,6 +382,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c b/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c index d224ef3aa..413c3fff5 100644 --- a/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c +++ b/src/libstrongswan/plugins/pkcs7/pkcs7_signed_data.c @@ -179,7 +179,7 @@ typedef struct { } signature_enumerator_t; METHOD(enumerator_t, enumerate, bool, - signature_enumerator_t *this, auth_cfg_t **out) + signature_enumerator_t *this, va_list args) { signerinfo_t *info; signature_scheme_t scheme; @@ -187,11 +187,13 @@ METHOD(enumerator_t, enumerate, bool, enumerator_t *enumerator; certificate_t *cert; public_key_t *key; - auth_cfg_t *auth; + auth_cfg_t *auth, **out; chunk_t chunk, hash, content; hasher_t *hasher; bool valid; + VA_ARGS_VGET(args, out); + while (this->inner->enumerate(this->inner, &info)) { /* clean up previous round */ @@ -300,7 +302,8 @@ METHOD(container_t, create_signature_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _enumerate, .destroy = _enumerator_destroy, }, .inner = this->signerinfos->create_enumerator(this->signerinfos), diff --git a/src/libstrongswan/plugins/pkcs8/Makefile.in b/src/libstrongswan/plugins/pkcs8/Makefile.in index 475de08fb..2066d8792 100644 --- a/src/libstrongswan/plugins/pkcs8/Makefile.in +++ b/src/libstrongswan/plugins/pkcs8/Makefile.in @@ -356,6 +356,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -378,6 +379,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/plugin_constructors.py b/src/libstrongswan/plugins/plugin_constructors.py new file mode 100644 index 000000000..d9c40e383 --- /dev/null +++ b/src/libstrongswan/plugins/plugin_constructors.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +# +# Copyright (C) 2017 Tobias Brunner +# 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. + +import sys +from argparse import ArgumentParser + +def generate_output(plugins): + """Generate a source file containing plugin constructor registrations""" + print("/**") + print(" * Register plugin constructors for static libraries") + print(" * Created by {0}".format(__file__)) + print(" */") + print("") + print("#include <plugins/plugin.h>") + print("#include <plugins/plugin_loader.h>") + print("") + + for plugin in plugins: + print("plugin_t *{0}_plugin_create();".format(plugin.replace('-', '_'))) + + print("") + print("static void register_plugins() __attribute__ ((constructor));") + print("static void register_plugins()") + print("{") + + for plugin in plugins: + print(' plugin_constructor_register("{0}", {1}_plugin_create);'.format(plugin, plugin.replace('-', '_'))) + + print("}") + + print("") + print("static void unregister_plugins() __attribute__ ((destructor));") + print("static void unregister_plugins()") + print("{") + + for plugin in plugins: + print(' plugin_constructor_register("{0}", NULL);'.format(plugin)) + + print("}") + print("") + +parser = ArgumentParser(description = "Generate constructor registration for a list of plugins") +parser.add_argument('plugins', metavar="plugin", nargs="*", + help = "name of a plugin for which to generate constructor registration") + + +args = parser.parse_args() +generate_output(args.plugins); diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c index e4698fac0..42d443b7a 100644 --- a/src/libstrongswan/plugins/plugin_loader.c +++ b/src/libstrongswan/plugins/plugin_loader.c @@ -40,6 +40,13 @@ typedef struct registered_feature_t registered_feature_t; typedef struct provided_feature_t provided_feature_t; typedef struct plugin_entry_t plugin_entry_t; +#ifdef STATIC_PLUGIN_CONSTRUCTORS +/** + * Statically registered constructors + */ +static hashtable_t *plugin_constructors = NULL; +#endif + /** * private data of plugin_loader */ @@ -298,6 +305,46 @@ static plugin_t *static_features_create(const char *name, return &this->public; } +#ifdef STATIC_PLUGIN_CONSTRUCTORS +/* + * Described in header. + */ +void plugin_constructor_register(char *name, void *constructor) +{ + bool old = FALSE; + + if (lib && lib->leak_detective) + { + old = lib->leak_detective->set_state(lib->leak_detective, FALSE); + } + + if (!plugin_constructors) + { + chunk_hash_seed(); + plugin_constructors = hashtable_create(hashtable_hash_str, + hashtable_equals_str, 32); + } + if (constructor) + { + plugin_constructors->put(plugin_constructors, name, constructor); + } + else + { + plugin_constructors->remove(plugin_constructors, name); + if (!plugin_constructors->get_count(plugin_constructors)) + { + plugin_constructors->destroy(plugin_constructors); + plugin_constructors = NULL; + } + } + + if (lib && lib->leak_detective) + { + lib->leak_detective->set_state(lib->leak_detective, old); + } +} +#endif + /** * create a plugin * returns: NOT_FOUND, if the constructor was not found @@ -309,7 +356,7 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle, { char create[128]; plugin_t *plugin; - plugin_constructor_t constructor; + plugin_constructor_t constructor = NULL; if (snprintf(create, sizeof(create), "%s_plugin_create", name) >= sizeof(create)) @@ -317,8 +364,17 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle, return FAILED; } translate(create, "-", "_"); - constructor = dlsym(handle, create); - if (constructor == NULL) +#ifdef STATIC_PLUGIN_CONSTRUCTORS + if (plugin_constructors) + { + constructor = plugin_constructors->get(plugin_constructors, name); + } + if (!constructor) +#endif + { + constructor = dlsym(handle, create); + } + if (!constructor) { return NOT_FOUND; } @@ -409,34 +465,48 @@ static plugin_entry_t *load_plugin(private_plugin_loader_t *this, char *name, return entry; } -/** - * Convert enumerated provided_feature_t to plugin_feature_t - */ -static bool feature_filter(void *null, provided_feature_t **provided, - plugin_feature_t **feature) +CALLBACK(feature_filter, bool, + void *null, enumerator_t *orig, va_list args) { - *feature = (*provided)->feature; - return (*provided)->loaded; + provided_feature_t *provided; + plugin_feature_t **feature; + + VA_ARGS_VGET(args, feature); + + while (orig->enumerate(orig, &provided)) + { + if (provided->loaded) + { + *feature = provided->feature; + return TRUE; + } + } + return FALSE; } -/** - * Convert enumerated entries to plugin_t - */ -static bool plugin_filter(void *null, plugin_entry_t **entry, plugin_t **plugin, - void *in, linked_list_t **list) +CALLBACK(plugin_filter, bool, + void *null, enumerator_t *orig, va_list args) { - plugin_entry_t *this = *entry; + plugin_entry_t *entry; + linked_list_t **list; + plugin_t **plugin; + + VA_ARGS_VGET(args, plugin, list); - *plugin = this->plugin; - if (list) + if (orig->enumerate(orig, &entry)) { - enumerator_t *features; - features = enumerator_create_filter( - this->features->create_enumerator(this->features), - (void*)feature_filter, NULL, NULL); - *list = linked_list_create_from_enumerator(features); + *plugin = entry->plugin; + if (list) + { + enumerator_t *features; + features = enumerator_create_filter( + entry->features->create_enumerator(entry->features), + feature_filter, NULL, NULL); + *list = linked_list_create_from_enumerator(features); + } + return TRUE; } - return TRUE; + return FALSE; } METHOD(plugin_loader_t, create_plugin_enumerator, enumerator_t*, @@ -444,7 +514,7 @@ METHOD(plugin_loader_t, create_plugin_enumerator, enumerator_t*, { return enumerator_create_filter( this->plugins->create_enumerator(this->plugins), - (void*)plugin_filter, NULL, NULL); + plugin_filter, NULL, NULL); } METHOD(plugin_loader_t, has_feature, bool, @@ -536,18 +606,14 @@ static void load_provided(private_plugin_loader_t *this, provided_feature_t *provided, int level); -/** - * Used to find a loaded feature - */ -static bool is_feature_loaded(provided_feature_t *item) +CALLBACK(is_feature_loaded, bool, + provided_feature_t *item, va_list args) { return item->loaded; } -/** - * Used to find a loadable feature - */ -static bool is_feature_loadable(provided_feature_t *item) +CALLBACK(is_feature_loadable, bool, + provided_feature_t *item, va_list args) { return !item->loading && !item->loaded && !item->failed; } @@ -560,8 +626,7 @@ static bool loaded_feature_matches(registered_feature_t *a, { if (plugin_feature_matches(a->feature, b->feature)) { - return b->plugins->find_first(b->plugins, (void*)is_feature_loaded, - NULL) == SUCCESS; + return b->plugins->find_first(b->plugins, is_feature_loaded, NULL); } return FALSE; } @@ -574,8 +639,7 @@ static bool loadable_feature_equals(registered_feature_t *a, { if (plugin_feature_equals(a->feature, b->feature)) { - return b->plugins->find_first(b->plugins, (void*)is_feature_loadable, - NULL) == SUCCESS; + return b->plugins->find_first(b->plugins, is_feature_loadable, NULL); } return FALSE; } @@ -588,8 +652,7 @@ static bool loadable_feature_matches(registered_feature_t *a, { if (plugin_feature_matches(a->feature, b->feature)) { - return b->plugins->find_first(b->plugins, (void*)is_feature_loadable, - NULL) == SUCCESS; + return b->plugins->find_first(b->plugins, is_feature_loadable, NULL); } return FALSE; } @@ -674,9 +737,11 @@ static bool load_dependencies(private_plugin_loader_t *this, if (!find_compatible_feature(this, &provided->feature[i])) { - char *name, *provide, *depend; bool soft = provided->feature[i].kind == FEATURE_SDEPEND; +#ifndef USE_FUZZING + char *name, *provide, *depend; + name = provided->entry->plugin->get_name(provided->entry->plugin); provide = plugin_feature_get_string(&provided->feature[0]); depend = plugin_feature_get_string(&provided->feature[i]); @@ -697,6 +762,8 @@ static bool load_dependencies(private_plugin_loader_t *this, } free(provide); free(depend); +#endif /* !USE_FUZZING */ + if (soft) { /* it's ok if we can't resolve soft dependencies */ continue; @@ -716,8 +783,6 @@ static void load_feature(private_plugin_loader_t *this, { if (load_dependencies(this, provided, level)) { - char *name, *provide; - if (plugin_feature_load(provided->entry->plugin, provided->feature, provided->reg)) { @@ -727,6 +792,9 @@ static void load_feature(private_plugin_loader_t *this, return; } +#ifndef USE_FUZZING + char *name, *provide; + name = provided->entry->plugin->get_name(provided->entry->plugin); provide = plugin_feature_get_string(&provided->feature[0]); if (provided->entry->critical) @@ -740,6 +808,7 @@ static void load_feature(private_plugin_loader_t *this, provide, name); } free(provide); +#endif /* !USE_FUZZING */ } else { /* TODO: we could check the current level and set a different flag when @@ -759,13 +828,16 @@ static void load_provided(private_plugin_loader_t *this, provided_feature_t *provided, int level) { - char *name, *provide; int indent = level * 2; if (provided->loaded || provided->failed) { return; } + +#ifndef USE_FUZZING + char *name, *provide; + name = provided->entry->plugin->get_name(provided->entry->plugin); provide = plugin_feature_get_string(provided->feature); if (provided->loading) @@ -778,6 +850,12 @@ static void load_provided(private_plugin_loader_t *this, DBG3(DBG_LIB, "%*sloading feature %s in plugin '%s'", indent, "", provide, name); free(provide); +#else + if (provided->loading) + { + return; + } +#endif /* USE_FUZZING */ provided->loading = TRUE; load_feature(this, provided, level + 1); @@ -926,8 +1004,8 @@ static void purge_plugins(private_plugin_loader_t *this) { /* feature interface not supported */ continue; } - if (entry->features->find_first(entry->features, - (void*)is_feature_loaded, NULL) != SUCCESS) + if (!entry->features->find_first(entry->features, is_feature_loaded, + NULL)) { DBG2(DBG_LIB, "unloading plugin '%s' without loaded features", entry->plugin->get_name(entry->plugin)); @@ -977,6 +1055,15 @@ static bool find_plugin(char *path, char *name, char *buf, char **file) return FALSE; } +CALLBACK(find_plugin_cb, bool, + char *path, va_list args) +{ + char *name, *buf, **file; + + VA_ARGS_VGET(args, name, buf, file); + return find_plugin(path, name, buf, file); +} + /** * Used to sort plugins by priority */ @@ -1024,14 +1111,20 @@ static int plugin_priority_cmp(const plugin_priority_t *a, return diff; } -/** - * Convert enumerated plugin_priority_t to a plugin name - */ -static bool plugin_priority_filter(void *null, plugin_priority_t **prio, - char **name) +CALLBACK(plugin_priority_filter, bool, + void *null, enumerator_t *orig, va_list args) { - *name = (*prio)->name; - return TRUE; + plugin_priority_t *prio; + char **name; + + VA_ARGS_VGET(args, name); + + if (orig->enumerate(orig, &prio)) + { + *name = prio->name; + return TRUE; + } + return FALSE; } /** @@ -1071,7 +1164,7 @@ static char *modular_pluginlist(char *list) else { enumerator = enumerator_create_filter(array_create_enumerator(given), - (void*)plugin_priority_filter, NULL, NULL); + plugin_priority_filter, NULL, NULL); load_def = TRUE; } while (enumerator->enumerate(enumerator, &plugin)) @@ -1153,8 +1246,8 @@ METHOD(plugin_loader_t, load_plugins, bool, } if (this->paths) { - this->paths->find_first(this->paths, (void*)find_plugin, NULL, - token, buf, &file); + this->paths->find_first(this->paths, find_plugin_cb, NULL, token, + buf, &file); } if (!file) { diff --git a/src/libstrongswan/plugins/plugin_loader.h b/src/libstrongswan/plugins/plugin_loader.h index 6be6a909c..92a860615 100644 --- a/src/libstrongswan/plugins/plugin_loader.h +++ b/src/libstrongswan/plugins/plugin_loader.h @@ -168,4 +168,14 @@ plugin_loader_t *plugin_loader_create(); */ void plugin_loader_add_plugindirs(char *basedir, char *plugins); +#ifdef STATIC_PLUGIN_CONSTRUCTORS +/** + * Register a plugin constructor in case of static builds. + * + * @param name name of the plugin + * @param constructor constructor to register (set to NULL to unregister) + */ +void plugin_constructor_register(char *name, void *constructor); +#endif + #endif /** PLUGIN_LOADER_H_ @}*/ diff --git a/src/libstrongswan/plugins/pubkey/Makefile.in b/src/libstrongswan/plugins/pubkey/Makefile.in index 4b0b13e16..04888cde2 100644 --- a/src/libstrongswan/plugins/pubkey/Makefile.in +++ b/src/libstrongswan/plugins/pubkey/Makefile.in @@ -357,6 +357,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -379,6 +380,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/random/Makefile.in b/src/libstrongswan/plugins/random/Makefile.in index 1cf00a586..940c5572a 100644 --- a/src/libstrongswan/plugins/random/Makefile.in +++ b/src/libstrongswan/plugins/random/Makefile.in @@ -357,6 +357,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -379,6 +380,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/rc2/Makefile.in b/src/libstrongswan/plugins/rc2/Makefile.in index a57e15b64..c432cf810 100644 --- a/src/libstrongswan/plugins/rc2/Makefile.in +++ b/src/libstrongswan/plugins/rc2/Makefile.in @@ -355,6 +355,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -377,6 +378,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/rdrand/Makefile.in b/src/libstrongswan/plugins/rdrand/Makefile.in index a5d76c109..849c89630 100644 --- a/src/libstrongswan/plugins/rdrand/Makefile.in +++ b/src/libstrongswan/plugins/rdrand/Makefile.in @@ -357,6 +357,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -379,6 +380,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/revocation/Makefile.in b/src/libstrongswan/plugins/revocation/Makefile.in index cfbbcd8ad..5840c7dd0 100644 --- a/src/libstrongswan/plugins/revocation/Makefile.in +++ b/src/libstrongswan/plugins/revocation/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/sha1/Makefile.in b/src/libstrongswan/plugins/sha1/Makefile.in index 8e3301e6f..fa596e6f4 100644 --- a/src/libstrongswan/plugins/sha1/Makefile.in +++ b/src/libstrongswan/plugins/sha1/Makefile.in @@ -356,6 +356,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -378,6 +379,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/sha2/Makefile.in b/src/libstrongswan/plugins/sha2/Makefile.in index 045d6e0cc..6e3d6a390 100644 --- a/src/libstrongswan/plugins/sha2/Makefile.in +++ b/src/libstrongswan/plugins/sha2/Makefile.in @@ -355,6 +355,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -377,6 +378,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/sha3/Makefile.in b/src/libstrongswan/plugins/sha3/Makefile.in index 9fc0a1a1f..2c249343c 100644 --- a/src/libstrongswan/plugins/sha3/Makefile.in +++ b/src/libstrongswan/plugins/sha3/Makefile.in @@ -356,6 +356,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -378,6 +379,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/soup/Makefile.in b/src/libstrongswan/plugins/soup/Makefile.in index 517900486..02e398729 100644 --- a/src/libstrongswan/plugins/soup/Makefile.in +++ b/src/libstrongswan/plugins/soup/Makefile.in @@ -356,6 +356,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -378,6 +379,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/sqlite/Makefile.in b/src/libstrongswan/plugins/sqlite/Makefile.in index 8ffc4aae0..5e23cb91c 100644 --- a/src/libstrongswan/plugins/sqlite/Makefile.in +++ b/src/libstrongswan/plugins/sqlite/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/sqlite/sqlite_database.c b/src/libstrongswan/plugins/sqlite/sqlite_database.c index 0a35e3017..9f874212e 100644 --- a/src/libstrongswan/plugins/sqlite/sqlite_database.c +++ b/src/libstrongswan/plugins/sqlite/sqlite_database.c @@ -174,10 +174,8 @@ typedef struct { private_sqlite_database_t *database; } sqlite_enumerator_t; -/** - * destroy a sqlite enumerator - */ -static void sqlite_enumerator_destroy(sqlite_enumerator_t *this) +METHOD(enumerator_t, sqlite_enumerator_destroy, void, + sqlite_enumerator_t *this) { sqlite3_finalize(this->stmt); if (!is_threadsave()) @@ -188,13 +186,10 @@ static void sqlite_enumerator_destroy(sqlite_enumerator_t *this) free(this); } -/** - * Implementation of database.query().enumerate - */ -static bool sqlite_enumerator_enumerate(sqlite_enumerator_t *this, ...) +METHOD(enumerator_t, sqlite_enumerator_enumerate, bool, + sqlite_enumerator_t *this, va_list args) { int i; - va_list args; switch (sqlite3_step(this->stmt)) { @@ -207,7 +202,7 @@ static bool sqlite_enumerator_enumerate(sqlite_enumerator_t *this, ...) case SQLITE_DONE: return FALSE; } - va_start(args, this); + for (i = 0; i < this->count; i++) { switch (this->columns[i]) @@ -245,11 +240,9 @@ static bool sqlite_enumerator_enumerate(sqlite_enumerator_t *this, ...) } default: DBG1(DBG_LIB, "invalid result type supplied"); - va_end(args); return FALSE; } } - va_end(args); return TRUE; } @@ -270,13 +263,17 @@ METHOD(database_t, query, enumerator_t*, stmt = run(this, sql, &args); if (stmt) { - enumerator = malloc_thing(sqlite_enumerator_t); - enumerator->public.enumerate = (void*)sqlite_enumerator_enumerate; - enumerator->public.destroy = (void*)sqlite_enumerator_destroy; - enumerator->stmt = stmt; - enumerator->count = sqlite3_column_count(stmt); + INIT(enumerator, + .public = { + .enumerate = enumerator_enumerate_default, + .venumerate = _sqlite_enumerator_enumerate, + .destroy = _sqlite_enumerator_destroy, + }, + .stmt = stmt, + .count = sqlite3_column_count(stmt), + .database = this, + ); enumerator->columns = malloc(sizeof(db_type_t) * enumerator->count); - enumerator->database = this; for (i = 0; i < enumerator->count; i++) { enumerator->columns[i] = va_arg(args, db_type_t); diff --git a/src/libstrongswan/plugins/sshkey/Makefile.in b/src/libstrongswan/plugins/sshkey/Makefile.in index 8528b8707..a6663999d 100644 --- a/src/libstrongswan/plugins/sshkey/Makefile.in +++ b/src/libstrongswan/plugins/sshkey/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/test_vectors/Makefile.in b/src/libstrongswan/plugins/test_vectors/Makefile.in index 27741dd15..33c5720a4 100644 --- a/src/libstrongswan/plugins/test_vectors/Makefile.in +++ b/src/libstrongswan/plugins/test_vectors/Makefile.in @@ -376,6 +376,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -398,6 +399,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/unbound/Makefile.in b/src/libstrongswan/plugins/unbound/Makefile.in index 4822283c3..15c8c27cc 100644 --- a/src/libstrongswan/plugins/unbound/Makefile.in +++ b/src/libstrongswan/plugins/unbound/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/winhttp/Makefile.in b/src/libstrongswan/plugins/winhttp/Makefile.in index 9a26a987c..b417d6e66 100644 --- a/src/libstrongswan/plugins/winhttp/Makefile.in +++ b/src/libstrongswan/plugins/winhttp/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/x509/Makefile.in b/src/libstrongswan/plugins/x509/Makefile.in index 8d7f9a810..e1ed6b7ee 100644 --- a/src/libstrongswan/plugins/x509/Makefile.in +++ b/src/libstrongswan/plugins/x509/Makefile.in @@ -357,6 +357,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -379,6 +380,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/plugins/x509/x509_ac.c b/src/libstrongswan/plugins/x509/x509_ac.c index aea8eb53d..ba459288b 100644 --- a/src/libstrongswan/plugins/x509/x509_ac.c +++ b/src/libstrongswan/plugins/x509/x509_ac.c @@ -1,9 +1,8 @@ /* * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler * Copyright (C) 2003 Martin Berner, Lukas Suter - * Copyright (C) 2002-2014 Andreas Steffen + * Copyright (C) 2002-2017 Andreas Steffen * Copyright (C) 2009 Martin Willi - * * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -177,7 +176,7 @@ static chunk_t ASN1_noRevAvail_ext = chunk_from_chars( /** * declaration of function implemented in x509_cert.c */ -extern void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, +extern bool x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list); /** * parses a directoryName @@ -191,7 +190,11 @@ static bool parse_directoryName(chunk_t blob, int level, bool implicit, linked_list_t *list; list = linked_list_create(); - x509_parse_generalNames(blob, level, implicit, list); + if (!x509_parse_generalNames(blob, level, implicit, list)) + { + list->destroy(list); + return FALSE; + } enumerator = list->create_enumerator(list); while (enumerator->enumerate(enumerator, &directoryName)) @@ -801,20 +804,27 @@ METHOD(ac_t, get_authKeyIdentifier, chunk_t, return this->authKeyIdentifier; } -/** - * Filter function for attribute enumeration - */ -static bool attr_filter(void *null, group_t **in, ac_group_type_t *type, - void *in2, chunk_t *out) +CALLBACK(attr_filter, bool, + void *null, enumerator_t *orig, va_list args) { - if ((*in)->type == AC_GROUP_TYPE_STRING && - !chunk_printable((*in)->value, NULL, 0)) - { /* skip non-printable strings */ - return FALSE; + group_t *group; + ac_group_type_t *type; + chunk_t *out; + + VA_ARGS_VGET(args, type, out); + + while (orig->enumerate(orig, &group)) + { + if (group->type == AC_GROUP_TYPE_STRING && + !chunk_printable(group->value, NULL, 0)) + { /* skip non-printable strings */ + continue; + } + *type = group->type; + *out = group->value; + return TRUE; } - *type = (*in)->type; - *out = (*in)->value; - return TRUE; + return FALSE; } METHOD(ac_t, create_group_enumerator, enumerator_t*, @@ -822,7 +832,7 @@ METHOD(ac_t, create_group_enumerator, enumerator_t*, { return enumerator_create_filter( this->groups->create_enumerator(this->groups), - (void*)attr_filter, NULL, NULL); + attr_filter, NULL, NULL); } METHOD(certificate_t, get_type, certificate_type_t, diff --git a/src/libstrongswan/plugins/x509/x509_cert.c b/src/libstrongswan/plugins/x509/x509_cert.c index b77c5db4d..974e687f9 100644 --- a/src/libstrongswan/plugins/x509/x509_cert.c +++ b/src/libstrongswan/plugins/x509/x509_cert.c @@ -2,10 +2,10 @@ * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss * Copyright (C) 2002 Mario Strasser - * Copyright (C) 2000-2006 Andreas Steffen + * Copyright (C) 2000-2017 Andreas Steffen * Copyright (C) 2006-2009 Martin Willi * Copyright (C) 2008 Tobias Brunner - * Hochschule fuer Technik Rapperswil + * 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 @@ -218,6 +218,29 @@ struct private_x509_cert_t { }; /** + * Convert a generalName to a string + */ +static bool gn_to_string(identification_t *id, char **uri) +{ + int len; + +#ifdef USE_FUZZING + chunk_t proper; + chunk_printable(id->get_encoding(id), &proper, '?'); + len = asprintf(uri, "%.*s", (int)proper.len, proper.ptr); + chunk_free(&proper); +#else + len = asprintf(uri, "%Y", id); +#endif + if (!len) + { + free(*uri); + return FALSE; + } + return len > 0; +} + +/** * Destroy a CertificateDistributionPoint */ static void crl_uri_destroy(x509_cdp_t *this) @@ -280,13 +303,14 @@ static const asn1Object_t basicConstraintsObjects[] = { /** * Extracts the basicConstraints extension */ -static void parse_basicConstraints(chunk_t blob, int level0, +static bool parse_basicConstraints(chunk_t blob, int level0, private_x509_cert_t *this) { asn1_parser_t *parser; chunk_t object; int objectID; bool isCA = FALSE; + bool success; parser = asn1_parser_create(basicConstraintsObjects, blob); parser->set_top_level(parser, level0); @@ -313,7 +337,10 @@ static void parse_basicConstraints(chunk_t blob, int level0, break; } } + success = parser->success(parser); parser->destroy(parser); + + return success; } /** @@ -502,11 +529,14 @@ static const asn1Object_t generalNamesObjects[] = { /** * Extracts one or several GNs and puts them into a chained list */ -void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list) +bool x509_parse_generalNames(chunk_t blob, int level0, bool implicit, + linked_list_t *list) { asn1_parser_t *parser; chunk_t object; + identification_t *gn; int objectID; + bool success = FALSE; parser = asn1_parser_create(generalNamesObjects, blob); parser->set_top_level(parser, level0); @@ -516,16 +546,20 @@ void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_lis { if (objectID == GENERAL_NAMES_GN) { - identification_t *gn = parse_generalName(object, - parser->get_level(parser)+1); - - if (gn) + gn = parse_generalName(object, parser->get_level(parser)+1); + if (!gn) { - list->insert_last(list, (void *)gn); + goto end; } + list->insert_last(list, (void *)gn); } } + success = parser->success(parser); + +end: parser->destroy(parser); + + return success; } /** @@ -579,6 +613,7 @@ chunk_t x509_parse_authorityKeyIdentifier(chunk_t blob, int level0, } } parser->destroy(parser); + return authKeyIdentifier; } @@ -599,13 +634,14 @@ static const asn1Object_t authInfoAccessObjects[] = { /** * Extracts an authorityInfoAcess location */ -static void parse_authorityInfoAccess(chunk_t blob, int level0, +static bool parse_authorityInfoAccess(chunk_t blob, int level0, private_x509_cert_t *this) { asn1_parser_t *parser; chunk_t object; int objectID; int accessMethod = OID_UNKNOWN; + bool success = FALSE; parser = asn1_parser_create(authInfoAccessObjects, blob); parser->set_top_level(parser, level0); @@ -636,7 +672,7 @@ static void parse_authorityInfoAccess(chunk_t blob, int level0, } DBG2(DBG_ASN, " '%Y'", id); if (accessMethod == OID_OCSP && - asprintf(&uri, "%Y", id) > 0) + gn_to_string(id, &uri)) { this->ocsp_uris->insert_last(this->ocsp_uris, uri); } @@ -653,9 +689,12 @@ static void parse_authorityInfoAccess(chunk_t blob, int level0, break; } } + success = parser->success(parser); end: parser->destroy(parser); + + return success; } /** @@ -726,12 +765,13 @@ static const asn1Object_t extendedKeyUsageObjects[] = { /** * Extracts extendedKeyUsage OIDs */ -static void parse_extendedKeyUsage(chunk_t blob, int level0, +static bool parse_extendedKeyUsage(chunk_t blob, int level0, private_x509_cert_t *this) { asn1_parser_t *parser; chunk_t object; int objectID; + bool success; parser = asn1_parser_create(extendedKeyUsageObjects, blob); parser->set_top_level(parser, level0); @@ -762,27 +802,30 @@ static void parse_extendedKeyUsage(chunk_t blob, int level0, } } } + success = parser->success(parser); parser->destroy(parser); + + return success; } /** * ASN.1 definition of crlDistributionPoints */ static const asn1Object_t crlDistributionPointsObjects[] = { - { 0, "crlDistributionPoints", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */ - { 1, "DistributionPoint", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */ - { 2, "distributionPoint", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_LOOP }, /* 2 */ - { 3, "fullName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_OBJ }, /* 3 */ - { 3, "end choice", ASN1_EOC, ASN1_END }, /* 4 */ - { 3, "nameRelToCRLIssuer",ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 5 */ - { 3, "end choice", ASN1_EOC, ASN1_END }, /* 6 */ - { 2, "end opt", ASN1_EOC, ASN1_END }, /* 7 */ - { 2, "reasons", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 8 */ - { 2, "end opt", ASN1_EOC, ASN1_END }, /* 9 */ - { 2, "crlIssuer", ASN1_CONTEXT_C_2, ASN1_OPT|ASN1_OBJ }, /* 10 */ - { 2, "end opt", ASN1_EOC, ASN1_END }, /* 11 */ - { 0, "end loop", ASN1_EOC, ASN1_END }, /* 12 */ - { 0, "exit", ASN1_EOC, ASN1_EXIT } + { 0, "crlDistributionPoints", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */ + { 1, "DistributionPoint", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */ + { 2, "distributionPoint", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_CHOICE }, /* 2 */ + { 3, "fullName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_OBJ }, /* 3 */ + { 3, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 4 */ + { 3, "nameRelToCRLIssuer",ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 5 */ + { 3, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 6 */ + { 2, "end opt/choices", ASN1_EOC, ASN1_END|ASN1_CHOICE }, /* 7 */ + { 2, "reasons", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 8 */ + { 2, "end opt", ASN1_EOC, ASN1_END }, /* 9 */ + { 2, "crlIssuer", ASN1_CONTEXT_C_2, ASN1_OPT|ASN1_OBJ }, /* 10 */ + { 2, "end opt", ASN1_EOC, ASN1_END }, /* 11 */ + { 0, "end loop", ASN1_EOC, ASN1_END }, /* 12 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } }; #define CRL_DIST_POINTS 1 #define CRL_DIST_POINTS_FULLNAME 3 @@ -801,7 +844,7 @@ static void add_cdps(linked_list_t *list, linked_list_t *uris, while (uris->remove_last(uris, (void**)&id) == SUCCESS) { - if (asprintf(&uri, "%Y", id) > 0) + if (gn_to_string(id, &uri)) { if (issuers->get_count(issuers)) { @@ -836,13 +879,14 @@ static void add_cdps(linked_list_t *list, linked_list_t *uris, /** * Extracts one or several crlDistributionPoints into a list */ -void x509_parse_crlDistributionPoints(chunk_t blob, int level0, +bool x509_parse_crlDistributionPoints(chunk_t blob, int level0, linked_list_t *list) { linked_list_t *uris, *issuers; asn1_parser_t *parser; chunk_t object; int objectID; + bool success = FALSE; uris = linked_list_create(); issuers = linked_list_create(); @@ -857,37 +901,45 @@ void x509_parse_crlDistributionPoints(chunk_t blob, int level0, add_cdps(list, uris, issuers); break; case CRL_DIST_POINTS_FULLNAME: - x509_parse_generalNames(object, parser->get_level(parser) + 1, - TRUE, uris); + if (!x509_parse_generalNames(object, + parser->get_level(parser) + 1, TRUE, uris)) + { + goto end; + } break; case CRL_DIST_POINTS_ISSUER: - x509_parse_generalNames(object, parser->get_level(parser) + 1, - TRUE, issuers); + if (!x509_parse_generalNames(object, + parser->get_level(parser) + 1, TRUE, issuers)) + { + goto end; + } break; default: break; } } - parser->destroy(parser); - + success = parser->success(parser); add_cdps(list, uris, issuers); - uris->destroy(uris); - issuers->destroy(issuers); +end: + parser->destroy(parser); + uris->destroy_offset(uris, offsetof(identification_t, destroy)); + issuers->destroy_offset(issuers, offsetof(identification_t, destroy)); + + return success; } /** * ASN.1 definition of nameConstraints */ static const asn1Object_t nameConstraintsObjects[] = { - { 0, "nameConstraints", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */ + { 0, "nameConstraints", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */ { 1, "permittedSubtrees", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_LOOP }, /* 1 */ { 2, "generalSubtree", ASN1_SEQUENCE, ASN1_BODY }, /* 2 */ { 1, "end loop", ASN1_EOC, ASN1_END }, /* 3 */ { 1, "excludedSubtrees", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_LOOP }, /* 4 */ { 2, "generalSubtree", ASN1_SEQUENCE, ASN1_BODY }, /* 5 */ { 1, "end loop", ASN1_EOC, ASN1_END }, /* 6 */ - { 0, "end loop", ASN1_EOC, ASN1_END }, /* 7 */ { 0, "exit", ASN1_EOC, ASN1_EXIT } }; #define NAME_CONSTRAINT_PERMITTED 2 @@ -896,13 +948,14 @@ static const asn1Object_t nameConstraintsObjects[] = { /** * Parse permitted/excluded nameConstraints */ -static void parse_nameConstraints(chunk_t blob, int level0, +static bool parse_nameConstraints(chunk_t blob, int level0, private_x509_cert_t *this) { asn1_parser_t *parser; identification_t *id; chunk_t object; int objectID; + bool success = FALSE; parser = asn1_parser_create(nameConstraintsObjects, blob); parser->set_top_level(parser, level0); @@ -913,59 +966,69 @@ static void parse_nameConstraints(chunk_t blob, int level0, { case NAME_CONSTRAINT_PERMITTED: id = parse_generalName(object, parser->get_level(parser) + 1); - if (id) + if (!id) { - this->permitted_names->insert_last(this->permitted_names, id); + goto end; } + this->permitted_names->insert_last(this->permitted_names, id); break; case NAME_CONSTRAINT_EXCLUDED: id = parse_generalName(object, parser->get_level(parser) + 1); - if (id) + if (!id) { - this->excluded_names->insert_last(this->excluded_names, id); + goto end; } + this->excluded_names->insert_last(this->excluded_names, id); break; default: break; } } + success = parser->success(parser); + +end: parser->destroy(parser); + + return success; } /** * ASN.1 definition of a certificatePolicies extension */ static const asn1Object_t certificatePoliciesObject[] = { - { 0, "certificatePolicies", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */ - { 1, "policyInformation", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */ - { 2, "policyId", ASN1_OID, ASN1_BODY }, /* 2 */ - { 2, "qualifiers", ASN1_SEQUENCE, ASN1_OPT|ASN1_LOOP }, /* 3 */ - { 3, "qualifierInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 4 */ - { 4, "qualifierId", ASN1_OID, ASN1_BODY }, /* 5 */ - { 4, "cPSuri", ASN1_IA5STRING, ASN1_OPT|ASN1_BODY }, /* 6 */ - { 4, "end choice", ASN1_EOC, ASN1_END }, /* 7 */ - { 4, "userNotice", ASN1_SEQUENCE, ASN1_OPT|ASN1_BODY }, /* 8 */ - { 5, "explicitText", ASN1_EOC, ASN1_RAW }, /* 9 */ - { 4, "end choice", ASN1_EOC, ASN1_END }, /* 10 */ - { 2, "end opt/loop", ASN1_EOC, ASN1_END }, /* 12 */ - { 0, "end loop", ASN1_EOC, ASN1_END }, /* 13 */ - { 0, "exit", ASN1_EOC, ASN1_EXIT } + { 0, "certificatePolicies", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */ + { 1, "policyInformation", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */ + { 2, "policyId", ASN1_OID, ASN1_BODY }, /* 2 */ + { 2, "qualifiers", ASN1_SEQUENCE, ASN1_OPT|ASN1_LOOP }, /* 3 */ + { 3, "qualifierInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 4 */ + { 4, "qualifierId", ASN1_OID, ASN1_BODY }, /* 5 */ + { 4, "qualifier", ASN1_EOC, ASN1_CHOICE }, /* 6 */ + { 5, "cPSuri", ASN1_IA5STRING, ASN1_OPT|ASN1_BODY }, /* 7 */ + { 5, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 8 */ + { 5, "userNotice", ASN1_SEQUENCE, ASN1_OPT|ASN1_BODY }, /* 9 */ + { 6, "explicitText", ASN1_EOC, ASN1_RAW }, /* 10 */ + { 5, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 11 */ + { 4, "end choices", ASN1_EOC, ASN1_END|ASN1_CHOICE }, /* 12 */ + { 2, "end opt/loop", ASN1_EOC, ASN1_END }, /* 13 */ + { 0, "end loop", ASN1_EOC, ASN1_END }, /* 14 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } }; -#define CERT_POLICY_ID 2 -#define CERT_POLICY_QUALIFIER_ID 5 -#define CERT_POLICY_CPS_URI 6 -#define CERT_POLICY_EXPLICIT_TEXT 9 +#define CERT_POLICY_ID 2 +#define CERT_POLICY_QUALIFIER_ID 5 +#define CERT_POLICY_CPS_URI 7 +#define CERT_POLICY_EXPLICIT_TEXT 10 /** * Parse certificatePolicies */ -static void parse_certificatePolicies(chunk_t blob, int level0, +static bool parse_certificatePolicies(chunk_t blob, int level0, private_x509_cert_t *this) { x509_cert_policy_t *policy = NULL; asn1_parser_t *parser; chunk_t object; int objectID, qualifier = OID_UNKNOWN; + bool success; parser = asn1_parser_create(certificatePoliciesObject, blob); parser->set_top_level(parser, level0); @@ -998,7 +1061,10 @@ static void parse_certificatePolicies(chunk_t blob, int level0, break; } } + success = parser->success(parser); parser->destroy(parser); + + return success; } /** @@ -1019,13 +1085,14 @@ static const asn1Object_t policyMappingsObjects[] = { /** * Parse policyMappings */ -static void parse_policyMappings(chunk_t blob, int level0, +static bool parse_policyMappings(chunk_t blob, int level0, private_x509_cert_t *this) { x509_policy_mapping_t *map = NULL; asn1_parser_t *parser; chunk_t object; int objectID; + bool success; parser = asn1_parser_create(policyMappingsObjects, blob); parser->set_top_level(parser, level0); @@ -1054,7 +1121,10 @@ static void parse_policyMappings(chunk_t blob, int level0, break; } } + success = parser->success(parser); parser->destroy(parser); + + return success; } /** @@ -1076,12 +1146,13 @@ static const asn1Object_t policyConstraintsObjects[] = { /** * Parse policyConstraints */ -static void parse_policyConstraints(chunk_t blob, int level0, +static bool parse_policyConstraints(chunk_t blob, int level0, private_x509_cert_t *this) { asn1_parser_t *parser; chunk_t object; int objectID; + bool success; parser = asn1_parser_create(policyConstraintsObjects, blob); parser->set_top_level(parser, level0); @@ -1100,34 +1171,41 @@ static void parse_policyConstraints(chunk_t blob, int level0, break; } } + success = parser->success(parser); parser->destroy(parser); + + return success; } /** * ASN.1 definition of ipAddrBlocks according to RFC 3779 */ static const asn1Object_t ipAddrBlocksObjects[] = { - { 0, "ipAddrBlocks", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */ - { 1, "ipAddressFamily", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */ - { 2, "addressFamily", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */ - { 2, "inherit", ASN1_NULL, ASN1_OPT|ASN1_NONE }, /* 3 */ - { 2, "end choice", ASN1_EOC, ASN1_END }, /* 4 */ - { 2, "addressesOrRanges", ASN1_SEQUENCE, ASN1_OPT|ASN1_LOOP }, /* 5 */ - { 3, "addressPrefix", ASN1_BIT_STRING, ASN1_OPT|ASN1_BODY }, /* 6 */ - { 3, "end choice", ASN1_EOC, ASN1_END }, /* 7 */ - { 3, "addressRange", ASN1_SEQUENCE, ASN1_OPT|ASN1_NONE }, /* 8 */ - { 4, "min", ASN1_BIT_STRING, ASN1_BODY }, /* 9 */ - { 4, "max", ASN1_BIT_STRING, ASN1_BODY }, /* 10 */ - { 3, "end choice", ASN1_EOC, ASN1_END }, /* 11 */ - { 2, "end opt/loop", ASN1_EOC, ASN1_END }, /* 12 */ - { 0, "end loop", ASN1_EOC, ASN1_END }, /* 13 */ - { 0, "exit", ASN1_EOC, ASN1_EXIT } + { 0, "ipAddrBlocks", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */ + { 1, "ipAddressFamily", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */ + { 2, "addressFamily", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */ + { 2, "ipAddressChoice", ASN1_EOC, ASN1_CHOICE }, /* 3 */ + { 3, "inherit", ASN1_NULL, ASN1_OPT }, /* 4 */ + { 3, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 5 */ + { 3, "addressesOrRanges", ASN1_SEQUENCE, ASN1_OPT|ASN1_LOOP }, /* 6 */ + { 4, "addressOrRange", ASN1_EOC, ASN1_CHOICE }, /* 7 */ + { 5, "addressPrefix", ASN1_BIT_STRING, ASN1_OPT|ASN1_BODY }, /* 8 */ + { 5, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 9 */ + { 5, "addressRange", ASN1_SEQUENCE, ASN1_OPT }, /* 10 */ + { 6, "min", ASN1_BIT_STRING, ASN1_BODY }, /* 11 */ + { 6, "max", ASN1_BIT_STRING, ASN1_BODY }, /* 12 */ + { 5, "end choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 13 */ + { 4, "end choices", ASN1_EOC, ASN1_END|ASN1_CHOICE }, /* 14 */ + { 3, "end loop/choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 15 */ + { 2, "end choices", ASN1_EOC, ASN1_END|ASN1_CHOICE }, /* 16 */ + { 0, "end loop", ASN1_EOC, ASN1_END }, /* 17 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } }; #define IP_ADDR_BLOCKS_FAMILY 2 -#define IP_ADDR_BLOCKS_INHERIT 3 -#define IP_ADDR_BLOCKS_PREFIX 6 -#define IP_ADDR_BLOCKS_MIN 9 -#define IP_ADDR_BLOCKS_MAX 10 +#define IP_ADDR_BLOCKS_INHERIT 4 +#define IP_ADDR_BLOCKS_PREFIX 8 +#define IP_ADDR_BLOCKS_MIN 11 +#define IP_ADDR_BLOCKS_MAX 12 static bool check_address_object(ts_type_t ts_type, chunk_t object) { @@ -1171,7 +1249,7 @@ static bool check_address_object(ts_type_t ts_type, chunk_t object) return TRUE; } -static void parse_ipAddrBlocks(chunk_t blob, int level0, +static bool parse_ipAddrBlocks(chunk_t blob, int level0, private_x509_cert_t *this) { asn1_parser_t *parser; @@ -1179,6 +1257,7 @@ static void parse_ipAddrBlocks(chunk_t blob, int level0, ts_type_t ts_type = 0; traffic_selector_t *ts; int objectID; + bool success = FALSE; parser = asn1_parser_create(ipAddrBlocksObjects, blob); parser->set_top_level(parser, level0); @@ -1240,10 +1319,13 @@ static void parse_ipAddrBlocks(chunk_t blob, int level0, break; } } + success = parser->success(parser); this->flags |= X509_IP_ADDR_BLOCKS; end: parser->destroy(parser); + + return success; } /** @@ -1387,43 +1469,74 @@ static bool parse_certificate(private_x509_cert_t *this) this->subjectKeyIdentifier = object; break; case OID_SUBJECT_ALT_NAME: - x509_parse_generalNames(object, level, FALSE, - this->subjectAltNames); + if (!x509_parse_generalNames(object, level, FALSE, + this->subjectAltNames)) + { + goto end; + } break; case OID_BASIC_CONSTRAINTS: - parse_basicConstraints(object, level, this); + if (!parse_basicConstraints(object, level, this)) + { + goto end; + } break; case OID_CRL_DISTRIBUTION_POINTS: - x509_parse_crlDistributionPoints(object, level, - this->crl_uris); + if (!x509_parse_crlDistributionPoints(object, level, + this->crl_uris)) + { + goto end; + } break; case OID_AUTHORITY_KEY_ID: - this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object, - level, &this->authKeySerialNumber); + chunk_free(&this->authKeyIdentifier); + this->authKeyIdentifier = x509_parse_authorityKeyIdentifier( + object, level, &this->authKeySerialNumber); break; case OID_AUTHORITY_INFO_ACCESS: - parse_authorityInfoAccess(object, level, this); + if (!parse_authorityInfoAccess(object, level, this)) + { + goto end; + } break; case OID_KEY_USAGE: parse_keyUsage(object, this); break; case OID_EXTENDED_KEY_USAGE: - parse_extendedKeyUsage(object, level, this); + if (!parse_extendedKeyUsage(object, level, this)) + { + goto end; + } break; case OID_IP_ADDR_BLOCKS: - parse_ipAddrBlocks(object, level, this); + if (!parse_ipAddrBlocks(object, level, this)) + { + goto end; + } break; case OID_NAME_CONSTRAINTS: - parse_nameConstraints(object, level, this); + if (!parse_nameConstraints(object, level, this)) + { + goto end; + } break; case OID_CERTIFICATE_POLICIES: - parse_certificatePolicies(object, level, this); + if (!parse_certificatePolicies(object, level, this)) + { + goto end; + } break; case OID_POLICY_MAPPINGS: - parse_policyMappings(object, level, this); + if (!parse_policyMappings(object, level, this)) + { + goto end; + } break; case OID_POLICY_CONSTRAINTS: - parse_policyConstraints(object, level, this); + if (!parse_policyConstraints(object, level, this)) + { + goto end; + } break; case OID_INHIBIT_ANY_POLICY: if (!asn1_parse_simple_object(&object, ASN1_INTEGER, diff --git a/src/libstrongswan/plugins/x509/x509_crl.c b/src/libstrongswan/plugins/x509/x509_crl.c index 4d7e7bd10..d8913ad73 100644 --- a/src/libstrongswan/plugins/x509/x509_crl.c +++ b/src/libstrongswan/plugins/x509/x509_crl.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2008-2009 Martin Willi - * Hochschule fuer Technik Rapperswil + * Copyright (C) 2017 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 @@ -149,7 +150,7 @@ extern chunk_t x509_parse_authorityKeyIdentifier(chunk_t blob, int level0, /** * from x509_cert */ -extern void x509_parse_crlDistributionPoints(chunk_t blob, int level0, +extern bool x509_parse_crlDistributionPoints(chunk_t blob, int level0, linked_list_t *list); /** @@ -309,8 +310,11 @@ static bool parse(private_x509_crl_t *this) this->crlNumber = object; break; case OID_FRESHEST_CRL: - x509_parse_crlDistributionPoints(object, level, - this->crl_uris); + if (!x509_parse_crlDistributionPoints(object, level, + this->crl_uris)) + { + goto end; + } break; case OID_DELTA_CRL_INDICATOR: if (!asn1_parse_simple_object(&object, ASN1_INTEGER, @@ -360,25 +364,33 @@ end: return success; } -/** - * enumerator filter callback for create_enumerator - */ -static bool filter(void *data, revoked_t **revoked, chunk_t *serial, void *p2, - time_t *date, void *p3, crl_reason_t *reason) +CALLBACK(filter, bool, + void *data, enumerator_t *orig, va_list args) { - if (serial) - { - *serial = (*revoked)->serial; - } - if (date) - { - *date = (*revoked)->date; - } - if (reason) + revoked_t *revoked; + crl_reason_t *reason; + chunk_t *serial; + time_t *date; + + VA_ARGS_VGET(args, serial, date, reason); + + if (orig->enumerate(orig, &revoked)) { - *reason = (*revoked)->reason; + if (serial) + { + *serial = revoked->serial; + } + if (date) + { + *date = revoked->date; + } + if (reason) + { + *reason = revoked->reason; + } + return TRUE; } - return TRUE; + return FALSE; } METHOD(crl_t, get_serial, chunk_t, @@ -418,7 +430,7 @@ METHOD(crl_t, create_enumerator, enumerator_t*, { return enumerator_create_filter( this->revoked->create_enumerator(this->revoked), - (void*)filter, NULL, NULL); + filter, NULL, NULL); } METHOD(certificate_t, get_type, certificate_type_t, diff --git a/src/libstrongswan/plugins/x509/x509_ocsp_response.c b/src/libstrongswan/plugins/x509/x509_ocsp_response.c index b46af30fe..140e9bfa9 100644 --- a/src/libstrongswan/plugins/x509/x509_ocsp_response.c +++ b/src/libstrongswan/plugins/x509/x509_ocsp_response.c @@ -228,32 +228,38 @@ METHOD(ocsp_response_t, create_cert_enumerator, enumerator_t*, return this->certs->create_enumerator(this->certs); } -/** - * enumerator filter callback for create_response_enumerator - */ -static bool filter(void *data, single_response_t **response, - chunk_t *serialNumber, - void *p2, cert_validation_t *status, - void *p3, time_t *revocationTime, - void *p4, crl_reason_t *revocationReason) +CALLBACK(filter, bool, + void *data, enumerator_t *orig, va_list args) { - if (serialNumber) - { - *serialNumber = (*response)->serialNumber; - } - if (status) - { - *status = (*response)->status; - } - if (revocationTime) - { - *revocationTime = (*response)->revocationTime; - } - if (revocationReason) + single_response_t *response; + cert_validation_t *status; + crl_reason_t *revocationReason; + chunk_t *serialNumber; + time_t *revocationTime; + + VA_ARGS_VGET(args, serialNumber, status, revocationTime, revocationReason); + + if (orig->enumerate(orig, &response)) { - *revocationReason = (*response)->revocationReason; + if (serialNumber) + { + *serialNumber = response->serialNumber; + } + if (status) + { + *status = response->status; + } + if (revocationTime) + { + *revocationTime = response->revocationTime; + } + if (revocationReason) + { + *revocationReason = response->revocationReason; + } + return TRUE; } - return TRUE; + return FALSE; } METHOD(ocsp_response_t, create_response_enumerator, enumerator_t*, @@ -261,7 +267,7 @@ METHOD(ocsp_response_t, create_response_enumerator, enumerator_t*, { return enumerator_create_filter( this->responses->create_enumerator(this->responses), - (void*)filter, NULL, NULL); + filter, NULL, NULL); } /** diff --git a/src/libstrongswan/plugins/x509/x509_pkcs10.c b/src/libstrongswan/plugins/x509/x509_pkcs10.c index 20561f7e2..e39e24bff 100644 --- a/src/libstrongswan/plugins/x509/x509_pkcs10.c +++ b/src/libstrongswan/plugins/x509/x509_pkcs10.c @@ -1,7 +1,6 @@ /* * Copyright (C) 2005 Jan Hutter, Martin Willi - * Copyright (C) 2009 Andreas Steffen - * + * Copyright (C) 2009-2017 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -101,7 +100,8 @@ struct private_x509_pkcs10_t { /** * Imported from x509_cert.c */ -extern void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list); +extern bool x509_parse_generalNames(chunk_t blob, int level0, bool implicit, + linked_list_t *list); extern chunk_t x509_build_subjectAltNames(linked_list_t *list); METHOD(certificate_t, get_type, certificate_type_t, @@ -290,8 +290,11 @@ static bool parse_extension_request(private_x509_pkcs10_t *this, chunk_t blob, i switch (extn_oid) { case OID_SUBJECT_ALT_NAME: - x509_parse_generalNames(object, level, FALSE, - this->subjectAltNames); + if (!x509_parse_generalNames(object, level, FALSE, + this->subjectAltNames)) + { + goto end; + } break; default: break; @@ -303,7 +306,10 @@ static bool parse_extension_request(private_x509_pkcs10_t *this, chunk_t blob, i } } success = parser->success(parser); + +end: parser->destroy(parser); + return success; } diff --git a/src/libstrongswan/plugins/xcbc/Makefile.in b/src/libstrongswan/plugins/xcbc/Makefile.in index 78f9268c2..a23130851 100644 --- a/src/libstrongswan/plugins/xcbc/Makefile.in +++ b/src/libstrongswan/plugins/xcbc/Makefile.in @@ -355,6 +355,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -377,6 +378,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/processing/processor.c b/src/libstrongswan/processing/processor.c index 27e5ab5f6..bd8d534a5 100644 --- a/src/libstrongswan/processing/processor.c +++ b/src/libstrongswan/processing/processor.c @@ -429,7 +429,15 @@ METHOD(processor_t, execute_job, void, METHOD(processor_t, set_threads, void, private_processor_t *this, u_int count) { + int i; + this->mutex->lock(this->mutex); + for (i = 0; i < JOB_PRIO_MAX; i++) + { + this->prio_threads[i] = lib->settings->get_int(lib->settings, + "%s.processor.priority_threads.%N", 0, lib->ns, + job_priority_names, i); + } if (count > this->total_threads) { /* increase thread count */ worker_thread_t *worker; @@ -551,13 +559,10 @@ processor_t *processor_create() .job_added = condvar_create(CONDVAR_TYPE_DEFAULT), .thread_terminated = condvar_create(CONDVAR_TYPE_DEFAULT), ); + for (i = 0; i < JOB_PRIO_MAX; i++) { this->jobs[i] = linked_list_create(); - this->prio_threads[i] = lib->settings->get_int(lib->settings, - "%s.processor.priority_threads.%N", 0, lib->ns, - job_priority_names, i); } - return &this->public; } diff --git a/src/libstrongswan/settings/settings.c b/src/libstrongswan/settings/settings.c index b00e8190c..2a92d523b 100644 --- a/src/libstrongswan/settings/settings.c +++ b/src/libstrongswan/settings/settings.c @@ -744,10 +744,8 @@ typedef struct { hashtable_t *seen; } enumerator_data_t; -/** - * Destroy enumerator data - */ -static void enumerator_destroy(enumerator_data_t *this) +CALLBACK(enumerator_destroy, void, + enumerator_data_t *this) { this->settings->lock->unlock(this->settings->lock); this->seen->destroy(this->seen); @@ -755,18 +753,25 @@ static void enumerator_destroy(enumerator_data_t *this) free(this); } -/** - * Enumerate section names, not sections - */ -static bool section_filter(hashtable_t *seen, section_t **in, char **out) +CALLBACK(section_filter, bool, + hashtable_t *seen, enumerator_t *orig, va_list args) { - *out = (*in)->name; - if (seen->get(seen, *out)) + section_t *section; + char **out; + + VA_ARGS_VGET(args, out); + + while (orig->enumerate(orig, §ion)) { - return FALSE; + if (seen->get(seen, section->name)) + { + continue; + } + *out = section->name; + seen->put(seen, section->name, section->name); + return TRUE; } - seen->put(seen, *out, *out); - return TRUE; + return FALSE; } /** @@ -776,8 +781,8 @@ static enumerator_t *section_enumerator(section_t *section, enumerator_data_t *data) { return enumerator_create_filter( - array_create_enumerator(section->sections_order), - (void*)section_filter, data->seen, NULL); + array_create_enumerator(section->sections_order), + section_filter, data->seen, NULL); } METHOD(settings_t, create_section_enumerator, enumerator_t*, @@ -803,23 +808,29 @@ METHOD(settings_t, create_section_enumerator, enumerator_t*, .seen = hashtable_create(hashtable_hash_str, hashtable_equals_str, 8), ); return enumerator_create_nested(array_create_enumerator(sections), - (void*)section_enumerator, data, (void*)enumerator_destroy); + (void*)section_enumerator, data, enumerator_destroy); } -/** - * Enumerate key and values, not kv_t entries - */ -static bool kv_filter(hashtable_t *seen, kv_t **in, char **key, - void *none, char **value) +CALLBACK(kv_filter, bool, + hashtable_t *seen, enumerator_t *orig, va_list args) { - *key = (*in)->key; - if (seen->get(seen, *key) || !(*in)->value) + kv_t *kv; + char **key, **value; + + VA_ARGS_VGET(args, key, value); + + while (orig->enumerate(orig, &kv)) { - return FALSE; + if (seen->get(seen, kv->key) || !kv->value) + { + continue; + } + *key = kv->key; + *value = kv->value; + seen->put(seen, kv->key, kv->key); + return TRUE; } - *value = (*in)->value; - seen->put(seen, *key, *key); - return TRUE; + return FALSE; } /** @@ -828,7 +839,7 @@ static bool kv_filter(hashtable_t *seen, kv_t **in, char **key, static enumerator_t *kv_enumerator(section_t *section, enumerator_data_t *data) { return enumerator_create_filter(array_create_enumerator(section->kv_order), - (void*)kv_filter, data->seen, NULL); + kv_filter, data->seen, NULL); } METHOD(settings_t, create_key_value_enumerator, enumerator_t*, diff --git a/src/libstrongswan/tests/Makefile.in b/src/libstrongswan/tests/Makefile.in index f4c607ca4..279e179ea 100644 --- a/src/libstrongswan/tests/Makefile.in +++ b/src/libstrongswan/tests/Makefile.in @@ -396,6 +396,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -418,6 +419,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libstrongswan/tests/suites/test_asn1_parser.c b/src/libstrongswan/tests/suites/test_asn1_parser.c index 973562bff..ebbe7ddaf 100644 --- a/src/libstrongswan/tests/suites/test_asn1_parser.c +++ b/src/libstrongswan/tests/suites/test_asn1_parser.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Andreas Steffen + * Copyright (C) 2014-2017 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -250,6 +250,7 @@ START_TEST(test_asn1_parser_option) i3 = *object.ptr; break; default: + break; } } @@ -264,6 +265,105 @@ START_TEST(test_asn1_parser_option) } END_TEST +/******************************************************************************* + * choice + */ + +typedef struct { + int i1, i2, i3, i4; + chunk_t blob; +} choice_test_t; + +static const asn1Object_t choiceObjects[] = { + { 0, "choiceObject", ASN1_EOC, ASN1_CHOICE }, /* 0 */ + { 1, "choiceA", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_CHOICE }, /* 1 */ + { 2, "choice1", ASN1_OCTET_STRING, ASN1_OPT|ASN1_BODY }, /* 2 */ + { 2, "end choice1", ASN1_EOC, ASN1_END|ASN1_CH }, /* 3 */ + { 2, "choice2", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 4 */ + { 2, "end choice2", ASN1_EOC, ASN1_END|ASN1_CH }, /* 5 */ + { 1, "end choiceA", ASN1_EOC, ASN1_END|ASN1_CHOICE| + ASN1_CH }, /* 6 */ + { 1, "choiceB", ASN1_SEQUENCE, ASN1_OPT|ASN1_LOOP }, /* 7 */ + { 2, "choiceObject", ASN1_EOC, ASN1_CHOICE }, /* 8 */ + { 3, "choice3", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 9 */ + { 3, "end choice3", ASN1_EOC, ASN1_END|ASN1_CH }, /* 10 */ + { 3, "choice4", ASN1_OCTET_STRING, ASN1_OPT|ASN1_BODY }, /* 11 */ + { 3, "end choice4", ASN1_EOC, ASN1_END|ASN1_CH }, /* 12 */ + { 2, "end choices", ASN1_EOC, ASN1_END|ASN1_CHOICE }, /* 13 */ + { 1, "end loop/choice", ASN1_EOC, ASN1_END|ASN1_CH }, /* 14 */ + { 0, "end choices", ASN1_EOC, ASN1_END|ASN1_CHOICE }, /* 15 */ + { 0, "exit", ASN1_EOC, ASN1_EXIT } +}; + +choice_test_t choice_tests[] = { + { 0, 0, 0, 0, { NULL, 0 } }, + { 0, 0, 0, 0, chunk_from_chars(0xA0, 0x00) }, + { 1, 0, 0, 0, chunk_from_chars(0xA0, 0x03, 0x04, 0x01, 0x01) }, + { 1, 0, 0, 0, chunk_from_chars(0xA0, 0x06, 0x04, 0x01, 0x01, + 0x02, 0x01, 0x02) }, + { 0, 2, 0, 0, chunk_from_chars(0xA0, 0x03, 0x02, 0x01, 0x02) }, + { 0, 2, 0, 0, chunk_from_chars(0xA0, 0x03, 0x02, 0x01, 0x02, + 0x30, 0x03, 0x02, 0x01, 0x03) }, + { 0, 0, 0, 0, chunk_from_chars(0xA0, 0x04, 0x03, 0x02, 0x00, 0x04) }, + { 0, 0, 3, 0, chunk_from_chars(0x30, 0x03, 0x02, 0x01, 0x03) }, + { 0, 0, 0, 4, chunk_from_chars(0x30, 0x03, 0x04, 0x01, 0x04) }, + { 0, 0, 3, 4, chunk_from_chars(0x30, 0x06, 0x04, 0x01, 0x04, + 0x02, 0x01, 0x03) }, + { 0, 0, 3, 4, chunk_from_chars(0x30, 0x06, 0x02, 0x01, 0x03, + 0x04, 0x01, 0x04) }, + { 0, 0, 6, 0, chunk_from_chars(0x30, 0x06, 0x02, 0x01, 0x03, + 0x02, 0x01, 0x03) }, + { 0, 0, 0, 8, chunk_from_chars(0x30, 0x06, 0x04, 0x01, 0x04, + 0x04, 0x01, 0x04) }, + { 0, 0, 0, 0, chunk_from_chars(0x30, 0x04, 0x03, 0x02, 0x00, 0x04) }, + { 0, 0, 0, 0, chunk_from_chars(0x03, 0x02, 0x00, 0x04) } +}; + +START_TEST(test_asn1_parser_choice) +{ + asn1_parser_t *parser; + chunk_t object; + int objectID, i1 = 0, i2 = 0, i3 = 0, i4 = 0; + bool success; + + parser = asn1_parser_create(choiceObjects, choice_tests[_i].blob); + while (parser->iterate(parser, &objectID, &object)) + { + switch (objectID) + { + case 2: + i1 += *object.ptr; + break; + case 4: + i2 += *object.ptr; + break; + case 9: + i3 += *object.ptr; + break; + case 11: + i4 += *object.ptr; + break; + default: + + break; + } + } + success = parser->success(parser); + parser->destroy(parser); + + ck_assert(success == (choice_tests[_i].i1 || + choice_tests[_i].i2 || + choice_tests[_i].i3 || + choice_tests[_i].i4 )); + + ck_assert(i1 == choice_tests[_i].i1 && + i2 == choice_tests[_i].i2 && + i3 == choice_tests[_i].i3 && + i4 == choice_tests[_i].i4 ); +} +END_TEST + + Suite *asn1_parser_suite_create() { Suite *s; @@ -287,5 +387,9 @@ Suite *asn1_parser_suite_create() tcase_add_loop_test(tc, test_asn1_parser_option, 0, countof(option_tests)); suite_add_tcase(s, tc); + tc = tcase_create("choice"); + tcase_add_loop_test(tc, test_asn1_parser_choice, 0, countof(choice_tests)); + suite_add_tcase(s, tc); + return s; } diff --git a/src/libstrongswan/tests/suites/test_enumerator.c b/src/libstrongswan/tests/suites/test_enumerator.c index 9bd6d24f2..b781ae9fd 100644 --- a/src/libstrongswan/tests/suites/test_enumerator.c +++ b/src/libstrongswan/tests/suites/test_enumerator.c @@ -104,25 +104,45 @@ static void destroy_data(void *data) * filtered test */ -static bool filter(int *data, int **v, int *vo, int **w, int *wo, - int **x, int *xo, int **y, int *yo, int **z, int *zo) +CALLBACK(filter, bool, + int *data, enumerator_t *orig, va_list args) { - int val = **v; + int *item, *vo, *wo, *xo, *yo, *zo; - *vo = val++; - *wo = val++; - *xo = val++; - *yo = val++; - *zo = val++; - fail_if(data != (void*)101, "data does not match '101' in filter function"); - return TRUE; + VA_ARGS_VGET(args, vo, wo, xo, yo, zo); + + if (orig->enumerate(orig, &item)) + { + int val = *item; + *vo = val++; + *wo = val++; + *xo = val++; + *yo = val++; + *zo = val++; + fail_if(data != (void*)101, "data does not match '101' in filter function"); + return TRUE; + } + return FALSE; } -static bool filter_odd(void *data, int **item, int *out) +CALLBACK(filter_odd, bool, + void *data, enumerator_t *orig, va_list args) { + int *item, *out; + + VA_ARGS_VGET(args, out); + fail_if(data != (void*)101, "data does not match '101' in filter function"); - *out = **item; - return **item % 2 == 0; + + while (orig->enumerate(orig, &item)) + { + if (*item % 2 == 0) + { + *out = *item; + return TRUE; + } + } + return FALSE; } START_TEST(test_filtered) @@ -136,7 +156,7 @@ START_TEST(test_filtered) round = 1; enumerator = enumerator_create_filter(list->create_enumerator(list), - (void*)filter, (void*)101, destroy_data); + filter, (void*)101, destroy_data); while (enumerator->enumerate(enumerator, &v, &w, &x, &y, &z)) { ck_assert_int_eq(v, round); @@ -166,7 +186,7 @@ START_TEST(test_filtered_filter) /* should also work without destructor, so set this manually */ destroy_data_called = 1; enumerator = enumerator_create_filter(list->create_enumerator(list), - (void*)filter_odd, (void*)101, NULL); + filter_odd, (void*)101, NULL); while (enumerator->enumerate(enumerator, &x)) { ck_assert(x % 2 == 0); diff --git a/src/libstrongswan/tests/suites/test_linked_list.c b/src/libstrongswan/tests/suites/test_linked_list.c index 7a161817c..aa1e0429f 100644 --- a/src/libstrongswan/tests/suites/test_linked_list.c +++ b/src/libstrongswan/tests/suites/test_linked_list.c @@ -183,26 +183,48 @@ END_TEST * find */ -static bool match_a_b(void *item, void *a, void *b) +CALLBACK(find_a_b, bool, + void *item, va_list args) { + void *a, *b; + + VA_ARGS_VGET(args, a, b); ck_assert(a == (void*)1); ck_assert(b == (void*)2); return item == a || item == b; } +CALLBACK(find_a, bool, + void *item, va_list args) +{ + void *a; + + VA_ARGS_VGET(args, a); + return match_a(item, a); +} + +CALLBACK(find_b, bool, + void *item, va_list args) +{ + void *b; + + VA_ARGS_VGET(args, b); + return match_b(item, b); +} + START_TEST(test_find) { void *a = (void*)1, *b = (void*)2; - ck_assert(list->find_first(list, NULL, &a) == NOT_FOUND); + ck_assert(!list->find_first(list, NULL, &a)); list->insert_last(list, a); - ck_assert(list->find_first(list, NULL, &a) == SUCCESS); - ck_assert(list->find_first(list, NULL, &b) == NOT_FOUND); + ck_assert(list->find_first(list, NULL, &a)); + ck_assert(!list->find_first(list, NULL, &b)); list->insert_last(list, b); - ck_assert(list->find_first(list, NULL, &a) == SUCCESS); - ck_assert(list->find_first(list, NULL, &b) == SUCCESS); + ck_assert(list->find_first(list, NULL, &a)); + ck_assert(list->find_first(list, NULL, &b)); - ck_assert(list->find_first(list, NULL, NULL) == NOT_FOUND); + ck_assert(!list->find_first(list, NULL, NULL)); } END_TEST @@ -210,29 +232,57 @@ START_TEST(test_find_callback) { void *a = (void*)1, *b = (void*)2, *x = NULL; - ck_assert(list->find_first(list, (linked_list_match_t)match_a_b, &x, a, b) == NOT_FOUND); + ck_assert(!list->find_first(list, find_a_b, &x, a, b)); list->insert_last(list, a); - ck_assert(list->find_first(list, (linked_list_match_t)match_a, NULL, a) == SUCCESS); + ck_assert(list->find_first(list, find_a, NULL, a)); x = NULL; - ck_assert(list->find_first(list, (linked_list_match_t)match_a, &x, a) == SUCCESS); + ck_assert(list->find_first(list, find_a, &x, a)); ck_assert(a == x); - ck_assert(list->find_first(list, (linked_list_match_t)match_b, &x, b) == NOT_FOUND); + ck_assert(!list->find_first(list, find_b, &x, b)); ck_assert(a == x); x = NULL; - ck_assert(list->find_first(list, (linked_list_match_t)match_a_b, &x, a, b) == SUCCESS); + ck_assert(list->find_first(list, find_a_b, &x, a, b)); ck_assert(a == x); list->insert_last(list, b); - ck_assert(list->find_first(list, (linked_list_match_t)match_a, &x, a) == SUCCESS); + ck_assert(list->find_first(list, find_a, &x, a)); ck_assert(a == x); - ck_assert(list->find_first(list, (linked_list_match_t)match_b, &x, b) == SUCCESS); + ck_assert(list->find_first(list, find_b, &x, b)); ck_assert(b == x); x = NULL; - ck_assert(list->find_first(list, (linked_list_match_t)match_a_b, &x, a, b) == SUCCESS); + ck_assert(list->find_first(list, find_a_b, &x, a, b)); ck_assert(a == x); } END_TEST +CALLBACK(find_args, bool, + void *item, va_list args) +{ + uint64_t d, e; + level_t c; + int *a, b; + + VA_ARGS_VGET(args, a, b, c, d, e); + ck_assert_int_eq(*a, 1); + ck_assert_int_eq(b, 2); + ck_assert_int_eq(c, LEVEL_PRIVATE); + ck_assert_int_eq(d, UINT64_MAX); + ck_assert_int_eq(e, UINT64_MAX-1); + return item == a; +} + +START_TEST(test_find_callback_args) +{ + int a = 1, b = 2, *x; + uint64_t d = UINT64_MAX; + + list->insert_last(list, &a); + ck_assert(list->find_first(list, find_args, (void**)&x, &a, b, + LEVEL_PRIVATE, d, UINT64_MAX-1)); + ck_assert_int_eq(a, *x); +} +END_TEST + /******************************************************************************* * invoke */ @@ -241,11 +291,16 @@ typedef struct invoke_t invoke_t; struct invoke_t { int val; - void (*invoke)(invoke_t *item, void *a, void *b, void *c, void *d, int *sum); + void (*invoke)(invoke_t *item); }; -static void invoke(intptr_t item, void *a, void *b, void *c, void *d, int *sum) +CALLBACK(invoke, void, + intptr_t item, va_list args) { + void *a, *b, *c, *d; + int *sum; + + VA_ARGS_VGET(args, a, b, c, d, sum); ck_assert_int_eq((uintptr_t)a, 1); ck_assert_int_eq((uintptr_t)b, 2); ck_assert_int_eq((uintptr_t)c, 3); @@ -253,9 +308,9 @@ static void invoke(intptr_t item, void *a, void *b, void *c, void *d, int *sum) *sum += item; } -static void invoke_offset(invoke_t *item, void *a, void *b, void *c, void *d, int *sum) +static void invoke_offset(invoke_t *item) { - invoke(item->val, a, b, c, d, sum); + item->val++; } START_TEST(test_invoke_function) @@ -267,8 +322,7 @@ START_TEST(test_invoke_function) list->insert_last(list, (void*)3); list->insert_last(list, (void*)4); list->insert_last(list, (void*)5); - list->invoke_function(list, (linked_list_invoke_t)invoke, - (uintptr_t)1, (uintptr_t)2, + list->invoke_function(list, invoke, (uintptr_t)1, (uintptr_t)2, (uintptr_t)3, (uintptr_t)4, &sum); ck_assert_int_eq(sum, 15); } @@ -282,17 +336,19 @@ START_TEST(test_invoke_offset) { .val = 3, .invoke = invoke_offset, }, { .val = 4, .invoke = invoke_offset, }, { .val = 5, .invoke = invoke_offset, }, - }; - int i, sum = 0; + }, *item; + int i; for (i = 0; i < countof(items); i++) { list->insert_last(list, &items[i]); } - list->invoke_offset(list, offsetof(invoke_t, invoke), - (uintptr_t)1, (uintptr_t)2, - (uintptr_t)3, (uintptr_t)4, &sum); - ck_assert_int_eq(sum, 15); + list->invoke_offset(list, offsetof(invoke_t, invoke)); + i = 2; + while (list->remove_first(list, (void**)&item) == SUCCESS) + { + ck_assert_int_eq(item->val, i++); + } } END_TEST @@ -458,6 +514,7 @@ Suite *linked_list_suite_create() tcase_add_checked_fixture(tc, setup_list, teardown_list); tcase_add_test(tc, test_find); tcase_add_test(tc, test_find_callback); + tcase_add_test(tc, test_find_callback_args); suite_add_tcase(s, tc); tc = tcase_create("invoke"); diff --git a/src/libstrongswan/tests/test_suite.h b/src/libstrongswan/tests/test_suite.h index 66c68465a..97c1b42c1 100644 --- a/src/libstrongswan/tests/test_suite.h +++ b/src/libstrongswan/tests/test_suite.h @@ -298,7 +298,7 @@ void test_fail_if_worker_failed(); chunk_t _a = (chunk_t)a; \ chunk_t _b = (chunk_t)b; \ test_fail_if_worker_failed(); \ - if (_a.len != _b.len || !memeq(a.ptr, b.ptr, a.len)) \ + if (_a.len != _b.len || !memeq(_a.ptr, _b.ptr, _a.len)) \ { \ test_fail_msg(__FILE__, __LINE__, \ #a " != " #b " (\"%#B\" != \"%#B\")", &_a, &_b); \ diff --git a/src/libstrongswan/utils/backtrace.c b/src/libstrongswan/utils/backtrace.c index 6dd68d60e..18b19166e 100644 --- a/src/libstrongswan/utils/backtrace.c +++ b/src/libstrongswan/utils/backtrace.c @@ -668,8 +668,12 @@ typedef struct { } frame_enumerator_t; METHOD(enumerator_t, frame_enumerate, bool, - frame_enumerator_t *this, void **addr) + frame_enumerator_t *this, va_list args) { + void **addr; + + VA_ARGS_VGET(args, addr); + if (this->i < this->bt->frame_count) { *addr = this->bt->frames[this->i++]; @@ -685,7 +689,8 @@ METHOD(backtrace_t, create_frame_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_frame_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _frame_enumerate, .destroy = (void*)free, }, .bt = this, diff --git a/src/libstrongswan/utils/chunk.c b/src/libstrongswan/utils/chunk.c index 0c50ab788..8f4b7efff 100644 --- a/src/libstrongswan/utils/chunk.c +++ b/src/libstrongswan/utils/chunk.c @@ -643,7 +643,7 @@ chunk_t chunk_from_base64(chunk_t base64, char *buf) outlen += 3; for (j = 0; j < 4; j++) { - if (*pos == '=') + if (*pos == '=' && outlen > 0) { outlen--; } diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c index 384bd6c92..1a4769063 100644 --- a/src/libstrongswan/utils/identification.c +++ b/src/libstrongswan/utils/identification.c @@ -136,9 +136,12 @@ typedef struct { } rdn_enumerator_t; METHOD(enumerator_t, rdn_enumerate, bool, - rdn_enumerator_t *this, chunk_t *oid, u_char *type, chunk_t *data) + rdn_enumerator_t *this, va_list args) { - chunk_t rdn; + chunk_t rdn, *oid, *data; + u_char *type; + + VA_ARGS_VGET(args, oid, type, data); /* a DN contains one or more SET, each containing one or more SEQUENCES, * each containing a OID/value RDN */ @@ -173,7 +176,8 @@ static enumerator_t* create_rdn_enumerator(chunk_t dn) INIT(e, .public = { - .enumerate = (void*)_rdn_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _rdn_enumerate, .destroy = (void*)free, }, ); @@ -199,10 +203,11 @@ typedef struct { } rdn_part_enumerator_t; METHOD(enumerator_t, rdn_part_enumerate, bool, - rdn_part_enumerator_t *this, id_part_t *type, chunk_t *data) + rdn_part_enumerator_t *this, va_list args) { int i, known_oid, strtype; - chunk_t oid, inner_data; + chunk_t oid, inner_data, *data; + id_part_t *type; static const struct { int oid; id_part_t type; @@ -228,6 +233,8 @@ METHOD(enumerator_t, rdn_part_enumerate, bool, {OID_EMPLOYEE_NUMBER, ID_PART_RDN_EN}, }; + VA_ARGS_VGET(args, type, data); + while (this->inner->enumerate(this->inner, &oid, &strtype, &inner_data)) { known_oid = asn1_known_oid(oid); @@ -263,7 +270,8 @@ METHOD(identification_t, create_part_enumerator, enumerator_t*, INIT(e, .inner = create_rdn_enumerator(this->encoded), .public = { - .enumerate = (void*)_rdn_part_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _rdn_part_enumerate, .destroy = _rdn_part_enumerator_destroy, }, ); diff --git a/src/libstrongswan/utils/leak_detective.c b/src/libstrongswan/utils/leak_detective.c index ad67c0380..1dfeea557 100644 --- a/src/libstrongswan/utils/leak_detective.c +++ b/src/libstrongswan/utils/leak_detective.c @@ -606,6 +606,9 @@ static char *whitelist[] = { "system__tasking__stages__create_task", /* in case external threads call into our code */ "thread_current_id", + /* FHH IMCs and IMVs */ + "TNC_IMC_NotifyConnectionChange", + "TNC_IMV_NotifyConnectionChange", }; /** diff --git a/src/libstrongswan/utils/utils.h b/src/libstrongswan/utils/utils.h index 0aed842b1..33b8d1956 100644 --- a/src/libstrongswan/utils/utils.h +++ b/src/libstrongswan/utils/utils.h @@ -1,7 +1,7 @@ /* - * Copyright (C) 2008-2015 Tobias Brunner + * Copyright (C) 2008-2017 Tobias Brunner * Copyright (C) 2008 Martin Willi - * Hochschule fuer Technik Rapperswil + * 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 @@ -28,6 +28,7 @@ #include <stddef.h> #include <sys/time.h> #include <string.h> +#include <stdarg.h> #ifdef HAVE_SYS_PARAM_H #include <sys/param.h> @@ -141,6 +142,49 @@ void utils_deinit(); #define __VA_ARGS_DISPATCH(func, num) func ## num /** + * Assign variadic arguments to the given variables. + * + * @note The order and types of the variables are significant and must match the + * variadic arguments passed to the function that calls this macro exactly. + * + * @param last the last argument before ... in the function that calls this + * @param ... variable names + */ +#define VA_ARGS_GET(last, ...) ({ \ + va_list _va_args_get_ap; \ + va_start(_va_args_get_ap, last); \ + _VA_ARGS_GET_ASGN(__VA_ARGS__) \ + va_end(_va_args_get_ap); \ +}) + +/** + * Assign variadic arguments from a va_list to the given variables. + * + * @note The order and types of the variables are significant and must match the + * variadic arguments passed to the function that calls this macro exactly. + * + * @param list the va_list variable in the function that calls this + * @param ... variable names + */ +#define VA_ARGS_VGET(list, ...) ({ \ + va_list _va_args_get_ap; \ + va_copy(_va_args_get_ap, list); \ + _VA_ARGS_GET_ASGN(__VA_ARGS__) \ + va_end(_va_args_get_ap); \ +}) + +#define _VA_ARGS_GET_ASGN(...) VA_ARGS_DISPATCH(_VA_ARGS_GET_ASGN, __VA_ARGS__)(__VA_ARGS__) +#define _VA_ARGS_GET_ASGN1(v1) __VA_ARGS_GET_ASGN(v1) +#define _VA_ARGS_GET_ASGN2(v1,v2) __VA_ARGS_GET_ASGN(v1) __VA_ARGS_GET_ASGN(v2) +#define _VA_ARGS_GET_ASGN3(v1,v2,v3) __VA_ARGS_GET_ASGN(v1) __VA_ARGS_GET_ASGN(v2) \ + __VA_ARGS_GET_ASGN(v3) +#define _VA_ARGS_GET_ASGN4(v1,v2,v3,v4) __VA_ARGS_GET_ASGN(v1) __VA_ARGS_GET_ASGN(v2) \ + __VA_ARGS_GET_ASGN(v3) __VA_ARGS_GET_ASGN(v4) +#define _VA_ARGS_GET_ASGN5(v1,v2,v3,v4,v5) __VA_ARGS_GET_ASGN(v1) __VA_ARGS_GET_ASGN(v2) \ + __VA_ARGS_GET_ASGN(v3) __VA_ARGS_GET_ASGN(v4) __VA_ARGS_GET_ASGN(v5) +#define __VA_ARGS_GET_ASGN(v) v = va_arg(_va_args_get_ap, typeof(v)); + +/** * Macro to allocate a sized type. */ #define malloc_thing(thing) ((thing*)malloc(sizeof(thing))) diff --git a/src/libtls/Makefile.in b/src/libtls/Makefile.in index 197ffc479..ee1d7fc7e 100644 --- a/src/libtls/Makefile.in +++ b/src/libtls/Makefile.in @@ -408,6 +408,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -430,6 +431,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libtls/tests/Makefile.in b/src/libtls/tests/Makefile.in index 22eb0994e..8c87e1dd0 100644 --- a/src/libtls/tests/Makefile.in +++ b/src/libtls/tests/Makefile.in @@ -352,6 +352,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -374,6 +375,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libtls/tls_crypto.c b/src/libtls/tls_crypto.c index 84b511f53..05ae62b49 100644 --- a/src/libtls/tls_crypto.c +++ b/src/libtls/tls_crypto.c @@ -1296,28 +1296,32 @@ static struct { { ECP_192_BIT, TLS_SECP192R1}, }; -/** - * Filter EC groups, add TLS curve - */ -static bool group_filter(void *null, - diffie_hellman_group_t *in, diffie_hellman_group_t *out, - void* dummy1, tls_named_curve_t *curve) +CALLBACK(group_filter, bool, + void *null, enumerator_t *orig, va_list args) { + diffie_hellman_group_t group, *out; + tls_named_curve_t *curve; + char *plugin; int i; - for (i = 0; i < countof(curves); i++) + VA_ARGS_VGET(args, out, curve); + + while (orig->enumerate(orig, &group, &plugin)) { - if (curves[i].group == *in) + for (i = 0; i < countof(curves); i++) { - if (out) - { - *out = curves[i].group; - } - if (curve) + if (curves[i].group == group) { - *curve = curves[i].curve; + if (out) + { + *out = curves[i].group; + } + if (curve) + { + *curve = curves[i].curve; + } + return TRUE; } - return TRUE; } } return FALSE; @@ -1327,8 +1331,8 @@ METHOD(tls_crypto_t, create_ec_enumerator, enumerator_t*, private_tls_crypto_t *this) { return enumerator_create_filter( - lib->crypto->create_dh_enumerator(lib->crypto), - (void*)group_filter, NULL, NULL); + lib->crypto->create_dh_enumerator(lib->crypto), + group_filter, NULL, NULL); } METHOD(tls_crypto_t, set_protection, void, diff --git a/src/libtnccs/Makefile.am b/src/libtnccs/Makefile.am index 7a630fe54..ff7b54f6a 100644 --- a/src/libtnccs/Makefile.am +++ b/src/libtnccs/Makefile.am @@ -26,6 +26,15 @@ tnc/tnccs/tnccs_manager.h tnc/tnccs/tnccs_manager.c EXTRA_DIST = Android.mk +if STATIC_PLUGIN_CONSTRUCTORS +BUILT_SOURCES = $(srcdir)/plugin_constructors.c +CLEANFILES = $(srcdir)/plugin_constructors.c + +$(srcdir)/plugin_constructors.c: $(top_srcdir)/src/libstrongswan/plugins/plugin_constructors.py + $(AM_V_GEN) \ + $(PYTHON) $(top_srcdir)/src/libstrongswan/plugins/plugin_constructors.py ${t_plugins} > $@ +endif + # build optional plugins ######################## diff --git a/src/libtnccs/Makefile.in b/src/libtnccs/Makefile.in index a22a631bc..653d841a3 100644 --- a/src/libtnccs/Makefile.in +++ b/src/libtnccs/Makefile.in @@ -412,6 +412,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -434,6 +435,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ @@ -521,6 +523,8 @@ tnc/tnccs/tnccs.h tnc/tnccs/tnccs.c \ tnc/tnccs/tnccs_manager.h tnc/tnccs/tnccs_manager.c EXTRA_DIST = Android.mk +@STATIC_PLUGIN_CONSTRUCTORS_TRUE@BUILT_SOURCES = $(srcdir)/plugin_constructors.c +@STATIC_PLUGIN_CONSTRUCTORS_TRUE@CLEANFILES = $(srcdir)/plugin_constructors.c @MONOLITHIC_FALSE@SUBDIRS = . $(am__append_2) $(am__append_4) \ @MONOLITHIC_FALSE@ $(am__append_6) $(am__append_8) \ @MONOLITHIC_FALSE@ $(am__append_10) $(am__append_12) @@ -530,7 +534,8 @@ EXTRA_DIST = Android.mk @MONOLITHIC_TRUE@SUBDIRS = $(am__append_2) $(am__append_4) \ @MONOLITHIC_TRUE@ $(am__append_6) $(am__append_8) \ @MONOLITHIC_TRUE@ $(am__append_10) $(am__append_12) -all: all-recursive +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .c .lo .o .obj @@ -832,14 +837,16 @@ distdir: $(DISTFILES) fi; \ done check-am: all-am -check: check-recursive +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive all-am: Makefile $(LTLIBRARIES) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(ipseclibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done -install: install-recursive +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive @@ -861,6 +868,7 @@ install-strip: mostlyclean-generic: clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) @@ -875,6 +883,7 @@ distclean-generic: maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-recursive clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \ @@ -946,7 +955,8 @@ ps-am: uninstall-am: uninstall-ipseclibLTLIBRARIES -.MAKE: $(am__recursive_targets) install-am install-strip +.MAKE: $(am__recursive_targets) all check install install-am \ + install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-ipseclibLTLIBRARIES \ @@ -967,6 +977,10 @@ uninstall-am: uninstall-ipseclibLTLIBRARIES .PRECIOUS: Makefile +@STATIC_PLUGIN_CONSTRUCTORS_TRUE@$(srcdir)/plugin_constructors.c: $(top_srcdir)/src/libstrongswan/plugins/plugin_constructors.py +@STATIC_PLUGIN_CONSTRUCTORS_TRUE@ $(AM_V_GEN) \ +@STATIC_PLUGIN_CONSTRUCTORS_TRUE@ $(PYTHON) $(top_srcdir)/src/libstrongswan/plugins/plugin_constructors.py ${t_plugins} > $@ + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/src/libtnccs/plugins/tnc_imc/Makefile.in b/src/libtnccs/plugins/tnc_imc/Makefile.in index 2d04cc10e..84dbf1461 100644 --- a/src/libtnccs/plugins/tnc_imc/Makefile.in +++ b/src/libtnccs/plugins/tnc_imc/Makefile.in @@ -360,6 +360,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -382,6 +383,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libtnccs/plugins/tnc_imv/Makefile.in b/src/libtnccs/plugins/tnc_imv/Makefile.in index cfdd73c19..5fd128faa 100644 --- a/src/libtnccs/plugins/tnc_imv/Makefile.in +++ b/src/libtnccs/plugins/tnc_imv/Makefile.in @@ -361,6 +361,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -383,6 +384,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libtnccs/plugins/tnc_imv/tnc_imv_recommendations.c b/src/libtnccs/plugins/tnc_imv/tnc_imv_recommendations.c index a9dbb2b9f..9c6307d65 100644 --- a/src/libtnccs/plugins/tnc_imv/tnc_imv_recommendations.c +++ b/src/libtnccs/plugins/tnc_imv/tnc_imv_recommendations.c @@ -320,31 +320,33 @@ METHOD(recommendations_t, set_reason_language, TNC_Result, return found ? TNC_RESULT_SUCCESS : TNC_RESULT_INVALID_PARAMETER; } -/** - * Enumerate reason and reason_language, not recommendation entries - */ -static bool reason_filter(void *null, recommendation_entry_t **entry, - TNC_IMVID *id, void *i2, chunk_t *reason, void *i3, - chunk_t *reason_language) +CALLBACK(reason_filter, bool, + void *null, enumerator_t *orig, va_list args) { - if ((*entry)->reason.len) - { - *id = (*entry)->id; - *reason = (*entry)->reason; - *reason_language = (*entry)->reason_language; - return TRUE; - } - else + recommendation_entry_t *entry; + TNC_IMVID *id; + chunk_t *reason, *reason_language; + + VA_ARGS_VGET(args, id, reason, reason_language); + + while (orig->enumerate(orig, &entry)) { - return FALSE; + if (entry->reason.len) + { + *id = entry->id; + *reason = entry->reason; + *reason_language = entry->reason_language; + return TRUE; + } } + return FALSE; } METHOD(recommendations_t, create_reason_enumerator, enumerator_t*, private_tnc_imv_recommendations_t *this) { return enumerator_create_filter(this->recs->create_enumerator(this->recs), - (void*)reason_filter, NULL, NULL); + reason_filter, NULL, NULL); } METHOD(recommendations_t, destroy, void, diff --git a/src/libtnccs/plugins/tnc_tnccs/Makefile.in b/src/libtnccs/plugins/tnc_tnccs/Makefile.in index 094d3be9d..acddd84a2 100644 --- a/src/libtnccs/plugins/tnc_tnccs/Makefile.in +++ b/src/libtnccs/plugins/tnc_tnccs/Makefile.in @@ -360,6 +360,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -382,6 +383,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libtnccs/plugins/tnccs_11/Makefile.in b/src/libtnccs/plugins/tnccs_11/Makefile.in index d816d6b10..b6b80749b 100644 --- a/src/libtnccs/plugins/tnccs_11/Makefile.in +++ b/src/libtnccs/plugins/tnccs_11/Makefile.in @@ -370,6 +370,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -392,6 +393,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libtnccs/plugins/tnccs_11/tnccs_11_plugin.c b/src/libtnccs/plugins/tnccs_11/tnccs_11_plugin.c index f534af008..191adbb77 100644 --- a/src/libtnccs/plugins/tnccs_11/tnccs_11_plugin.c +++ b/src/libtnccs/plugins/tnccs_11/tnccs_11_plugin.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Andreas Steffen + * Copyright (C) 2010-2017 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -17,6 +17,7 @@ #include "tnccs_11.h" #include <tnc/tnccs/tnccs_manager.h> +#include <libxml/parser.h> METHOD(plugin_t, get_name, char*, tnccs_11_plugin_t *this) @@ -39,6 +40,7 @@ METHOD(plugin_t, get_features, int, METHOD(plugin_t, destroy, void, tnccs_11_plugin_t *this) { + xmlCleanupParser(); free(this); } @@ -56,6 +58,7 @@ plugin_t *tnccs_11_plugin_create() .destroy = _destroy, }, ); + xmlInitParser(); return &this->plugin; } diff --git a/src/libtnccs/plugins/tnccs_20/Makefile.in b/src/libtnccs/plugins/tnccs_20/Makefile.in index a64288fa1..2a1d327b4 100644 --- a/src/libtnccs/plugins/tnccs_20/Makefile.in +++ b/src/libtnccs/plugins/tnccs_20/Makefile.in @@ -373,6 +373,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -395,6 +396,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libtnccs/plugins/tnccs_dynamic/Makefile.in b/src/libtnccs/plugins/tnccs_dynamic/Makefile.in index 043e64d9a..65201ddaa 100644 --- a/src/libtnccs/plugins/tnccs_dynamic/Makefile.in +++ b/src/libtnccs/plugins/tnccs_dynamic/Makefile.in @@ -360,6 +360,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -382,6 +383,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libtnccs/tnc/tnc.c b/src/libtnccs/tnc/tnc.c index 80ba61c5a..9627be862 100644 --- a/src/libtnccs/tnc/tnc.c +++ b/src/libtnccs/tnc/tnc.c @@ -55,6 +55,13 @@ struct private_tnc_t { }; /** + * Register plugins if built statically + */ +#ifdef STATIC_PLUGIN_CONSTRUCTORS +#include "plugin_constructors.c" +#endif + +/** * Single instance of tnc_t. */ tnc_t *tnc; diff --git a/src/libtncif/Makefile.in b/src/libtncif/Makefile.in index 77c950a60..2432a704f 100644 --- a/src/libtncif/Makefile.in +++ b/src/libtncif/Makefile.in @@ -322,6 +322,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -344,6 +345,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libtpmtss/Makefile.am b/src/libtpmtss/Makefile.am index c7ac39a09..5f3a97a99 100644 --- a/src/libtpmtss/Makefile.am +++ b/src/libtpmtss/Makefile.am @@ -33,6 +33,15 @@ else SUBDIRS = . endif +if STATIC_PLUGIN_CONSTRUCTORS +BUILT_SOURCES = $(srcdir)/plugin_constructors.c +CLEANFILES = $(srcdir)/plugin_constructors.c + +$(srcdir)/plugin_constructors.c: $(top_srcdir)/src/libstrongswan/plugins/plugin_constructors.py + $(AM_V_GEN) \ + $(PYTHON) $(top_srcdir)/src/libstrongswan/plugins/plugin_constructors.py ${p_plugins} > $@ +endif + if USE_TPM SUBDIRS += plugins/tpm if MONOLITHIC diff --git a/src/libtpmtss/Makefile.in b/src/libtpmtss/Makefile.in index 1a19fb5c8..405d717d9 100644 --- a/src/libtpmtss/Makefile.in +++ b/src/libtpmtss/Makefile.in @@ -400,6 +400,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -422,6 +423,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ @@ -508,7 +510,10 @@ libtpmtss_la_SOURCES = \ @MONOLITHIC_FALSE@SUBDIRS = . $(am__append_3) @MONOLITHIC_TRUE@SUBDIRS = $(am__append_3) -all: all-recursive +@STATIC_PLUGIN_CONSTRUCTORS_TRUE@BUILT_SOURCES = $(srcdir)/plugin_constructors.c +@STATIC_PLUGIN_CONSTRUCTORS_TRUE@CLEANFILES = $(srcdir)/plugin_constructors.c +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-recursive .SUFFIXES: .SUFFIXES: .c .lo .o .obj @@ -777,14 +782,16 @@ distdir: $(DISTFILES) fi; \ done check-am: all-am -check: check-recursive +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive all-am: Makefile $(LTLIBRARIES) installdirs: installdirs-recursive installdirs-am: for dir in "$(DESTDIR)$(ipseclibdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done -install: install-recursive +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive @@ -806,6 +813,7 @@ install-strip: mostlyclean-generic: clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) @@ -814,6 +822,7 @@ distclean-generic: maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) clean: clean-recursive clean-am: clean-generic clean-ipseclibLTLIBRARIES clean-libtool \ @@ -885,7 +894,8 @@ ps-am: uninstall-am: uninstall-ipseclibLTLIBRARIES -.MAKE: $(am__recursive_targets) install-am install-strip +.MAKE: $(am__recursive_targets) all check install install-am \ + install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-ipseclibLTLIBRARIES \ @@ -906,6 +916,10 @@ uninstall-am: uninstall-ipseclibLTLIBRARIES .PRECIOUS: Makefile +@STATIC_PLUGIN_CONSTRUCTORS_TRUE@$(srcdir)/plugin_constructors.c: $(top_srcdir)/src/libstrongswan/plugins/plugin_constructors.py +@STATIC_PLUGIN_CONSTRUCTORS_TRUE@ $(AM_V_GEN) \ +@STATIC_PLUGIN_CONSTRUCTORS_TRUE@ $(PYTHON) $(top_srcdir)/src/libstrongswan/plugins/plugin_constructors.py ${p_plugins} > $@ + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/src/libtpmtss/plugins/tpm/Makefile.in b/src/libtpmtss/plugins/tpm/Makefile.in index 9e2641bc6..eb9489eb4 100644 --- a/src/libtpmtss/plugins/tpm/Makefile.in +++ b/src/libtpmtss/plugins/tpm/Makefile.in @@ -357,6 +357,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -379,6 +380,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/libtpmtss/tpm_tss.c b/src/libtpmtss/tpm_tss.c index b7b970c8d..42a341896 100644 --- a/src/libtpmtss/tpm_tss.c +++ b/src/libtpmtss/tpm_tss.c @@ -18,6 +18,13 @@ #include "tpm_tss_trousers.h" /** + * Register plugins if built statically + */ +#ifdef STATIC_PLUGIN_CONSTRUCTORS +#include "plugin_constructors.c" +#endif + +/** * Described in header. */ void libtpmtss_init(void) diff --git a/src/manager/Makefile.in b/src/manager/Makefile.in index 8b0a40245..58c247e1b 100644 --- a/src/manager/Makefile.in +++ b/src/manager/Makefile.in @@ -374,6 +374,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -396,6 +397,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/manager/xml.c b/src/manager/xml.c index bf5bbbf05..0aee5f69b 100644 --- a/src/manager/xml.c +++ b/src/manager/xml.c @@ -67,8 +67,13 @@ typedef struct { } child_enum_t; METHOD(enumerator_t, child_enumerate, bool, - child_enum_t *e, private_xml_t **child, char **name, char **value) + child_enum_t *e, va_list args) { + private_xml_t **child; + char **name, **value; + + VA_ARGS_VGET(args, child, name, value); + while (e->node && e->node->type != XML_ELEMENT_NODE) { e->node = e->node->next; @@ -120,7 +125,8 @@ METHOD(xml_t, children, enumerator_t*, child_enum_t *ce; INIT(ce, .e = { - .enumerate = (void*)_child_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _child_enumerate, .destroy = _child_destroy, }, .child = { diff --git a/src/medsrv/Makefile.in b/src/medsrv/Makefile.in index 249728b69..7561ad91c 100644 --- a/src/medsrv/Makefile.in +++ b/src/medsrv/Makefile.in @@ -363,6 +363,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -385,6 +386,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/pki/Makefile.in b/src/pki/Makefile.in index 72d554a48..ed95d812a 100644 --- a/src/pki/Makefile.in +++ b/src/pki/Makefile.in @@ -376,6 +376,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -398,6 +399,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/pki/commands/issue.c b/src/pki/commands/issue.c index b0399c78b..e41c56d08 100644 --- a/src/pki/commands/issue.c +++ b/src/pki/commands/issue.c @@ -406,6 +406,7 @@ static int issue() goto end; } public->destroy(public); + public = NULL; if (hex) { diff --git a/src/pki/commands/signcrl.c b/src/pki/commands/signcrl.c index 6bccf1b09..25a3aac52 100644 --- a/src/pki/commands/signcrl.c +++ b/src/pki/commands/signcrl.c @@ -61,16 +61,24 @@ static void revoked_destroy(revoked_t *revoked) free(revoked); } -/** - * Filter for revoked enumerator - */ -static bool filter(void *data, revoked_t **revoked, chunk_t *serial, void *p2, - time_t *date, void *p3, crl_reason_t *reason) +CALLBACK(filter, bool, + void *data, enumerator_t *orig, va_list args) { - *serial = (*revoked)->serial; - *date = (*revoked)->date; - *reason = (*revoked)->reason; - return TRUE; + revoked_t *revoked; + crl_reason_t *reason; + chunk_t *serial; + time_t *date; + + VA_ARGS_VGET(args, serial, date, reason); + + if (orig->enumerate(orig, &revoked)) + { + *serial = revoked->serial; + *date = revoked->date; + *reason = revoked->reason; + return TRUE; + } + return FALSE; } /** @@ -392,7 +400,7 @@ static int sign_crl() chunk_increment(crl_serial); enumerator = enumerator_create_filter(list->create_enumerator(list), - (void*)filter, NULL, NULL); + filter, NULL, NULL); crl = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509_CRL, BUILD_SIGNING_KEY, private, BUILD_SIGNING_CERT, ca, BUILD_SERIAL, crl_serial, diff --git a/src/pki/man/Makefile.in b/src/pki/man/Makefile.in index e40aca3b4..a469f8b1c 100644 --- a/src/pki/man/Makefile.in +++ b/src/pki/man/Makefile.in @@ -313,6 +313,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -335,6 +336,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/pool/Makefile.in b/src/pool/Makefile.in index d67830ea8..415de5503 100644 --- a/src/pool/Makefile.in +++ b/src/pool/Makefile.in @@ -358,6 +358,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -380,6 +381,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/pt-tls-client/Makefile.in b/src/pt-tls-client/Makefile.in index 2c87f5fa5..7912c6058 100644 --- a/src/pt-tls-client/Makefile.in +++ b/src/pt-tls-client/Makefile.in @@ -327,6 +327,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -349,6 +350,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/scepclient/Makefile.in b/src/scepclient/Makefile.in index 47b0c8c3d..9b2023f7d 100644 --- a/src/scepclient/Makefile.in +++ b/src/scepclient/Makefile.in @@ -355,6 +355,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -377,6 +378,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/starter/Makefile.in b/src/starter/Makefile.in index 3c89b0c77..97a0713c3 100644 --- a/src/starter/Makefile.in +++ b/src/starter/Makefile.in @@ -400,6 +400,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -422,6 +423,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/starter/args.c b/src/starter/args.c index 0874cc7e5..477a52082 100644 --- a/src/starter/args.c +++ b/src/starter/args.c @@ -110,6 +110,7 @@ static const char *LST_authby[] = { static const char *LST_fragmentation[] = { "no", + "accept", "yes", "force", NULL @@ -164,6 +165,7 @@ static const token_info_t token_info[] = { ARG_TIME, offsetof(starter_conn_t, dpd_timeout), NULL }, { ARG_ENUM, offsetof(starter_conn_t, dpd_action), LST_dpd_action }, { ARG_ENUM, offsetof(starter_conn_t, close_action), LST_dpd_action }, + { ARG_ENUM, offsetof(starter_conn_t, sha256_96), LST_bool }, { ARG_TIME, offsetof(starter_conn_t, inactivity), NULL }, { ARG_MISC, 0, NULL /* KW_MODECONFIG */ }, { ARG_MISC, 0, NULL /* KW_XAUTH */ }, diff --git a/src/starter/confread.h b/src/starter/confread.h index 45f34ce23..8ee730daa 100644 --- a/src/starter/confread.h +++ b/src/starter/confread.h @@ -65,6 +65,7 @@ typedef enum { typedef enum { /* same as in ike_cfg.h */ FRAGMENTATION_NO, + FRAGMENTATION_ACCEPT, FRAGMENTATION_YES, FRAGMENTATION_FORCE, } fragmentation_t; @@ -161,6 +162,8 @@ struct starter_conn { dpd_action_t close_action; + bool sha256_96; + time_t inactivity; bool me_mediation; diff --git a/src/starter/keywords.c b/src/starter/keywords.c index 762c5d947..505b66010 100644 --- a/src/starter/keywords.c +++ b/src/starter/keywords.c @@ -54,7 +54,7 @@ struct kw_entry { kw_token_t token; }; -#define TOTAL_KEYWORDS 139 +#define TOTAL_KEYWORDS 140 #define MIN_WORD_LENGTH 2 #define MAX_WORD_LENGTH 17 #define MIN_HASH_VALUE 9 @@ -80,7 +80,7 @@ hash (str, len) 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 14, - 129, 258, 258, 258, 258, 258, 258, 258, 258, 258, + 129, 258, 258, 258, 4, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, 258, @@ -202,6 +202,7 @@ static const struct kw_entry wordlist[] = {"klipsdebug", KW_SETUP_DEPRECATED}, {"ldapbase", KW_CA_DEPRECATED}, {"overridemtu", KW_SETUP_DEPRECATED}, + {"sha256_96", KW_SHA256_96}, {"ocspuri1", KW_OCSPURI}, {"dpdtimeout", KW_DPDTIMEOUT}, {"aaa_identity", KW_AAA_IDENTITY}, @@ -278,20 +279,20 @@ static const short lookup[] = 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, -1, -1, 60, 61, 62, -1, 63, -1, 64, -1, 65, 66, 67, 68, 69, 70, 71, 72, - -1, 73, 74, 75, 76, 77, 78, -1, 79, -1, - -1, 80, 81, -1, 82, -1, -1, 83, 84, 85, - 86, 87, 88, -1, 89, -1, 90, 91, -1, 92, - 93, -1, 94, 95, -1, 96, -1, -1, 97, 98, - 99, 100, -1, 101, -1, 102, 103, 104, -1, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - -1, 116, -1, 117, -1, 118, -1, -1, 119, 120, - -1, -1, -1, -1, -1, 121, -1, 122, -1, 123, - 124, 125, -1, -1, -1, -1, -1, 126, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 127, -1, - -1, 128, 129, -1, 130, -1, 131, -1, -1, -1, - -1, -1, -1, 132, -1, 133, -1, 134, 135, -1, - -1, -1, -1, 136, -1, -1, -1, -1, -1, -1, - 137, -1, -1, -1, -1, -1, -1, 138 + -1, 73, 74, 75, 76, 77, 78, 79, 80, -1, + -1, 81, 82, -1, 83, -1, -1, 84, 85, 86, + 87, 88, 89, -1, 90, -1, 91, 92, -1, 93, + 94, -1, 95, 96, -1, 97, -1, -1, 98, 99, + 100, 101, -1, 102, -1, 103, 104, 105, -1, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + -1, 117, -1, 118, -1, 119, -1, -1, 120, 121, + -1, -1, -1, -1, -1, 122, -1, 123, -1, 124, + 125, 126, -1, -1, -1, -1, -1, 127, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 128, -1, + -1, 129, 130, -1, 131, -1, 132, -1, -1, -1, + -1, -1, -1, 133, -1, 134, -1, 135, 136, -1, + -1, -1, -1, 137, -1, -1, -1, -1, -1, -1, + 138, -1, -1, -1, -1, -1, -1, 139 }; #ifdef __GNUC__ diff --git a/src/starter/keywords.h b/src/starter/keywords.h index 94af493f8..0cb46a740 100644 --- a/src/starter/keywords.h +++ b/src/starter/keywords.h @@ -64,6 +64,7 @@ enum kw_token_t { KW_DPDTIMEOUT, KW_DPDACTION, KW_CLOSEACTION, + KW_SHA256_96, KW_INACTIVITY, KW_MODECONFIG, KW_XAUTH, diff --git a/src/starter/keywords.txt b/src/starter/keywords.txt index ee0bd31e1..3f92dc83f 100644 --- a/src/starter/keywords.txt +++ b/src/starter/keywords.txt @@ -61,6 +61,7 @@ dpddelay, KW_DPDDELAY dpdtimeout, KW_DPDTIMEOUT dpdaction, KW_DPDACTION closeaction, KW_CLOSEACTION +sha256_96, KW_SHA256_96 inactivity, KW_INACTIVITY modeconfig, KW_MODECONFIG xauth, KW_XAUTH diff --git a/src/starter/parser/conf_parser.c b/src/starter/parser/conf_parser.c index 6d1c54d20..66e0ae8e4 100644 --- a/src/starter/parser/conf_parser.c +++ b/src/starter/parser/conf_parser.c @@ -158,10 +158,13 @@ typedef struct { } dictionary_enumerator_t; METHOD(enumerator_t, dictionary_enumerate, bool, - dictionary_enumerator_t *this, char **key, char **value) + dictionary_enumerator_t *this, va_list args) { setting_t *setting; section_t *parent; + char **key, **value; + + VA_ARGS_VGET(args, key, value); while (TRUE) { @@ -221,7 +224,8 @@ METHOD(dictionary_t, dictionary_create_enumerator, enumerator_t*, INIT(enumerator, .public = { - .enumerate = (void*)_dictionary_enumerate, + .enumerate = enumerator_enumerate_default, + .venumerate = _dictionary_enumerate, .destroy = _dictionary_enumerator_destroy, }, .seen = hashtable_create(hashtable_hash_str, hashtable_equals_str, 8), @@ -290,24 +294,43 @@ static dictionary_t *section_dictionary_create(private_conf_parser_t *parser, return &this->public; } -static bool conn_filter(void *unused, section_t **section, char **name) +CALLBACK(conn_filter, bool, + void *unused, enumerator_t *orig, va_list args) { - if (streq((*section)->name, "%default")) + section_t *section; + char **name; + + VA_ARGS_VGET(args, name); + + while (orig->enumerate(orig, §ion)) { - return FALSE; + if (!streq(section->name, "%default")) + { + *name = section->name; + return TRUE; + } } - *name = (*section)->name; - return TRUE; + return FALSE; } -static bool ca_filter(void *unused, void *key, char **name, section_t **section) +CALLBACK(ca_filter, bool, + void *unused, enumerator_t *orig, va_list args) { - if (streq((*section)->name, "%default")) + void *key; + section_t *section; + char **name; + + VA_ARGS_VGET(args, name); + + while (orig->enumerate(orig, &key, §ion)) { - return FALSE; + if (!streq(section->name, "%default")) + { + *name = section->name; + return TRUE; + } } - *name = (*section)->name; - return TRUE; + return FALSE; } METHOD(conf_parser_t, get_sections, enumerator_t*, @@ -317,12 +340,12 @@ METHOD(conf_parser_t, get_sections, enumerator_t*, { case CONF_PARSER_CONN: return enumerator_create_filter( - array_create_enumerator(this->conns_order), - (void*)conn_filter, NULL, NULL); + array_create_enumerator(this->conns_order), + conn_filter, NULL, NULL); case CONF_PARSER_CA: return enumerator_create_filter( - this->cas->create_enumerator(this->cas), - (void*)ca_filter, NULL, NULL); + this->cas->create_enumerator(this->cas), + ca_filter, NULL, NULL); case CONF_PARSER_CONFIG_SETUP: default: return enumerator_create_empty(); diff --git a/src/starter/starterstroke.c b/src/starter/starterstroke.c index b92c00c87..90af9372a 100644 --- a/src/starter/starterstroke.c +++ b/src/starter/starterstroke.c @@ -220,6 +220,7 @@ int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn) msg->add_conn.dpd.timeout = conn->dpd_timeout; msg->add_conn.dpd.action = conn->dpd_action; msg->add_conn.close_action = conn->close_action; + msg->add_conn.sha256_96 = conn->sha256_96; msg->add_conn.inactivity = conn->inactivity; msg->add_conn.ikeme.mediation = conn->me_mediation; push_string(&msg, add_conn.ikeme.mediated_by, conn->me_mediated_by); diff --git a/src/starter/tests/Makefile.in b/src/starter/tests/Makefile.in index 8e9028a7e..6ce8bdaee 100644 --- a/src/starter/tests/Makefile.in +++ b/src/starter/tests/Makefile.in @@ -352,6 +352,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -374,6 +375,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/stroke/Makefile.in b/src/stroke/Makefile.in index fff0a5ea0..6af83d9b7 100644 --- a/src/stroke/Makefile.in +++ b/src/stroke/Makefile.in @@ -326,6 +326,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -348,6 +349,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/stroke/stroke_msg.h b/src/stroke/stroke_msg.h index a3b911d0f..60ea0028d 100644 --- a/src/stroke/stroke_msg.h +++ b/src/stroke/stroke_msg.h @@ -302,6 +302,7 @@ struct stroke_msg_t { } mark_in, mark_out; stroke_end_t me, other; uint32_t replay_window; + bool sha256_96; } add_conn; /* data for STR_ADD_CA */ diff --git a/src/swanctl/Makefile.in b/src/swanctl/Makefile.in index 7e2a1da6b..b5313a37d 100644 --- a/src/swanctl/Makefile.in +++ b/src/swanctl/Makefile.in @@ -375,6 +375,7 @@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ fips_mode = @fips_mode@ +fuzz_plugins = @fuzz_plugins@ gtk_CFLAGS = @gtk_CFLAGS@ gtk_LIBS = @gtk_LIBS@ host = @host@ @@ -397,6 +398,7 @@ json_CFLAGS = @json_CFLAGS@ json_LIBS = @json_LIBS@ libdir = @libdir@ libexecdir = @libexecdir@ +libfuzzer = @libfuzzer@ libiptc_CFLAGS = @libiptc_CFLAGS@ libiptc_LIBS = @libiptc_LIBS@ linux_headers = @linux_headers@ diff --git a/src/swanctl/commands/load_creds.c b/src/swanctl/commands/load_creds.c index 848d8512c..d8541061e 100644 --- a/src/swanctl/commands/load_creds.c +++ b/src/swanctl/commands/load_creds.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Tobias Brunner + * Copyright (C) 2016-2017 Tobias Brunner * Copyright (C) 2015 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * @@ -34,8 +34,6 @@ #include <vici_cert_info.h> -#define HASH_SIZE_SHA1_HEX (2 * HASH_SIZE_SHA1) - /** * Context used to track loaded secrets */ @@ -144,6 +142,7 @@ static bool load_key(load_ctx_t *ctx, char *dir, char *type, chunk_t data) vici_req_t *req; vici_res_t *res; bool ret = TRUE; + char *id; req = vici_begin("load-key"); @@ -178,6 +177,8 @@ static bool load_key(load_ctx_t *ctx, char *dir, char *type, chunk_t data) else { printf("loaded %s key from '%s'\n", type, dir); + id = vici_find_str(res, "", "id"); + free(ctx->keys->remove(ctx->keys, id)); } vici_free_res(res); return ret; @@ -190,8 +191,7 @@ static bool load_key_anytype(load_ctx_t *ctx, char *path, private_key_t *private) { bool loaded = FALSE; - chunk_t encoding, keyid; - char hex[HASH_SIZE_SHA1_HEX + 1]; + chunk_t encoding; if (!private->get_encoding(private, PRIVKEY_ASN1_DER, &encoding)) { @@ -213,13 +213,6 @@ static bool load_key_anytype(load_ctx_t *ctx, char *path, fprintf(stderr, "unsupported key type in '%s'\n", path); break; } - - if (loaded && - private->get_fingerprint(private, KEYID_PUBKEY_SHA1, &keyid) && - snprintf(hex, sizeof(hex), "%+B", &keyid) == HASH_SIZE_SHA1_HEX) - { - free(ctx->keys->remove(ctx->keys, hex)); - } chunk_clear(&encoding); return loaded; } @@ -408,7 +401,7 @@ static void* decrypt_with_config(load_ctx_t *ctx, char *name, char *type, /** * Try to decrypt and load a private key */ -static bool load_encrypted_key(load_ctx_t *ctx, char *rel, char *path, +static bool load_encrypted_key(load_ctx_t *ctx, char *rel, char *path, char *type, chunk_t data) { private_key_t *private; diff --git a/src/swanctl/swanctl.conf b/src/swanctl/swanctl.conf index 789b128fd..b2045a3d8 100644 --- a/src/swanctl/swanctl.conf +++ b/src/swanctl/swanctl.conf @@ -47,7 +47,7 @@ # Timeout for DPD checks (IKEV1 only). # dpd_timeout = 0s - # Use IKE UDP datagram fragmentation. (yes, no or force). + # Use IKE UDP datagram fragmentation. (yes, accept, no or force). # fragmentation = yes # Send certificate requests payloads (yes or no). @@ -227,6 +227,9 @@ # ESP proposals to offer for the CHILD_SA. # esp_proposals = default + # Use incorrect 96-bit truncation for HMAC-SHA-256. + # sha256_96 = no + # Local traffic selectors to include in CHILD_SA. # local_ts = dynamic @@ -308,6 +311,10 @@ # IPsec replay window to configure for this CHILD_SA. # replay_window = 32 + # Enable hardware offload for this CHILD_SA, if supported by the + # IPsec implementation. + # hw_offload = no + # Action to perform after loading the configuration (none, trap, # start). # start_action = none diff --git a/src/swanctl/swanctl.conf.5.main b/src/swanctl/swanctl.conf.5.main index 6e1e9adfb..9f4044d7e 100644 --- a/src/swanctl/swanctl.conf.5.main +++ b/src/swanctl/swanctl.conf.5.main @@ -168,18 +168,29 @@ Use IKE fragmentation (proprietary IKEv1 extension or RFC 7383 IKEv2 fragmentation). Acceptable values are .RI "" "yes" "" (the default), +.RI "" "accept" "," .RI "" "force" "" and .RI "" "no" "." -Fragmented IKE messages sent by a peer are always accepted irrespective of -the value of this option. If set to +If set to .RI "" "yes" "," -and the peer supports it, -oversized IKE messages will be sent in fragments. If set to +and the peer supports it, oversized IKE +messages will be sent in fragments. If set to +.RI "" "accept" "," +support for +fragmentation is announced to the peer but the daemon does not send its own +messages in fragments. If set to .RI "" "force" "" -(only -supported for IKEv1) the initial IKE message will already be fragmented if -required. +(only supported for IKEv1) the initial +IKE message will already be fragmented if required. Finally, setting the option +to +.RI "" "no" "" +will disable announcing support for this feature. + +Note that fragmented IKE messages sent by a peer are always accepted +irrespective of the value of this option (even when set to +.RI "" "no" ")." + .TP .BR connections.<conn>.send_certreq " [yes]" @@ -786,6 +797,14 @@ interoperability. If no algorithms are specified for AH nor ESP, the set of algorithms for ESP is included. .TP +.BR connections.<conn>.children.<child>.sha256_96 " [no]" +HMAC\-SHA\-256 is used with 128\-bit truncation with IPsec. For compatibility with +implementations that incorrectly use 96\-bit truncation this option may be +enabled to configure the shorter truncation length in the kernel. This is not +negotiated, so this only works with peers that use the incorrect truncation +length (or have this option enabled). + +.TP .BR connections.<conn>.children.<child>.local_ts " [dynamic]" Comma separated list of local traffic selectors to include in CHILD_SA. Each selector is a CIDR subnet definition, followed by an optional proto/port @@ -1065,6 +1084,11 @@ default of 32 are supported using the Netlink backend only, a value of 0 disables IPsec replay protection. .TP +.BR connections.<conn>.children.<child>.hw_offload " [no]" +Enable hardware offload for this CHILD_SA, if supported by the IPsec +implementation. + +.TP .BR connections.<conn>.children.<child>.start_action " [none]" Action to perform after loading the configuration. The default of .RI "" "none" "" diff --git a/src/swanctl/swanctl.opt b/src/swanctl/swanctl.opt index bdd92177f..7e204db61 100644 --- a/src/swanctl/swanctl.opt +++ b/src/swanctl/swanctl.opt @@ -154,15 +154,19 @@ connections.<conn>.dpd_timeout = 0s specified; this option has no effect on connections using IKE2. connections.<conn>.fragmentation = yes - Use IKE UDP datagram fragmentation. (_yes_, _no_ or _force_). + Use IKE UDP datagram fragmentation. (_yes_, _accept_, _no_ or _force_). Use IKE fragmentation (proprietary IKEv1 extension or RFC 7383 IKEv2 - fragmentation). Acceptable values are _yes_ (the default), _force_ and - _no_. Fragmented IKE messages sent by a peer are always accepted - irrespective of the value of this option. If set to _yes_, and the peer - supports it, oversized IKE messages will be sent in fragments. If set to - _force_ (only supported for IKEv1) the initial IKE message will already - be fragmented if required. + fragmentation). Acceptable values are _yes_ (the default), _accept_, + _force_ and _no_. If set to _yes_, and the peer supports it, oversized IKE + messages will be sent in fragments. If set to _accept_, support for + fragmentation is announced to the peer but the daemon does not send its own + messages in fragments. If set to _force_ (only supported for IKEv1) the + initial IKE message will already be fragmented if required. Finally, setting + the option to _no_ will disable announcing support for this feature. + + Note that fragmented IKE messages sent by a peer are always accepted + irrespective of the value of this option (even when set to _no_). connections.<conn>.send_certreq = yes Send certificate requests payloads (_yes_ or _no_). @@ -647,6 +651,15 @@ connections.<conn>.children.<child>.esp_proposals = default for interoperability. If no algorithms are specified for AH nor ESP, the _default_ set of algorithms for ESP is included. +connections.<conn>.children.<child>.sha256_96 = no + Use incorrect 96-bit truncation for HMAC-SHA-256. + + HMAC-SHA-256 is used with 128-bit truncation with IPsec. For compatibility + with implementations that incorrectly use 96-bit truncation this option may + be enabled to configure the shorter truncation length in the kernel. This + is not negotiated, so this only works with peers that use the incorrect + truncation length (or have this option enabled). + connections.<conn>.children.<child>.local_ts = dynamic Local traffic selectors to include in CHILD_SA. @@ -884,6 +897,10 @@ connections.<conn>.children.<child>.replay_window = 32 default of 32 are supported using the Netlink backend only, a value of 0 disables IPsec replay protection. +connections.<conn>.children.<child>.hw_offload = no + Enable hardware offload for this CHILD_SA, if supported by the IPsec + implementation. + connections.<conn>.children.<child>.start_action = none Action to perform after loading the configuration (_none_, _trap_, _start_). |