Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP5:GA
strongswan
0001-marvell-auth-els-strongswan-5.9.7-v1.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0001-marvell-auth-els-strongswan-5.9.7-v1.patch of Package strongswan
From 31f772c7d8db888df7fd62683d99b8513738bca0 Mon Sep 17 00:00:00 2001 From: Bhushan Narkhede <bnarkhede@marvell.com> Date: Wed, 30 Nov 2022 03:24:08 -0800 References: jsc#PED-1539 Upstream: no Subject: [PATCH] Marvell core changes and dummy plugin v5.9.7 --- conf/Makefile.am | 1 + conf/options/charon.opt | 3 + conf/plugins/auth-els.opt | 5 + configure.ac | 27 ++ src/charon-cmd/cmd/cmd_connection.c | 24 +- src/charon-nm/nm/nm_service.c | 24 +- src/charon/Makefile.am | 4 + src/libcharon/Makefile.am | 8 + src/libcharon/config/ike_cfg.c | 58 ++- src/libcharon/config/peer_cfg.c | 29 ++ src/libcharon/config/peer_cfg.h | 31 ++ src/libcharon/encoding/parser.c | 35 ++ .../payloads/traffic_selector_substructure.c | 82 +++- .../payloads/traffic_selector_substructure.h | 17 + src/libcharon/kernel/kernel_fc_sp.c | 61 +++ src/libcharon/kernel/kernel_fc_sp.h | 366 ++++++++++++++++++ src/libcharon/kernel/kernel_interface.c | 188 ++++++++- src/libcharon/kernel/kernel_interface.h | 50 ++- src/libcharon/kernel/kernel_ipsec.h | 23 ++ src/libcharon/network/sender.c | 53 ++- src/libcharon/network/socket.h | 27 ++ src/libcharon/network/socket_manager.c | 151 ++++++-- src/libcharon/network/socket_manager.h | 24 +- src/libcharon/plugins/auth_els/Makefile.am | 25 ++ .../plugins/auth_els/auth_els_configs.c | 183 +++++++++ .../plugins/auth_els/auth_els_configs.h | 41 ++ src/libcharon/plugins/auth_els/auth_els_ike.c | 270 +++++++++++++ src/libcharon/plugins/auth_els/auth_els_ike.h | 42 ++ .../plugins/auth_els/auth_els_kernel_fc_sp.c | 235 +++++++++++ .../plugins/auth_els/auth_els_kernel_fc_sp.h | 35 ++ .../plugins/auth_els/auth_els_plugin.c | 213 ++++++++++ .../plugins/auth_els/auth_els_plugin.h | 46 +++ .../plugins/auth_els/auth_els_socket.c | 114 ++++++ .../plugins/auth_els/auth_els_socket.h | 29 ++ .../plugins/auth_els/auth_els_utils.h | 60 +++ src/libcharon/plugins/ha/ha_tunnel.c | 24 +- .../kernel_netlink/kernel_netlink_net.c | 2 +- .../plugins/kernel_pfkey/kernel_pfkey_ipsec.c | 24 +- .../plugins/kernel_wfp/kernel_wfp_ipsec.c | 23 ++ .../plugins/load_tester/load_tester_config.c | 24 +- src/libcharon/plugins/medcli/medcli_config.c | 26 +- src/libcharon/plugins/medsrv/medsrv_config.c | 24 +- src/libcharon/plugins/sql/sql_config.c | 24 +- .../plugins/stroke/stroke_attribute.c | 23 ++ src/libcharon/plugins/stroke/stroke_config.c | 28 +- src/libcharon/plugins/stroke/stroke_list.c | 30 ++ src/libcharon/plugins/uci/uci_config.c | 26 +- src/libcharon/plugins/vici/vici_attribute.c | 25 +- src/libcharon/plugins/vici/vici_config.c | 39 +- src/libcharon/plugins/vici/vici_control.c | 24 +- src/libcharon/processing/jobs/migrate_job.c | 24 +- src/libcharon/sa/child_sa.c | 38 +- src/libcharon/sa/child_sa.h | 32 ++ src/libcharon/sa/ike_sa.c | 49 ++- src/libcharon/sa/ike_sa.h | 25 ++ src/libcharon/sa/ike_sa_manager.c | 48 ++- src/libcharon/sa/ike_sa_manager.h | 36 ++ src/libcharon/sa/ikev1/tasks/informational.c | 24 +- src/libcharon/sa/ikev1/tasks/isakmp_natd.c | 24 +- src/libcharon/sa/ikev2/task_manager_v2.c | 26 +- src/libcharon/sa/ikev2/tasks/child_create.c | 27 +- src/libcharon/sa/ikev2/tasks/ike_mobike.c | 27 +- src/libcharon/sa/ikev2/tasks/ike_natd.c | 37 +- src/libstrongswan/networking/host.c | 46 ++- src/libstrongswan/networking/host.h | 31 ++ .../selectors/traffic_selector.c | 90 ++++- .../selectors/traffic_selector.h | 49 +++ src/libstrongswan/utils/identification.c | 35 +- src/libstrongswan/utils/identification.h | 28 ++ src/libstrongswan/utils/parser_helper.c | 114 +++++- src/libstrongswan/utils/utils.h | 29 ++ src/swanctl/swanctl.c | 94 +++++ 74 files changed, 3816 insertions(+), 115 deletions(-) create mode 100644 conf/plugins/auth-els.opt create mode 100644 src/libcharon/kernel/kernel_fc_sp.c create mode 100644 src/libcharon/kernel/kernel_fc_sp.h create mode 100644 src/libcharon/plugins/auth_els/Makefile.am create mode 100644 src/libcharon/plugins/auth_els/auth_els_configs.c create mode 100644 src/libcharon/plugins/auth_els/auth_els_configs.h create mode 100644 src/libcharon/plugins/auth_els/auth_els_ike.c create mode 100644 src/libcharon/plugins/auth_els/auth_els_ike.h create mode 100644 src/libcharon/plugins/auth_els/auth_els_kernel_fc_sp.c create mode 100644 src/libcharon/plugins/auth_els/auth_els_kernel_fc_sp.h create mode 100644 src/libcharon/plugins/auth_els/auth_els_plugin.c create mode 100644 src/libcharon/plugins/auth_els/auth_els_plugin.h create mode 100644 src/libcharon/plugins/auth_els/auth_els_socket.c create mode 100644 src/libcharon/plugins/auth_els/auth_els_socket.h create mode 100644 src/libcharon/plugins/auth_els/auth_els_utils.h diff --git a/conf/Makefile.am b/conf/Makefile.am index 74fb63680..540a3b563 100644 --- a/conf/Makefile.am +++ b/conf/Makefile.am @@ -32,6 +32,7 @@ plugins = \ plugins/android_log.opt \ plugins/attr.opt \ plugins/attr-sql.opt \ + plugins/auth-els.opt \ plugins/bliss.opt \ plugins/botan.opt \ plugins/bypass-lan.opt \ diff --git a/conf/options/charon.opt b/conf/options/charon.opt index 7d00e1a8c..3fef9d35b 100644 --- a/conf/options/charon.opt +++ b/conf/options/charon.opt @@ -420,6 +420,9 @@ charon.send_delay_request = yes charon.send_delay_type = 0 Specific IKEv2 message type to delay, 0 for any. +charon.sender_thread_count = 1 + For applications that require connection scaling, this allows creation of multiples threads to do sends. + charon.send_vendor_id = no Send strongSwan vendor ID payload diff --git a/conf/plugins/auth-els.opt b/conf/plugins/auth-els.opt new file mode 100644 index 000000000..38b670c94 --- /dev/null +++ b/conf/plugins/auth-els.opt @@ -0,0 +1,5 @@ +charon.plugins.auth-els.disabled_remotes.remote_1.wwpn = 21:00:00:24:ff:78:30:c5 + WWPN of remote port. + +charon.plugins.auth-els.disabled_remotes.remote_1.wwpn_separator = . : - + WWPN separated by : . -. diff --git a/configure.ac b/configure.ac index dd9d128c1..06a9ad284 100644 --- a/configure.ac +++ b/configure.ac @@ -16,6 +16,28 @@ # for more details. # +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + # ============================ # initialize & set some vars # ============================ @@ -215,6 +237,7 @@ ARG_ENABL_SET([eap-tnc], [enable EAP TNC trusted network connect module.] ARG_ENABL_SET([eap-dynamic], [enable dynamic EAP proxy module.]) ARG_ENABL_SET([eap-radius], [enable RADIUS proxy authentication module.]) ARG_ENABL_SET([ext-auth], [enable plugin calling an external authorization script.]) +ARG_ENABL_SET([auth-els], [enable auth els plugin authorization module.]) ARG_ENABL_SET([ipseckey], [enable IPSECKEY authentication plugin.]) ARG_ENABL_SET([keychain], [enables OS X Keychain Services credential set.]) ARG_ENABL_SET([pkcs11], [enables the PKCS11 token support plugin.]) @@ -1571,6 +1594,7 @@ ADD_PLUGIN([kernel-wfp], [c charon]) ADD_PLUGIN([kernel-iph], [c charon]) ADD_PLUGIN([kernel-pfkey], [c charon starter nm cmd]) ADD_PLUGIN([kernel-pfroute], [c charon starter nm cmd]) +ADD_PLUGIN([auth-els], [c charon]) ADD_PLUGIN([kernel-netlink], [c charon starter nm cmd]) ADD_PLUGIN([selinux], [c charon starter nm cmd]) ADD_PLUGIN([resolve], [c charon cmd]) @@ -1755,6 +1779,8 @@ AM_CONDITIONAL(USE_KERNEL_WFP, test x$kernel_wfp = xtrue) AM_CONDITIONAL(USE_KERNEL_IPH, test x$kernel_iph = xtrue) AM_CONDITIONAL(USE_WHITELIST, test x$whitelist = xtrue) AM_CONDITIONAL(USE_EXT_AUTH, test x$ext_auth = xtrue) +AM_CONDITIONAL(USE_AUTH_ELS, test x$auth_els = xtrue) +AM_CONDITIONAL(USE_DISABLE_SIGNAL_HANDLER, test x$auth_els = xtrue) AM_CONDITIONAL(USE_LOOKIP, test x$lookip = xtrue) AM_CONDITIONAL(USE_ERROR_NOTIFY, test x$error_notify = xtrue) AM_CONDITIONAL(USE_CERTEXPIRE, test x$certexpire = xtrue) @@ -2102,6 +2128,7 @@ AC_CONFIG_FILES([ src/libcharon/plugins/kernel_iph/Makefile src/libcharon/plugins/whitelist/Makefile src/libcharon/plugins/ext_auth/Makefile + src/libcharon/plugins/auth_els/Makefile src/libcharon/plugins/lookip/Makefile src/libcharon/plugins/error_notify/Makefile src/libcharon/plugins/certexpire/Makefile diff --git a/src/charon-cmd/cmd/cmd_connection.c b/src/charon-cmd/cmd/cmd_connection.c index 8c09cac89..0467882da 100644 --- a/src/charon-cmd/cmd/cmd_connection.c +++ b/src/charon-cmd/cmd/cmd_connection.c @@ -15,6 +15,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "cmd_connection.h" #include <signal.h> @@ -180,7 +202,7 @@ static peer_cfg_t* create_peer_cfg(private_cmd_connection_t *this) break; } - ike.local_port = charon->socket->get_port(charon->socket, FALSE); + ike.local_port = charon->socket->get_port(charon->socket, SOCKET_FAMILY_BOTH, FALSE); if (ike.local_port != IKEV2_UDP_PORT) { ike.remote_port = IKEV2_NATT_PORT; diff --git a/src/charon-nm/nm/nm_service.c b/src/charon-nm/nm/nm_service.c index 5d6d32950..07c3ab049 100644 --- a/src/charon-nm/nm/nm_service.c +++ b/src/charon-nm/nm/nm_service.c @@ -15,6 +15,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "nm_service.h" #include <daemon.h> @@ -614,7 +636,7 @@ static gboolean connect_(NMVpnServicePlugin *plugin, NMConnection *connection, ike_cfg_create_t ike = { .version = IKEV2, .local = "%any", - .local_port = charon->socket->get_port(charon->socket, FALSE), + .local_port = charon->socket->get_port(charon->socket, SOCKET_FAMILY_BOTH, FALSE), .remote_port = IKEV2_UDP_PORT, .fragmentation = FRAGMENTATION_YES, }; diff --git a/src/charon/Makefile.am b/src/charon/Makefile.am index b78bbd757..f490be6e6 100644 --- a/src/charon/Makefile.am +++ b/src/charon/Makefile.am @@ -17,4 +17,8 @@ charon_LDADD = \ $(top_builddir)/src/libcharon/libcharon.la \ -lm $(PTHREADLIB) $(ATOMICLIB) $(DLLIB) +if USE_DISABLE_SIGNAL_HANDLER + AM_CPPFLAGS += -DDISABLE_SIGNAL_HANDLER +endif + EXTRA_DIST = Android.mk diff --git a/src/libcharon/Makefile.am b/src/libcharon/Makefile.am index fb6de8ebd..af68e1d56 100644 --- a/src/libcharon/Makefile.am +++ b/src/libcharon/Makefile.am @@ -47,6 +47,7 @@ encoding/payloads/hash_payload.c encoding/payloads/hash_payload.h \ encoding/payloads/fragment_payload.c encoding/payloads/fragment_payload.h \ kernel/kernel_interface.c kernel/kernel_interface.h \ kernel/kernel_ipsec.c kernel/kernel_ipsec.h \ +kernel/kernel_fc_sp.c kernel/kernel_fc_sp.h \ kernel/kernel_net.c kernel/kernel_net.h \ kernel/kernel_listener.h kernel/kernel_handler.c kernel/kernel_handler.h \ network/receiver.c network/receiver.h network/sender.c network/sender.h \ @@ -327,6 +328,13 @@ if MONOLITHIC endif endif +if USE_AUTH_ELS + SUBDIRS += plugins/auth_els +if MONOLITHIC + libcharon_la_LIBADD += plugins/auth_els/libstrongswan-auth-els.la +endif +endif + if USE_EAP_IDENTITY SUBDIRS += plugins/eap_identity if MONOLITHIC diff --git a/src/libcharon/config/ike_cfg.c b/src/libcharon/config/ike_cfg.c index 792f8022a..79cb0b53a 100644 --- a/src/libcharon/config/ike_cfg.c +++ b/src/libcharon/config/ike_cfg.c @@ -16,6 +16,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #define _GNU_SOURCE /* for stdndup() */ #include <string.h> @@ -120,6 +142,11 @@ struct private_ike_cfg_t { * List of proposals to use */ linked_list_t *proposals; + + /** + * Indicates that this config is for FC_ADDR + */ + bool fc_addr; }; METHOD(ike_cfg_t, get_version, ike_version_t, @@ -198,7 +225,7 @@ METHOD(ike_cfg_t, resolve_other, host_t*, /** * Common function for match_me/other */ -static u_int match(linked_list_t *hosts, linked_list_t *ranges, host_t *cand) +static u_int match(linked_list_t *hosts, linked_list_t *ranges, host_t *cand, bool fc_addr) { enumerator_t *enumerator; traffic_selector_t *ts; @@ -211,6 +238,11 @@ static u_int match(linked_list_t *hosts, linked_list_t *ranges, host_t *cand) enumerator = hosts->create_enumerator(hosts); while (enumerator->enumerate(enumerator, &str)) { + if (cand->get_family(cand) == AF_NETLINK && !fc_addr) + { + DBG1 (DBG_IKE, "ike_cfg.c: Looking for FC addr but this ike_cfg is not for FC"); + continue; + } host = host_create_from_dns(str, cand->get_family(cand), 0); if (host) { @@ -252,13 +284,13 @@ static u_int match(linked_list_t *hosts, linked_list_t *ranges, host_t *cand) METHOD(ike_cfg_t, match_me, u_int, private_ike_cfg_t *this, host_t *host) { - return match(this->my_hosts, this->my_ranges, host); + return match(this->my_hosts, this->my_ranges, host, this->fc_addr); } METHOD(ike_cfg_t, match_other, u_int, private_ike_cfg_t *this, host_t *host) { - return match(this->other_hosts, this->other_ranges, host); + return match(this->other_hosts, this->other_ranges, host, this->fc_addr); } METHOD(ike_cfg_t, get_my_addr, char*, @@ -451,7 +483,7 @@ static traffic_selector_t* make_range(char *str) { return NULL; } - if (to->get_family(to) == AF_INET) + if (to->get_family(to) == AF_INET || to->get_family(to) == AF_NETLINK) { type = TS_IPV4_ADDR_RANGE; } @@ -507,6 +539,12 @@ int ike_cfg_get_family(ike_cfg_t *cfg, bool local) char *str; int family = AF_UNSPEC; + // If this config is for FC, then we don't have to look any further. + if (this->fc_addr) + { + return AF_NETLINK; + } + if (local) { enumerator = this->my_hosts->create_enumerator(this->my_hosts); @@ -553,6 +591,12 @@ bool ike_cfg_has_address(ike_cfg_t *cfg, host_t *addr, bool local) char *str; bool found = FALSE; + // If this config is for FC then make sure that is what they are looking for + if ((addr->get_family (addr) == AF_NETLINK) && !this->fc_addr) + { + return false; + } + if (local) { enumerator = this->my_hosts->create_enumerator(this->my_hosts); @@ -626,6 +670,12 @@ ike_cfg_t *ike_cfg_create(ike_cfg_create_t *data) .proposals = linked_list_create(), ); + if (strstr (data->local, "-fcsp") && strstr (data->remote, "-fcsp")) + { + this->fc_addr = true; + data->local[strlen (data->local) - 5] = '\0'; + data->remote[strlen (data->remote) - 5] = '\0'; + } parse_addresses(data->local, this->my_hosts, this->my_ranges); parse_addresses(data->remote, this->other_hosts, this->other_ranges); diff --git a/src/libcharon/config/peer_cfg.c b/src/libcharon/config/peer_cfg.c index f08eef502..0c2da66cd 100644 --- a/src/libcharon/config/peer_cfg.c +++ b/src/libcharon/config/peer_cfg.c @@ -16,6 +16,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include <string.h> #include "peer_cfg.h" @@ -213,6 +235,12 @@ METHOD(peer_cfg_t, get_ike_cfg, ike_cfg_t*, return this->ike_cfg; } +METHOD(peer_cfg_t, set_ike_cfg, void, + private_peer_cfg_t *this, ike_cfg_t* ike_cfg) +{ + this->ike_cfg = ike_cfg; +} + METHOD(peer_cfg_t, add_child_cfg, void, private_peer_cfg_t *this, child_cfg_t *child_cfg) { @@ -822,6 +850,7 @@ peer_cfg_t *peer_cfg_create(char *name, ike_cfg_t *ike_cfg, .get_name = _get_name, .get_ike_version = _get_ike_version, .get_ike_cfg = _get_ike_cfg, + .set_ike_cfg = _set_ike_cfg, .add_child_cfg = _add_child_cfg, .remove_child_cfg = (void*)_remove_child_cfg, .replace_child_cfgs = _replace_child_cfgs, diff --git a/src/libcharon/config/peer_cfg.h b/src/libcharon/config/peer_cfg.h index 6b0834339..24783a7e3 100644 --- a/src/libcharon/config/peer_cfg.h +++ b/src/libcharon/config/peer_cfg.h @@ -16,6 +16,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + /** * @defgroup peer_cfg peer_cfg * @{ @ingroup config @@ -141,6 +163,15 @@ struct peer_cfg_t { */ ike_cfg_t* (*get_ike_cfg) (peer_cfg_t *this); + /** + * Set the IKE config to use for initiation. + * This is needed for FCSP2 because the ike_cfg is not created + * correctly by vici as it doesn't have all of the information. + * + * @param the IKE config to use + */ + void (*set_ike_cfg) (peer_cfg_t *this, ike_cfg_t* ike_cfg); + /** * Attach a CHILD config. * diff --git a/src/libcharon/encoding/parser.c b/src/libcharon/encoding/parser.c index 546d39931..38d81cc48 100644 --- a/src/libcharon/encoding/parser.c +++ b/src/libcharon/encoding/parser.c @@ -15,6 +15,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include <stdlib.h> #include <string.h> @@ -369,9 +391,11 @@ METHOD(parser_t, parse_payload, status_t, payload_t *pld; void *output; int payload_length = 0, spi_size = 0, attribute_length = 0, header_length; + uint8_t ts_type = 0; bool attribute_format = FALSE; int rule_number, rule_count; encoding_rule_t *rule; + payload_type_t pld_type = 0; /* create instance of the payload to parse */ if (payload_is_known(payload_type, this->major_version)) @@ -389,6 +413,7 @@ METHOD(parser_t, parse_payload, status_t, DBG3(DBG_ENC, "parsing payload from %b", this->byte_pos, (u_int)(this->input_roof - this->byte_pos)); + pld_type = pld->get_type(pld); /* base pointer for output, avoids casting in every rule */ output = pld; /* parse the payload with its own rules */ @@ -420,6 +445,16 @@ METHOD(parser_t, parse_payload, status_t, pld->destroy(pld); return PARSE_ERROR; } + if (pld_type == PLV2_TRAFFIC_SELECTOR_SUBSTRUCTURE) + { + ts_type = *(uint8_t*)(output + rule->offset); + if(ts_type == TS_FC_ADDR_RANGE) + { + traffic_selector_substructure_t *tsstruct = (traffic_selector_substructure_t*)pld; + tsstruct->set_ts_type(tsstruct, TS_FC_ADDR_RANGE); + rule_count = pld->get_encoding_rules(pld, &this->rules); + } + } break; } case U_INT_16: diff --git a/src/libcharon/encoding/payloads/traffic_selector_substructure.c b/src/libcharon/encoding/payloads/traffic_selector_substructure.c index 8fbcdf98c..ed1caad08 100644 --- a/src/libcharon/encoding/payloads/traffic_selector_substructure.c +++ b/src/libcharon/encoding/payloads/traffic_selector_substructure.c @@ -16,6 +16,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "traffic_selector_substructure.h" #include <encoding/payloads/encodings.h> @@ -122,6 +144,9 @@ static bool parse_ts_data(private_traffic_selector_substructure_t *this, case TS_IPV6_ADDR_RANGE: addr_len = 16; break; + case TS_FC_ADDR_RANGE: + addr_len = 3; + break; default: return FALSE; } @@ -166,6 +191,32 @@ METHOD(payload_t, verify, status_t, } break; } + case TS_FC_ADDR_RANGE: + { + uint16_t start_port, end_port; + chunk_t start_addr, end_addr; + + if (!parse_ts_data(this, &start_port, &end_port, &start_addr, + &end_addr)) + { + return FAILED; + } + + if (start_port > end_port) + { + /* OPAQUE ports are the only exception */ + if (start_port != 0xffff && end_port != 0) + { + return FAILED; + } + } + if ((start_addr.len != 3) || + (start_addr.len != 3)) + { + return FAILED; + } + break; + } case TS_SECLABEL: if (!this->ts_data.len) { @@ -215,9 +266,26 @@ METHOD(payload_t, get_length, size_t, return this->payload_length; } +METHOD(traffic_selector_substructure_t, set_ts_type, void, + private_traffic_selector_substructure_t *this, ts_type_t ts_type) +{ + this->ts_type = ts_type; + if (this->ts_type == TS_FC_ADDR_RANGE) + { + this->payload_length = get_header_length(this) + 10; //starting address(3), ending address(3) + } +} + +METHOD(traffic_selector_substructure_t, get_ts_type, ts_type_t, + private_traffic_selector_substructure_t *this) +{ + return this->ts_type; +} + METHOD(traffic_selector_substructure_t, get_traffic_selector, traffic_selector_t*, private_traffic_selector_substructure_t *this) { + traffic_selector_t* ts = NULL; uint16_t start_port, end_port; chunk_t start_addr, end_addr; @@ -225,9 +293,18 @@ METHOD(traffic_selector_substructure_t, get_traffic_selector, traffic_selector_t { return NULL; } + if (this->ts_type == TS_FC_ADDR_RANGE) + { + ts = traffic_selector_create_from_fcsp2_format(start_addr, start_port, + end_addr, end_port); + } + else + { return traffic_selector_create_from_bytes( this->ip_protocol_id, this->ts_type, start_addr, start_port, end_addr, end_port); + } + return ts; } METHOD(traffic_selector_substructure_t, get_sec_label, sec_label_t*, @@ -266,6 +343,8 @@ traffic_selector_substructure_t *traffic_selector_substructure_create() .get_type = _get_type, .destroy = _destroy, }, + .get_ts_type = _get_ts_type, + .set_ts_type = _set_ts_type, .get_traffic_selector = _get_traffic_selector, .get_sec_label = _get_sec_label, .destroy = _destroy, @@ -290,7 +369,8 @@ traffic_selector_substructure_t *traffic_selector_substructure_create_from_traff this->ts_type = ts->get_type(ts); this->ip_protocol_id = ts->get_protocol(ts); - writer = bio_writer_create(this->ts_type == TS_IPV4_ADDR_RANGE ? 12 : 36); + writer = bio_writer_create(this->ts_type == TS_IPV4_ADDR_RANGE ? 12 : + (this->ts_type == TS_FC_ADDR_RANGE) ? 14 : 36); writer->write_uint16(writer, ts->get_from_port(ts)); writer->write_uint16(writer, ts->get_to_port(ts)); writer->write_data(writer, ts->get_from_address(ts)); diff --git a/src/libcharon/encoding/payloads/traffic_selector_substructure.h b/src/libcharon/encoding/payloads/traffic_selector_substructure.h index 57d940043..c8bf58815 100644 --- a/src/libcharon/encoding/payloads/traffic_selector_substructure.h +++ b/src/libcharon/encoding/payloads/traffic_selector_substructure.h @@ -44,6 +44,23 @@ struct traffic_selector_substructure_t { */ payload_t payload_interface; + /** + * Get the type of Traffic selector. + * + * @return type of traffic selector + * + */ + ts_type_t (*get_ts_type) (traffic_selector_substructure_t *this); + + /** + * Set the type of Traffic selector. + * + * @param ts_type type of traffic selector + */ + void (*set_ts_type) (traffic_selector_substructure_t *this, + ts_type_t ts_type); + + /** * Get a traffic_selector_t from this substructure if possible. * diff --git a/src/libcharon/kernel/kernel_fc_sp.c b/src/libcharon/kernel/kernel_fc_sp.c new file mode 100644 index 000000000..947684c0f --- /dev/null +++ b/src/libcharon/kernel/kernel_fc_sp.c @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2008 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. + */ + +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "kernel_fc_sp.h" + +#include <daemon.h> + +/** + * See header + */ +bool kernel_fc_sp_register(plugin_t *plugin, plugin_feature_t *feature, + bool reg, void *data) +{ + if (reg) + { + return charon->kernel->add_fc_sp_interface(charon->kernel, + (kernel_fc_sp_constructor_t)data); + } + else + { + return charon->kernel->remove_fc_sp_interface(charon->kernel, + (kernel_fc_sp_constructor_t)data); + } +} + + diff --git a/src/libcharon/kernel/kernel_fc_sp.h b/src/libcharon/kernel/kernel_fc_sp.h new file mode 100644 index 000000000..9e1339432 --- /dev/null +++ b/src/libcharon/kernel/kernel_fc_sp.h @@ -0,0 +1,366 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/* + * File: kernel_fc_sp.h + * Author: cwinkler + * + * Created on October 20, 2020, 2:19 PM + */ + +#ifndef KERNEL_FC_SP_H +#define KERNEL_FC_SP_H + +typedef struct kernel_fc_sp_t kernel_fc_sp_t; +typedef struct kernel_fc_sp_sa_id_t kernel_fc_sp_sa_id_t; +typedef struct kernel_fc_sp_add_sa_t kernel_fc_sp_add_sa_t; +typedef struct kernel_fc_sp_update_sa_t kernel_fc_sp_update_sa_t; +typedef struct kernel_fc_sp_query_sa_t kernel_fc_sp_query_sa_t; +typedef struct kernel_fc_sp_del_sa_t kernel_fc_sp_del_sa_t; +typedef struct kernel_fc_sp_policy_id_t kernel_fc_sp_policy_id_t; +typedef struct kernel_fc_sp_manage_policy_t kernel_fc_sp_manage_policy_t; +typedef struct kernel_fc_sp_query_policy_t kernel_fc_sp_query_policy_t; + +#include <networking/host.h> +#include <ipsec/ipsec_types.h> +#include <selectors/traffic_selector.h> +#include <selectors/sec_label.h> +#include <plugins/plugin.h> +#include <kernel/kernel_interface.h> + +/** + * Data required to identify an SA in the kernel + */ +struct kernel_fc_sp_sa_id_t { + /** Source address */ + host_t *src; + /** Destination address */ + host_t *dst; + /** SPI */ + uint32_t spi; + /** Protocol (ESP/AH) */ + uint8_t proto; + /** Optional mark */ + mark_t mark; + /** Optional interface ID */ + uint32_t if_id; +}; + +/** + * Data required to add an SA to the kernel + */ +struct kernel_fc_sp_add_sa_t { + /** Reqid */ + uint32_t reqid; + /** Mode (tunnel, transport...) */ + ipsec_mode_t mode; + /** List of source traffic selectors */ + linked_list_t *src_ts; + /** List of destination traffic selectors */ + linked_list_t *dst_ts; + /** Network interface restricting policy */ + char *interface; + /** Lifetime configuration */ + lifetime_cfg_t *lifetime; + /** Encryption algorithm */ + uint16_t enc_alg; + /** Encryption key */ + chunk_t enc_key; + /** Integrity protection algorithm */ + uint16_t int_alg; + /** Integrity protection key */ + chunk_t int_key; + /** Anti-replay window size */ + uint32_t replay_window; + /** Traffic Flow Confidentiality padding */ + uint32_t tfc; + /** IPComp transform */ + uint16_t ipcomp; + /** CPI for IPComp */ + uint16_t cpi; + /** TRUE to enable UDP encapsulation for NAT traversal */ + bool encap; + /** no (disabled), yes (enabled), auto (enabled if supported) */ + hw_offload_t hw_offload; + /** Mark the SA should apply to packets after processing */ + mark_t mark; + /** Security label to match or apply */ + sec_label_t *label; + /** TRUE to use Extended Sequence Numbers */ + bool esn; + /** TRUE to copy the DF bit to the outer IPv4 header in tunnel mode */ + bool copy_df; + /** TRUE to copy the ECN header field to/from the outer header */ + bool copy_ecn; + /** Whether to copy the DSCP header field to/from the outer header */ + dscp_copy_t copy_dscp; + /** TRUE if initiator of the exchange creating the SA */ + bool initiator; + /** TRUE if this is an inbound SA */ + bool inbound; + /** TRUE if an SPI has already been allocated for this SA */ + bool update; +}; + +/** + * Data required to update the hosts of an SA in the kernel + */ +struct kernel_fc_sp_update_sa_t { + /** CPI in case IPComp is used */ + uint16_t cpi; + /** New source address */ + host_t *new_src; + /** New destination address */ + host_t *new_dst; + /** TRUE if UDP encapsulation is currently enabled */ + bool encap; + /** TRUE to enable UDP encapsulation */ + bool new_encap; +}; + +/** + * Data required to query an SA in the kernel + */ +struct kernel_fc_sp_query_sa_t { + uint16_t cpi; +}; + +/** + * Data required to delete an SA in the kernel + */ +struct kernel_fc_sp_del_sa_t { + /** CPI in case IPComp is used */ + uint16_t cpi; +}; + +/** + * Data identifying a policy in the kernel + */ +struct kernel_fc_sp_policy_id_t { + /** Direction of traffic */ + policy_dir_t dir; + /** Source traffic selector */ + traffic_selector_t *src_ts; + /** Destination traffic selector */ + traffic_selector_t *dst_ts; + /** Optional mark */ + mark_t mark; + /** Optional interface ID */ + uint32_t if_id; + /** Network interface restricting policy */ + char *interface; +}; + +/** + * Data required to add/delete a policy to/from the kernel + */ +struct kernel_fc_sp_manage_policy_t { + /** Type of policy */ + policy_type_t type; + /** Priority class */ + policy_priority_t prio; + /** Manually-set priority (automatic if set to 0) */ + uint32_t manual_prio; + /** Source address of the SA(s) tied to this policy */ + host_t *src; + /** Destination address of the SA(s) tied to this policy */ + host_t *dst; + /** Details about the SA(s) tied to this policy */ + ipsec_sa_cfg_t *sa; +}; + +/** + * Data required to query a policy in the kernel + */ +struct kernel_fc_sp_query_policy_t { +}; + + +/** + * Interface to the fc-sp subsystem. + * + * The kernel fc-sp interface handles the communication with the FC-SP + * module that will communicate to the lower level that handles the SAs. + * FC-SP does not currently use policies so they are not provided in this + * implementation of the interface. + */ +struct kernel_fc_sp_t { + + /** + * Get the feature set supported by this kernel backend. + * + * @return ORed feature-set of backend + */ + kernel_feature_t (*get_features)(kernel_fc_sp_t *this); + + /** + * Get a SPI from the kernel. + * + * @param src source address of SA + * @param dst destination address of SA + * @param protocol protocol for SA (ESP/AH) + * @param spi allocated spi + * @return SUCCESS if operation completed + */ + status_t (*get_spi)(kernel_fc_sp_t *this, host_t *src, host_t *dst, + uint8_t protocol, uint32_t *spi); + + /** + * Get a Compression Parameter Index (CPI) from the kernel. + * + * @param src source address of SA + * @param dst destination address of SA + * @param cpi allocated cpi + * @return SUCCESS if operation completed + */ + status_t (*get_cpi)(kernel_fc_sp_t *this, host_t *src, host_t *dst, + uint16_t *cpi); + + /** + * Add an SA to the SAD. + * + * This function does install a single SA for a single protocol in one + * direction. + * + * @param id data identifying this SA + * @param data data for this SA + * @return SUCCESS if operation completed + */ + status_t (*add_sa)(kernel_fc_sp_t *this, kernel_fc_sp_sa_id_t *id, + kernel_fc_sp_add_sa_t *data); + + /** + * Update the hosts on an installed SA. + * + * We cannot directly update the destination address as the kernel + * requires the spi, the protocol AND the destination address (and family) + * to identify SAs. Therefore if the destination address changed we + * create a new SA and delete the old one. + * + * @param id data identifying this SA + * @param data updated data for this SA + * @return SUCCESS if operation completed, NOT_SUPPORTED if + * the kernel interface can't update the SA + */ + status_t (*update_sa)(kernel_fc_sp_t *this, kernel_fc_sp_sa_id_t *id, + kernel_fc_sp_update_sa_t *data); + + /** + * Query the number of bytes processed by an SA from the SAD. + * + * @param id data identifying this SA + * @param data data to query the SA + * @param[out] bytes the number of bytes processed by SA + * @param[out] packets number of packets processed by SA + * @param[out] time last (monotonic) time of SA use + * @return SUCCESS if operation completed + */ + status_t (*query_sa)(kernel_fc_sp_t *this, kernel_fc_sp_sa_id_t *id, + kernel_fc_sp_query_sa_t *data, uint64_t *bytes, + uint64_t *packets, time_t *time); + + /** + * Delete a previously installed SA from the SAD. + * + * @param id data identifying this SA + * @param data data to delete the SA + * @return SUCCESS if operation completed + */ + status_t (*del_sa)(kernel_fc_sp_t *this, kernel_fc_sp_sa_id_t *id, + kernel_fc_sp_del_sa_t *data); + + /** + * Add a policy to the SPD. + * + * @param id data identifying this policy + * @param data data for this policy + * @return SUCCESS if operation completed + */ + status_t (*add_policy)(kernel_fc_sp_t *this, + kernel_fc_sp_policy_id_t *id, + kernel_fc_sp_manage_policy_t *data); + + /** + * Query the use time of a policy. + * + * The use time of a policy is the time the policy was used for the last + * time. It is not the system time, but a monotonic timestamp as returned + * by time_monotonic. + * + * @param id data identifying this policy + * @param data data to query the policy + * @param[out] use_time the monotonic timestamp of this SA's last use + * @return SUCCESS if operation completed + */ + status_t (*query_policy)(kernel_fc_sp_t *this, + kernel_fc_sp_policy_id_t *id, + kernel_fc_sp_query_policy_t *data, + time_t *use_time); + + /** + * Remove a policy from the SPD. + * + * @param id data identifying this policy + * @param data data for this policy + * @return SUCCESS if operation completed + */ + status_t (*del_policy)(kernel_fc_sp_t *this, + kernel_fc_sp_policy_id_t *id, + kernel_fc_sp_manage_policy_t *data); + + /** + * Install a bypass policy for the given socket. + * + * @param fd socket file descriptor to setup policy for + * @param family protocol family of the socket + * @return TRUE of policy set up successfully + */ + bool (*bypass_socket)(kernel_fc_sp_t *this, int fd, int family); + + /** + * Enable decapsulation of ESP-in-UDP packets for the given port/socket. + * + * @param fd socket file descriptor + * @param family protocol family of the socket + * @param port the UDP port + * @return TRUE if UDP decapsulation was enabled successfully + */ + bool (*enable_udp_decap)(kernel_fc_sp_t *this, int fd, int family, + uint16_t port); + + /** + * Destroy the implementation. + */ + void (*destroy)(kernel_fc_sp_t *this); +}; + +bool kernel_fc_sp_register(plugin_t *plugin, plugin_feature_t *feature, + bool reg, void *data); + +#endif /* KERNEL_FC_SP_H */ + diff --git a/src/libcharon/kernel/kernel_interface.c b/src/libcharon/kernel/kernel_interface.c index 4f4a99731..e54f2acd8 100644 --- a/src/libcharon/kernel/kernel_interface.c +++ b/src/libcharon/kernel/kernel_interface.c @@ -37,6 +37,28 @@ * THE SOFTWARE. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "kernel_interface.h" #include <utils/debug.h> @@ -90,6 +112,11 @@ struct private_kernel_interface_t { */ kernel_ipsec_constructor_t ipsec_constructor; + /** + * Registered FC-SP constructor + */ + kernel_fc_sp_constructor_t fc_sp_constructor; + /** * Registered net constructor */ @@ -100,6 +127,11 @@ struct private_kernel_interface_t { */ kernel_ipsec_t *ipsec; + /** + * fc-sp interface + */ + kernel_fc_sp_t *fc_sp; + /** * network interface */ @@ -154,17 +186,27 @@ struct private_kernel_interface_t { }; METHOD(kernel_interface_t, get_features, kernel_feature_t, - private_kernel_interface_t *this) + private_kernel_interface_t *this, int family) { kernel_feature_t features = 0; - if (this->ipsec && this->ipsec->get_features) + if (family == AF_NETLINK) { - features |= this->ipsec->get_features(this->ipsec); + if (this->fc_sp && this->fc_sp->get_features) + { + features |= this->fc_sp->get_features(this->fc_sp); + } } - if (this->net && this->net->get_features) + else { - features |= this->net->get_features(this->net); + if (this->ipsec && this->ipsec->get_features) + { + features |= this->ipsec->get_features(this->ipsec); + } + if (this->net && this->net->get_features) + { + features |= this->net->get_features(this->net); + } } return features; } @@ -173,6 +215,19 @@ METHOD(kernel_interface_t, get_spi, status_t, private_kernel_interface_t *this, host_t *src, host_t *dst, uint8_t protocol, uint32_t *spi) { + + int family = src->get_family (src); + + if (family == AF_NETLINK) + { + if (!this->fc_sp) + { + return NOT_SUPPORTED; + } + + return this->fc_sp->get_spi (this->fc_sp, src, dst, protocol, spi); + } + if (!this->ipsec) { return NOT_SUPPORTED; @@ -184,6 +239,17 @@ METHOD(kernel_interface_t, get_cpi, status_t, private_kernel_interface_t *this, host_t *src, host_t *dst, uint16_t *cpi) { + int family = src->get_family (src); + + if (family == AF_NETLINK) + { + if (!this->fc_sp) + { + return NOT_SUPPORTED; + } + this->fc_sp->get_cpi (this->fc_sp, src, dst, cpi); + } + if (!this->ipsec) { return NOT_SUPPORTED; @@ -474,6 +540,18 @@ METHOD(kernel_interface_t, add_sa, status_t, private_kernel_interface_t *this, kernel_ipsec_sa_id_t *id, kernel_ipsec_add_sa_t *data) { + int family = id->src->get_family (id->src); + + if (family == AF_NETLINK) + { + if (!this->fc_sp) + { + return NOT_SUPPORTED; + } + + return this->fc_sp->add_sa (this->fc_sp, (kernel_fc_sp_sa_id_t*) id, (kernel_fc_sp_add_sa_t*) data); + } + if (!this->ipsec) { return NOT_SUPPORTED; @@ -497,6 +575,18 @@ METHOD(kernel_interface_t, query_sa, status_t, kernel_ipsec_query_sa_t *data, uint64_t *bytes, uint64_t *packets, time_t *time) { + int family = id->src->get_family (id->src); + + if (family == AF_NETLINK) + { + if (!this->fc_sp) + { + return NOT_SUPPORTED; + } + + return this->fc_sp->query_sa (this->fc_sp, (kernel_fc_sp_sa_id_t*) id, (kernel_fc_sp_query_sa_t*) data, bytes, packets, time); + } + if (!this->ipsec) { return NOT_SUPPORTED; @@ -508,6 +598,18 @@ METHOD(kernel_interface_t, del_sa, status_t, private_kernel_interface_t *this, kernel_ipsec_sa_id_t *id, kernel_ipsec_del_sa_t *data) { + int family = id->src->get_family (id->src); + + if (family == AF_NETLINK) + { + if (!this->fc_sp) + { + return NOT_SUPPORTED; + } + + return this->fc_sp->del_sa (this->fc_sp, (kernel_fc_sp_sa_id_t*) id, (kernel_fc_sp_del_sa_t*) data); + } + if (!this->ipsec) { return NOT_SUPPORTED; @@ -529,6 +631,17 @@ METHOD(kernel_interface_t, add_policy, status_t, private_kernel_interface_t *this, kernel_ipsec_policy_id_t *id, kernel_ipsec_manage_policy_t *data) { + int family = data->src->get_family (data->src); + + if (family == AF_NETLINK) + { + if (!this->fc_sp) + { + return NOT_SUPPORTED; + } + return this->fc_sp->add_policy(this->fc_sp, (kernel_fc_sp_policy_id_t*) id, (kernel_fc_sp_manage_policy_t*) data); + } + if (!this->ipsec) { return NOT_SUPPORTED; @@ -540,6 +653,14 @@ METHOD(kernel_interface_t, query_policy, status_t, private_kernel_interface_t *this, kernel_ipsec_policy_id_t *id, kernel_ipsec_query_policy_t *data, time_t *use_time) { + if (data->family == AF_NETLINK) + { + if (!this->fc_sp) + { + return NOT_SUPPORTED; + } + return this->fc_sp->query_policy(this->fc_sp, (kernel_fc_sp_policy_id_t*) id, (kernel_fc_sp_query_policy_t*) data, use_time); + } if (!this->ipsec) { return NOT_SUPPORTED; @@ -551,6 +672,17 @@ METHOD(kernel_interface_t, del_policy, status_t, private_kernel_interface_t *this, kernel_ipsec_policy_id_t *id, kernel_ipsec_manage_policy_t *data) { + int family = data->src->get_family (data->src); + + if (family == AF_NETLINK) + { + if (!this->fc_sp) + { + return NOT_SUPPORTED; + } + return this->fc_sp->del_policy (this->fc_sp, (kernel_fc_sp_policy_id_t*) id, (kernel_fc_sp_manage_policy_t*) data); + } + if (!this->ipsec) { return NOT_SUPPORTED; @@ -669,6 +801,15 @@ METHOD(kernel_interface_t, del_route, status_t, METHOD(kernel_interface_t, bypass_socket, bool, private_kernel_interface_t *this, int fd, int family) { + if (family == AF_NETLINK) + { + if (!this->fc_sp) + { + return NOT_SUPPORTED; + } + return this->fc_sp->bypass_socket(this->fc_sp, fd, family); + } + if (!this->ipsec) { return FALSE; @@ -679,6 +820,15 @@ METHOD(kernel_interface_t, bypass_socket, bool, METHOD(kernel_interface_t, enable_udp_decap, bool, private_kernel_interface_t *this, int fd, int family, uint16_t port) { + if (family == AF_NETLINK) + { + if (!this->fc_sp) + { + return NOT_SUPPORTED; + } + return this->fc_sp->enable_udp_decap(this->fc_sp, fd, family, port); + } + if (!this->ipsec) { return FALSE; @@ -813,6 +963,31 @@ METHOD(kernel_interface_t, remove_ipsec_interface, bool, return FALSE; } + +METHOD(kernel_interface_t, add_fc_sp_interface, bool, + private_kernel_interface_t *this, kernel_fc_sp_constructor_t constructor) +{ + if (!this->fc_sp) + { + this->fc_sp_constructor = constructor; + this->fc_sp = constructor(); + return this->fc_sp != NULL; + } + return FALSE; +} + +METHOD(kernel_interface_t, remove_fc_sp_interface, bool, + private_kernel_interface_t *this, kernel_fc_sp_constructor_t constructor) +{ + if (constructor == this->fc_sp_constructor && this->fc_sp) + { + this->fc_sp->destroy(this->fc_sp); + this->fc_sp = NULL; + return TRUE; + } + return FALSE; +} + METHOD(kernel_interface_t, add_net_interface, bool, private_kernel_interface_t *this, kernel_net_constructor_t constructor) { @@ -1031,6 +1206,7 @@ METHOD(kernel_interface_t, destroy, void, this->algorithms->destroy(this->algorithms); this->mutex_algs->destroy(this->mutex_algs); DESTROY_IF(this->ipsec); + DESTROY_IF(this->fc_sp); DESTROY_IF(this->net); DESTROY_FUNCTION_IF(this->ifaces_filter, (void*)free); this->reqids->destroy(this->reqids); @@ -1082,6 +1258,8 @@ kernel_interface_t *kernel_interface_create() .get_address_by_ts = _get_address_by_ts, .add_ipsec_interface = _add_ipsec_interface, .remove_ipsec_interface = _remove_ipsec_interface, + .add_fc_sp_interface = _add_fc_sp_interface, + .remove_fc_sp_interface = _remove_fc_sp_interface, .add_net_interface = _add_net_interface, .remove_net_interface = _remove_net_interface, diff --git a/src/libcharon/kernel/kernel_interface.h b/src/libcharon/kernel/kernel_interface.h index 21b777ae9..c85d8df9f 100644 --- a/src/libcharon/kernel/kernel_interface.h +++ b/src/libcharon/kernel/kernel_interface.h @@ -39,6 +39,28 @@ * THE SOFTWARE. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + /** * @defgroup kernel_interface kernel_interface * @{ @ingroup kernel @@ -55,6 +77,7 @@ typedef enum kernel_feature_t kernel_feature_t; #include <kernel/kernel_listener.h> #include <kernel/kernel_ipsec.h> #include <kernel/kernel_net.h> +#include <kernel/kernel_fc_sp.h> /** * Default range for SPIs requested from kernels @@ -86,6 +109,11 @@ enum kernel_feature_t { */ typedef kernel_ipsec_t* (*kernel_ipsec_constructor_t)(void); +/** + * Constructor function for fc-sp kernel interface + */ +typedef kernel_fc_sp_t* (*kernel_fc_sp_constructor_t)(void); + /** * Constructor function for network kernel interface */ @@ -104,7 +132,7 @@ struct kernel_interface_t { * * @return ORed feature-set of backends */ - kernel_feature_t (*get_features)(kernel_interface_t *this); + kernel_feature_t (*get_features)(kernel_interface_t *this, int family); /** * Get a SPI from the kernel. @@ -476,6 +504,26 @@ struct kernel_interface_t { bool (*remove_ipsec_interface)(kernel_interface_t *this, kernel_ipsec_constructor_t create); + /** + * Register an fc-sp interface constructor on the manager. + * + * @param create constructor to register + * @return TRUE if the fc-sp kernel interface was registered + * successfully, FALSE if an interface was already + * registered or the registration failed + */ + bool (*add_fc_sp_interface) (kernel_interface_t *this, kernel_fc_sp_constructor_t constructor); + + /** + * Unregister an fc-sp interface constructor. + * + * @param create constructor to unregister + * @return TRUE if the ipsec kernel interface was unregistered + * successfully, FALSE otherwise + */ + bool (*remove_fc_sp_interface)(kernel_interface_t *this, + kernel_fc_sp_constructor_t create); + /** * Register a network kernel interface constructor on the manager. * diff --git a/src/libcharon/kernel/kernel_ipsec.h b/src/libcharon/kernel/kernel_ipsec.h index ae8b82a40..968d8b868 100644 --- a/src/libcharon/kernel/kernel_ipsec.h +++ b/src/libcharon/kernel/kernel_ipsec.h @@ -18,6 +18,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + /** * @defgroup kernel_ipsec kernel_ipsec * @{ @ingroup kernel @@ -192,6 +214,7 @@ struct kernel_ipsec_manage_policy_t { * Data required to query a policy in the kernel */ struct kernel_ipsec_query_policy_t { + int family; }; /** diff --git a/src/libcharon/network/sender.c b/src/libcharon/network/sender.c index 4543766d6..d1745059c 100644 --- a/src/libcharon/network/sender.c +++ b/src/libcharon/network/sender.c @@ -16,6 +16,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include <unistd.h> #include <stdlib.h> @@ -50,6 +72,10 @@ struct private_sender_t { */ mutex_t *mutex; + mutex_t *wakeup_mutex; + + int sender_thread_count; + /** * condvar to signal for packets added to list */ @@ -98,8 +124,8 @@ METHOD(sender_t, send_, void, src = packet->get_source(packet); dst = packet->get_destination(packet); - DBG1(DBG_NET, "sending packet: from %#H to %#H (%zu bytes)", src, dst, - packet->get_data(packet).len); + DBG1(DBG_NET, "sending packet: from %#H to %#H (%zu bytes), src family: %d", src, dst, + packet->get_data(packet).len, src->get_family (src)); if (this->send_delay) { @@ -142,6 +168,7 @@ static job_requeue_t send_packets(private_sender_t *this) { packet_t *packet; bool oldstate; + bool got_wakeup_mutex = false; this->mutex->lock(this->mutex); while (this->list->get_count(this->list) == 0) @@ -151,12 +178,27 @@ static job_requeue_t send_packets(private_sender_t *this) oldstate = thread_cancelability(TRUE); this->got->wait(this->got, this->mutex); + this->wakeup_mutex->lock (this->wakeup_mutex); + got_wakeup_mutex = true; thread_cancelability(oldstate); thread_cleanup_pop(FALSE); + + // If there is a spurious wakeup and we are the second ones to be awoken, + // there may be no send to service. So double check after we get the wakeup lock + // that there is still something to be serviced + if (this->list->get_count(this->list) == 0) + { + this->wakeup_mutex->unlock (this->wakeup_mutex); + got_wakeup_mutex = false; + } } this->list->remove_first(this->list, (void**)&packet); this->sent->signal(this->sent); + if (got_wakeup_mutex) + { + this->wakeup_mutex->unlock (this->wakeup_mutex); + } this->mutex->unlock(this->mutex); charon->socket->send(charon->socket, packet); @@ -192,6 +234,7 @@ METHOD(sender_t, destroy, void, sender_t * sender_create() { private_sender_t *this; + int i; INIT(this, .public = { @@ -202,6 +245,9 @@ sender_t * sender_create() }, .list = linked_list_create(), .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + .wakeup_mutex = mutex_create(MUTEX_TYPE_DEFAULT), + .sender_thread_count = lib->settings->get_int(lib->settings, + "%s.sender_thread_count", 1, lib->ns), .got = condvar_create(CONDVAR_TYPE_DEFAULT), .sent = condvar_create(CONDVAR_TYPE_DEFAULT), .send_delay = lib->settings->get_int(lib->settings, @@ -214,9 +260,12 @@ sender_t * sender_create() "%s.send_delay_response", TRUE, lib->ns), ); + for (i = 0; i < this->sender_thread_count; i++) + { lib->processor->queue_job(lib->processor, (job_t*)callback_job_create_with_prio((callback_job_cb_t)send_packets, this, NULL, (callback_job_cancel_t)return_false, JOB_PRIO_CRITICAL)); + } return &this->public; } diff --git a/src/libcharon/network/socket.h b/src/libcharon/network/socket.h index b4062f8a0..cc3b1beca 100644 --- a/src/libcharon/network/socket.h +++ b/src/libcharon/network/socket.h @@ -17,6 +17,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + /** * @defgroup socket socket * @{ @ingroup network @@ -61,6 +83,11 @@ enum socket_family_t { * Both address families supported */ SOCKET_FAMILY_BOTH = (1 << 2) - 1, + + /** + * FC BSG + */ + SOCKET_FAMILY_FC = (1 << 2), }; /** diff --git a/src/libcharon/network/socket_manager.c b/src/libcharon/network/socket_manager.c index 2b2a05702..f495a1455 100644 --- a/src/libcharon/network/socket_manager.c +++ b/src/libcharon/network/socket_manager.c @@ -15,12 +15,35 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "socket_manager.h" #include <daemon.h> #include <threading/thread.h> #include <threading/rwlock.h> #include <collections/linked_list.h> +#include <collections/hashtable.h> typedef struct private_socket_manager_t private_socket_manager_t; @@ -35,15 +58,20 @@ struct private_socket_manager_t { socket_manager_t public; /** - * List of registered socket constructors + * List of socket constructors used during shutdown. */ - linked_list_t *sockets; + hashtable_t *socket_constructors; /** - * Instantiated socket implementation + * Instantiated socket implementation for IP */ socket_t *socket; + /** + * Instantiated socket implementation for FC + */ + socket_t *fc_socket; + /** * The constructor used to create the current socket */ @@ -77,26 +105,51 @@ METHOD(socket_manager_t, sender, status_t, private_socket_manager_t *this, packet_t *packet) { status_t status; + socket_t *selected_socket = NULL; + this->lock->read_lock(this->lock); - if (!this->socket) + host_t *src = packet->get_source (packet); + int family = src->get_family (src); + + if (family == AF_NETLINK) { - DBG1(DBG_NET, "no socket implementation registered, sending failed"); + selected_socket = this->fc_socket; + } + else + { + selected_socket = this->socket; + } + + if (!selected_socket) + { + DBG1(DBG_NET, "no socket implementation registered for family %d, sending failed", family); this->lock->unlock(this->lock); return NOT_SUPPORTED; } - status = this->socket->send(this->socket, packet); + status = selected_socket->send(selected_socket, packet); this->lock->unlock(this->lock); return status; } METHOD(socket_manager_t, get_port, uint16_t, - private_socket_manager_t *this, bool nat_t) + private_socket_manager_t *this, socket_family_t family, bool nat_t) { uint16_t port = 0; + socket_t *selected_socket; + this->lock->read_lock(this->lock); - if (this->socket) + if (family == SOCKET_FAMILY_FC) + { + selected_socket = this->fc_socket; + } + else { - port = this->socket->get_port(this->socket, nat_t); + selected_socket = this->socket; + } + + if (selected_socket) + { + port = selected_socket->get_port(selected_socket, nat_t); } this->lock->unlock(this->lock); return port; @@ -106,40 +159,58 @@ METHOD(socket_manager_t, supported_families, socket_family_t, private_socket_manager_t *this) { socket_family_t families = SOCKET_FAMILY_NONE; - this->lock->read_lock(this->lock); - if (this->socket) + + // Supported families is not needed for fc_socket because there is only one + // family for FC, i.e. no IPv4 and IPv6. + if (this->socket != NULL) { + this->lock->read_lock(this->lock); families = this->socket->supported_families(this->socket); + this->lock->unlock(this->lock); } - this->lock->unlock(this->lock); return families; } -static void create_socket(private_socket_manager_t *this) +METHOD(socket_manager_t, add_socket, void, + private_socket_manager_t *this, socket_constructor_t create) { - socket_constructor_t create; - /* remove constructors in order to avoid trying to create broken ones - * multiple times */ - while (this->sockets->remove_first(this->sockets, - (void**)&create) == SUCCESS) + socket_t *new_socket; + socket_family_t family; + + this->lock->write_lock(this->lock); + new_socket = create(); + family = new_socket->supported_families (new_socket); + + if (family == SOCKET_FAMILY_FC) + { + if (this->fc_socket) + { + DBG0(DBG_NET, "Attempting to create second FC-SP socket! Ignoring second socket."); + DESTROY_IF (new_socket); + new_socket = NULL; + } + else + { + this->fc_socket = new_socket; + } + } + else { - this->socket = create(); if (this->socket) { - this->create = create; - break; + DBG0(DBG_NET, "Attempting to create second IPsec-SP socket! Ignoring second socket."); + DESTROY_IF (new_socket); + new_socket = NULL; + } + else + { + this->socket = new_socket; } } -} -METHOD(socket_manager_t, add_socket, void, - private_socket_manager_t *this, socket_constructor_t create) -{ - this->lock->write_lock(this->lock); - this->sockets->insert_last(this->sockets, create); - if (!this->socket) + if (new_socket) { - create_socket(this); + this->socket_constructors->put (this->socket_constructors, (void*) create, (void*) family); } this->lock->unlock(this->lock); } @@ -148,14 +219,20 @@ METHOD(socket_manager_t, remove_socket, void, private_socket_manager_t *this, socket_constructor_t create) { this->lock->write_lock(this->lock); - this->sockets->remove(this->sockets, create, NULL); - if (this->create == create) + + socket_family_t family = (socket_family_t) this->socket_constructors->get (this->socket_constructors, (void*) create); + + if (family == SOCKET_FAMILY_FC) + { + this->fc_socket->destroy (this->fc_socket); + this->fc_socket = NULL; + } + else { - this->socket->destroy(this->socket); + this->socket->destroy (this->socket); this->socket = NULL; - this->create = NULL; - create_socket(this); } + this->socket_constructors->remove (this->socket_constructors, (void*) create); this->lock->unlock(this->lock); } @@ -163,7 +240,7 @@ METHOD(socket_manager_t, destroy, void, private_socket_manager_t *this) { DESTROY_IF(this->socket); - this->sockets->destroy(this->sockets); + DESTROY_IF(this->fc_socket); this->lock->destroy(this->lock); free(this); } @@ -185,8 +262,10 @@ socket_manager_t *socket_manager_create() .remove_socket = _remove_socket, .destroy = _destroy, }, - .sockets = linked_list_create(), + .socket_constructors = hashtable_create (hashtable_hash_ptr, hashtable_equals_ptr, 8), .lock = rwlock_create(RWLOCK_TYPE_DEFAULT), + .socket = NULL, + .fc_socket = NULL, ); return &this->public; diff --git a/src/libcharon/network/socket_manager.h b/src/libcharon/network/socket_manager.h index add3ffa2c..ee6d1235f 100644 --- a/src/libcharon/network/socket_manager.h +++ b/src/libcharon/network/socket_manager.h @@ -15,6 +15,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + /** * @defgroup socket_manager socket_manager * @{ @ingroup network @@ -58,7 +80,7 @@ struct socket_manager_t { * @param nat_t TRUE to get the port used to float in case of NAT-T * @return the port, or 0, if no socket is registered */ - uint16_t (*get_port)(socket_manager_t *this, bool nat_t); + uint16_t (*get_port)(socket_manager_t *this, socket_family_t family, bool nat_t); /** * Get the address families the registered socket is listening on. diff --git a/src/libcharon/plugins/auth_els/Makefile.am b/src/libcharon/plugins/auth_els/Makefile.am new file mode 100644 index 000000000..5bb04d3da --- /dev/null +++ b/src/libcharon/plugins/auth_els/Makefile.am @@ -0,0 +1,25 @@ +AM_CPPFLAGS = \ + -I$(top_srcdir)/src/libstrongswan \ + -I$(top_srcdir)/src/libhydra \ + -I$(top_srcdir)/src/libcharon + +AM_CFLAGS = \ + $(PLUGIN_CFLAGS) + +if MONOLITHIC +noinst_LTLIBRARIES = libstrongswan-auth-els.la +else +plugin_LTLIBRARIES = libstrongswan-auth-els.la +endif + +libstrongswan_auth_els_la_SOURCES = \ + auth_els_configs.h auth_els_configs.c \ + auth_els_kernel_fc_sp.h auth_els_kernel_fc_sp.c \ + auth_els_ike.h auth_els_ike.c \ + auth_els_socket.h auth_els_socket.c \ + auth_els_plugin.h auth_els_plugin.c \ + auth_els_utils.h + +libstrongswan_auth_els_la_LDFLAGS = -module -avoid-version + + diff --git a/src/libcharon/plugins/auth_els/auth_els_configs.c b/src/libcharon/plugins/auth_els/auth_els_configs.c new file mode 100644 index 000000000..5a0a0e9c6 --- /dev/null +++ b/src/libcharon/plugins/auth_els/auth_els_configs.c @@ -0,0 +1,183 @@ +/* Copyright (C) 2019-2022 Marvell */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdio.h> +#include <unistd.h> +#include <dirent.h> +#include <signal.h> +#include <errno.h> + +#ifdef AUTH_ELS_KMIP // If we are not compiling KMIP, then don't want these +#include <openssl/bio.h> +#endif + +#include <collections/linked_list.h> +#include <threading/thread.h> +#include <threading/condvar.h> +#include <threading/mutex.h> +#include <processing/jobs/callback_job.h> +#include <credentials/keys/shared_key.h> +#include <utils/identification.h> +#include <collections/hashtable.h> + +#include <config/child_cfg.h> + +#include "auth_els_configs.h" +#include "auth_els_utils.h" + +#define DEFAULT_REAUTH_REKEY_JITTER 30 // minimum time between reauth and rekey +#define CONFIG_LIMIT_OVERRIDE_LIMITS_COOKIE 18652001 + +enum shared_secret_type_t { + SHARED_SECRET_TYPE_WWPN, + SHARED_SECRET_TYPE_CONFIG_FILE, + SHARED_SECRET_TYPE_KMIP, +}; + +struct private_auth_els_configs_t { + + auth_els_configs_t public; + + unsigned int reauth_rekey_jitter; + bool override_limits; // Allows overriding of minimum reauth_time and rekey_time + + chunk_t shared_secret; + enum shared_secret_type_t secret_type; + + proposal_t *esp_proposal; + proposal_t *ike_proposal; + bool vmware; +}; +typedef struct private_auth_els_configs_t private_auth_els_configs_t; + +METHOD(auth_els_configs_t, reload_config, bool, + private_auth_els_configs_t *this) +{ + char *remote, *wwpn, *disabled_remote; + int wwpn_len = 0, index = 0, j = 0; + int cookie; + char *rekey; + + enumerator_t* enumerator = lib->settings->create_section_enumerator(lib->settings, + "%s.plugins.auth-els.disabled_remotes", lib->ns); + + while (enumerator->enumerate(enumerator, &remote)) + { + DBG2(DBG_CFG, "disabled remotes: %s", remote); + wwpn = lib->settings->get_str(lib->settings, + "%s.plugins.auth-els.disabled_remotes.%s.wwpn", NULL, + lib->ns, remote); + if (wwpn == NULL) + { + DBG2(DBG_CFG, "disabled remotes NOT found in auth-els.conf"); + continue; + } + DBG2(DBG_CFG, "disabled remote port for auth from conf '%s'", wwpn); + wwpn_len = strlen(wwpn) + 1; + disabled_remote = (char*)malloc(wwpn_len); + memset(disabled_remote, 0, wwpn_len); + for (index = 0, j = 0; index < strlen(wwpn); index++) + { + if (wwpn[index] == ':') + continue; + if (wwpn[index] == '-') + continue; + if (wwpn[index] == '.') + continue; + if (wwpn[index] == ' ') + continue; + + disabled_remote[j++] = wwpn[index]; + if (index == (strlen(wwpn) - 1)) + disabled_remote[j] = '\0'; + } + + + if(j > 0) + { + + } + else + { + free (disabled_remote); + } + } + enumerator->destroy(enumerator); + + enumerator = lib->settings->create_section_enumerator(lib->settings, + "%s.plugins.auth-els.rekey_config", lib->ns); + + while (enumerator->enumerate(enumerator, &rekey)) + { + this->reauth_rekey_jitter = lib->settings->get_int(lib->settings, + "%s.plugins.auth-els.rekey_config.%s.reauth_rekey_jitter", DEFAULT_REAUTH_REKEY_JITTER, + lib->ns, rekey); + + cookie = lib->settings->get_int(lib->settings, + "%s.plugins.auth-els.rekey_config.%s.override_lower_limits", 0, + lib->ns, rekey); + + if (cookie == CONFIG_LIMIT_OVERRIDE_LIMITS_COOKIE) + { + this->override_limits = true; + } + } + enumerator->destroy(enumerator); + + int sender_thread_count = lib->settings->get_int(lib->settings, + "%s.sender_thread_count", 1, lib->ns); + + this->vmware = lib->settings->get_bool(lib->settings, + "%s.plugins.auth-els.vmware", FALSE, lib->ns); + + DBG_STD ("config setting of reauth_rekey_jitter: %d, override_limits: %d, sender_thread_count: %d", + this->reauth_rekey_jitter, this->override_limits, sender_thread_count); + + return TRUE; +} + +METHOD(auth_els_configs_t, get_vmware, bool, + private_auth_els_configs_t *this) +{ + return this->vmware; +} + +METHOD(auth_els_configs_t, get_reauth_rekey_jitter, unsigned int, + private_auth_els_configs_t *this) +{ + return this->reauth_rekey_jitter; +} + +METHOD(auth_els_configs_t, get_override_limits, bool, + private_auth_els_configs_t *this) +{ + return this->override_limits; +} + +METHOD(auth_els_configs_t, destroy, void, + private_auth_els_configs_t *this) +{ + DBG_ENTER; + + free(this); +} + +auth_els_configs_t *auth_els_configs_create() +{ + private_auth_els_configs_t *this; + + INIT(this, + .public = { + .destroy = _destroy, + .reload_config = _reload_config, + .get_reauth_rekey_jitter = _get_reauth_rekey_jitter, + .get_override_limits = _get_override_limits, + .get_vmware = _get_vmware, + }, + .override_limits = false, + .vmware = false, + ); + + return &(this->public); +} diff --git a/src/libcharon/plugins/auth_els/auth_els_configs.h b/src/libcharon/plugins/auth_els/auth_els_configs.h new file mode 100644 index 000000000..184651da2 --- /dev/null +++ b/src/libcharon/plugins/auth_els/auth_els_configs.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2019-2020 Marvell */ + +/** + * @defgroup auth_els auth_els + * @ingroup cplugins + * + * @defgroup auth_els_configs auth_els_configs + * @{ @ingroup auth_els + */ + +#ifndef AUTH_ELS_CONFIGS_H_ +#define AUTH_ELS_CONFIGS_H_ + +#include <credentials/credential_set.h> +#include <daemon.h> + +// ESP proposal default +#define ESP_ENCR_PROPOSAL_DEFAULT_128_BIT "aes128gcm16" + +// IKE proposal default +#define IKE_PROPOSAL_DEFAULT_128_BIT "aes128gcm16-prfsha256-curve25519" + +#define HOST_NAME_SIZE 16 +#define HOST_ID_SIZE 4 +#define REMOTE_PORT_ID_SIZE 4 +#define PEER_NAME_SIZE 33 + +typedef struct auth_els_configs_t auth_els_configs_t; +struct auth_els_configs_t { + + bool (*reload_config)(auth_els_configs_t *this); + unsigned int (*get_reauth_rekey_jitter)(auth_els_configs_t *this); + bool (*get_override_limits)(auth_els_configs_t *this); + bool (*get_vmware) (auth_els_configs_t *this); + + void (*destroy)(auth_els_configs_t *this); +}; + +auth_els_configs_t *auth_els_configs_create(); + +#endif /** AUTH_ELS_CONFIGS_H_ @}*/ diff --git a/src/libcharon/plugins/auth_els/auth_els_ike.c b/src/libcharon/plugins/auth_els/auth_els_ike.c new file mode 100644 index 000000000..2640469ca --- /dev/null +++ b/src/libcharon/plugins/auth_els/auth_els_ike.c @@ -0,0 +1,270 @@ +/* Copyright (C) 2019-2020 Marvell */ + +#include <errno.h> +#include <fcntl.h> +#include <getopt.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/ioctl.h> +#include <scsi/scsi.h> +#include <scsi/sg.h> +#include <linux/types.h> + +#include <linux/bsg.h> +#include <sys/socket.h> +#include <errno.h> +#include <unistd.h> + +#include <scsi/scsi.h> +#include <scsi/scsi_bsg_fc.h> + +#include <sa/ikev2/keymat_v2.h> +#include <sa/ikev1/keymat_v1.h> +#include <sa/ikev2/tasks/child_create.h> +#include <encoding/payloads/nonce_payload.h> +#include <encoding/payloads/cert_payload.h> +#include <encoding/payloads/auth_payload.h> +#include <encoding/payloads/id_payload.h> +#include <encoding/payloads/sa_payload.h> +#include <encoding/payloads/ts_payload.h> +#include <encoding/payloads/ke_payload.h> +#include <encoding/payloads/notify_payload.h> +#include <threading/rwlock.h> +#include <threading/condvar.h> +#include <threading/mutex.h> +#include <processing/jobs/rekey_ike_sa_job.h> +#include <processing/jobs/rekey_child_sa_job.h> +#include <processing/jobs/delete_ike_sa_job.h> + +#include "auth_els_ike.h" +#include "auth_els_socket.h" +#include "auth_els_utils.h" + +/** + * Private data of an auth_els_ike_t object. + */ +typedef struct private_auth_els_ike_t private_auth_els_ike_t; +struct private_auth_els_ike_t { + + /** + * Public auth_els_ike_t interface. + */ + auth_els_ike_t public; + + hashtable_t *fchosts; + +}; + + + +METHOD(listener_t, ike_keys, bool, + private_auth_els_ike_t *this, ike_sa_t *ike_sa, key_exchange_t *dh, + chunk_t dh_other, chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey, + shared_key_t *shared, auth_method_t method) +{ + DBG_ENTER; + + return TRUE; +} + +METHOD(listener_t, ike_updown, bool, + private_auth_els_ike_t *this, ike_sa_t *ike_sa, bool up) +{ + DBG_STD ("enter: up=%s", (up? "yes" : "no")); + + return TRUE; +} + +METHOD(listener_t, ike_rekey, bool, + private_auth_els_ike_t *this, ike_sa_t *old, ike_sa_t *new) +{ + return TRUE; +} + + +METHOD(listener_t, child_keys, bool, + private_auth_els_ike_t *this, ike_sa_t *ike_sa, child_sa_t *child_sa, + bool initiator, key_exchange_t *dh, chunk_t nonce_i, chunk_t nonce_r) +{ + DBG_STD ("ike_sa: %p, child_sa: %p", ike_sa, child_sa); + + return TRUE; +} + +METHOD(listener_t, child_state_change, bool, + private_auth_els_ike_t *this, ike_sa_t *ike_sa, + child_sa_t *child_sa, child_sa_state_t state) +{ + + DBG_STD ("ike_sa: %p, child_sa: %p, new state: %N", ike_sa, child_sa, child_sa_state_names, state); + + return TRUE; +} + +METHOD(listener_t, child_updown, bool, + private_auth_els_ike_t *this, ike_sa_t *ike_sa, + child_sa_t *child_sa, bool up) +{ + DBG_ENTER; + + return TRUE; +} + +METHOD(listener_t, child_rekey, bool, + private_auth_els_ike_t *this, ike_sa_t *ike_sa, + child_sa_t *old, child_sa_t *new) +{ + DBG_STD ("ike_sa: %p, child_sa old: %p, new: %p", ike_sa, old, new); + + return TRUE; +} + +METHOD(listener_t, narrow, bool, + private_auth_els_ike_t *this, ike_sa_t *ike_sa, + child_sa_t *child_sa, narrow_hook_t type, + linked_list_t *local, linked_list_t *remote) +{ + DBG_ENTER; + + return TRUE; +} + +METHOD(listener_t, ike_reestablish_pre, bool, + private_auth_els_ike_t *this, ike_sa_t *old, ike_sa_t *new) +{ + DBG_ENTER; + return TRUE; +} + +METHOD(listener_t, ike_reestablish_post, bool, + private_auth_els_ike_t *this, ike_sa_t *old, ike_sa_t *new, + bool initiated) +{ + DBG_ENTER; + return TRUE; +} + +METHOD(listener_t, ike_state_change, bool, + private_auth_els_ike_t *this, ike_sa_t *ike_sa, ike_sa_state_t new) +{ + DBG_STD ("ike_sa: %p, new_state=%N", ike_sa, ike_sa_state_names, new); + + return TRUE; +} + +METHOD(listener_t, message_hook, bool, + private_auth_els_ike_t *this, ike_sa_t *ike_sa, message_t *message, + bool incoming, bool plain) +{ + DBG_STD ("plain=%s - incoming=%s - request=%s message=%N, message_id initiate: %x, respond: %x", + (plain?"true":"false"), + (incoming?"true":"false"), + (message->get_request(message)?"true":"false"), + exchange_type_names, message->get_exchange_type(message), + ike_sa->get_message_id(ike_sa, true), ike_sa->get_message_id(ike_sa, false)); + + return true; +} + +METHOD(listener_t, authorize, bool, + private_auth_els_ike_t *this, ike_sa_t *ike_sa, + bool final, bool *success) +{ + DBG2(DBG_CFG, "auth_els - entering authorize event"); + + if (final) + { + DBG_STD ("final event"); + } + + *success = TRUE; + + return TRUE; /* stay registered */ +} + + +METHOD(listener_t, alert_hook, bool, + private_auth_els_ike_t *this, ike_sa_t *ike_sa, alert_t alert, va_list args) +{ + DBG_STD ("enter: alert=%d, ike_sa: %p", alert, ike_sa); + + switch(alert) + { + case ALERT_SHUTDOWN_SIGNAL: + DBG_STD ("AUTH_ELS Plugin shutdown: send app_stop to all hosts now."); + break; + + case ALERT_KEEP_ON_CHILD_SA_FAILURE: + case ALERT_RETRANSMIT_SEND_TIMEOUT: + case ALERT_HALF_OPEN_TIMEOUT: + case ALERT_PEER_INIT_UNREACHABLE: + case ALERT_LOCAL_AUTH_FAILED: + case ALERT_PEER_AUTH_FAILED: + case ALERT_PEER_ADDR_FAILED: + case ALERT_PARSE_ERROR_HEADER: + case ALERT_PARSE_ERROR_BODY: + case ALERT_PROPOSAL_MISMATCH_IKE: + case ALERT_PROPOSAL_MISMATCH_CHILD: + case ALERT_TS_MISMATCH: + case ALERT_INSTALL_CHILD_SA_FAILED: + case ALERT_INSTALL_CHILD_POLICY_FAILED: + case ALERT_AUTHORIZATION_FAILED: + case ALERT_RETRANSMIT_RECEIVE: + + case ALERT_INVALID_IKE_SPI: + case ALERT_TS_NARROWED: + case ALERT_RETRANSMIT_SEND: + case ALERT_IKE_SA_EXPIRED: + default: + break; + }; + + return TRUE; +} + +METHOD(auth_els_ike_t, destroy, void, + private_auth_els_ike_t *this) +{ + DBG2(DBG_CFG, "auth_els_ike: destroy"); + + free(this); +} + +/** + * See header + */ +auth_els_ike_t *auth_els_ike_create() +{ + DBG2(DBG_CFG, "In auth_els_ike_create"); + + private_auth_els_ike_t *this; + + INIT(this, + .public = { + .listener = { + .ike_keys = _ike_keys, + .ike_updown = _ike_updown, + .ike_rekey = _ike_rekey, + .ike_state_change = _ike_state_change, + .message = _message_hook, + .authorize = _authorize, + .alert = _alert_hook, + .ike_reestablish_pre = _ike_reestablish_pre, + .ike_reestablish_post = _ike_reestablish_post, + .child_keys = _child_keys, + .child_state_change = _child_state_change, + .child_updown = _child_updown, + .child_rekey = _child_rekey, + .narrow = _narrow, + }, + .destroy = _destroy, + }, + ); + + return &(this->public); +} diff --git a/src/libcharon/plugins/auth_els/auth_els_ike.h b/src/libcharon/plugins/auth_els/auth_els_ike.h new file mode 100644 index 000000000..39e53c09e --- /dev/null +++ b/src/libcharon/plugins/auth_els/auth_els_ike.h @@ -0,0 +1,42 @@ +/* Copyright (C) 2019-2020 Marvell */ + +/** + * @defgroup auth_els_ike auth_els_ike + * @{ @ingroup auth_els + */ + +#ifndef AUTH_ELS_IKE_H_ +#define AUTH_ELS_IKE_H_ + +#include <collections/hashtable.h> +#include <sa/ike_sa.h> +#include <daemon.h> + +typedef struct auth_els_ike_t auth_els_ike_t; +/** + * Listener to synchronize IKE_SAs. + */ +struct auth_els_ike_t { + + /** + * Implements bus listener interface. + */ + listener_t listener; + + /** + * Destroy a auth_els_ike_t. + */ + void (*destroy)(auth_els_ike_t *this); + +}; + +/** + * Create a auth_els_ike instance. + * + * @param cache message cache + * @param cache List of rport sockets + * @return IKE listener + */ +auth_els_ike_t *auth_els_ike_create(); + +#endif /** AUTH_ELS_IKE_ @}*/ diff --git a/src/libcharon/plugins/auth_els/auth_els_kernel_fc_sp.c b/src/libcharon/plugins/auth_els/auth_els_kernel_fc_sp.c new file mode 100644 index 000000000..3d3544e3f --- /dev/null +++ b/src/libcharon/plugins/auth_els/auth_els_kernel_fc_sp.c @@ -0,0 +1,235 @@ +/* Copyright (C) 2019-2020 Marvell */ + +#include "auth_els_kernel_fc_sp.h" + +#include <collections/hashtable.h> +#include <collections/linked_list.h> +#include <processing/jobs/delete_ike_sa_job.h> +#include <threading/rwlock.h> +#include <threading/mutex.h> +#include <daemon.h> + +#include "auth_els_utils.h" + +#include <errno.h> +#include <linux/xfrm.h> +#include <utils/debug.h> +#include <utils/chunk.h> + +typedef struct private_auth_els_kernel_fc_sp_t private_auth_els_kernel_fc_sp_t; + +/** + * Private variables and functions of auth_els kernel fc_sp instance. + */ +struct private_auth_els_kernel_fc_sp_t { + + /** + * Public auth_els_kernel_fc_sp interface. + */ + auth_els_kernel_fc_sp_t public; + + /** + * RNG used for SPI generation. + */ + rng_t *rng; + /** + * Lock to access the RNG instance and the callback for getting spi + */ + rwlock_t *spi_lock; +}; + + +METHOD(kernel_fc_sp_t, get_features, kernel_feature_t, + private_auth_els_kernel_fc_sp_t *this) +{ + DBG2 (DBG_CFG, "auth_els - auth_els_kernel_fc_sp - get_features callback, ignoring"); + return KERNEL_POLICY_SPI; +} + +METHOD(kernel_fc_sp_t, get_spi, status_t, + private_auth_els_kernel_fc_sp_t *this, host_t *src, host_t *dst, + uint8_t protocol, uint32_t *spi) +{ + DBG_ENTER; + + bool result = FALSE; + + this->spi_lock->read_lock(this->spi_lock); + + if (!this->rng) + { + DBG_FATAL ("unable to create RNG"); + *spi = 0; + this->spi_lock->unlock(this->spi_lock); + return FAILED; + } + + result = this->rng->get_bytes(this->rng, sizeof(uint32_t), + (uint8_t *)spi); + if (!result) + { + DBG_FATAL ("get_spi failed, set to 0"); + *spi = 0; + } + this->spi_lock->unlock(this->spi_lock); + + DBG_STD ("src port_number %d dest port_number %d, spi provided: %x", src->get_port(src), dst->get_port(dst), *spi); + + return result ? SUCCESS : FAILED; +} + +METHOD(kernel_fc_sp_t, get_cpi, status_t, + private_auth_els_kernel_fc_sp_t *this, host_t *src, host_t *dst, + uint16_t *cpi) +{ + DBG_ENTER; + (void) this; + (void) src; + (void) dst; + (void) cpi; + + return NOT_SUPPORTED; +} + +METHOD(kernel_fc_sp_t, add_sa, status_t, + private_auth_els_kernel_fc_sp_t *this, kernel_fc_sp_sa_id_t *id, + kernel_fc_sp_add_sa_t *data) +{ + DBG_ENTER; + + uint32_t key_size; + uint16_t remote_port_number; + status_t final_status = FAILED; + + key_size = data->enc_key.len - 4; + + if (data->inbound) + { + remote_port_number = id->src->get_port(id->src); + } + else + { + remote_port_number = id->dst->get_port(id->dst); + } + + DBG_STD ("remote_port_number: %d, enc_alg: %N, key_size: %d", + remote_port_number, encryption_algorithm_names, data->enc_alg, key_size); + + return final_status; +} + +METHOD(kernel_fc_sp_t, query_sa, status_t, + private_auth_els_kernel_fc_sp_t *this, kernel_fc_sp_sa_id_t *id, + kernel_fc_sp_query_sa_t *data, uint64_t *bytes, uint64_t *packets, + time_t *time) +{ + DBG_ENTER; + + int ret_status = SUCCESS; + + *bytes = 0; + *packets = 0; // Driver only provides bytes for now. + + return ret_status; +} + +METHOD(kernel_fc_sp_t, del_sa, status_t, + private_auth_els_kernel_fc_sp_t *this, + kernel_fc_sp_sa_id_t *id, + kernel_fc_sp_del_sa_t *data) +{ + status_t final_status = FAILED; + + DBG_STD ("start: spi: %x", id->spi); + + return final_status; +} + +METHOD(kernel_fc_sp_t, update_sa, status_t, + private_auth_els_kernel_fc_sp_t *this, kernel_fc_sp_sa_id_t *id, + kernel_fc_sp_update_sa_t *data) +{ + DBG_ENTER; + DBG_STD ("child_sa: me: %d, other: %d", + id->src->get_port(id->src), id->dst->get_port(id->dst)); + + return SUCCESS; +} + +METHOD(kernel_fc_sp_t, add_policy, status_t, + private_auth_els_kernel_fc_sp_t *this, kernel_fc_sp_policy_id_t *id, + kernel_fc_sp_manage_policy_t *data) +{ + DBG_ENTER; + return SUCCESS; +} + +METHOD(kernel_fc_sp_t, query_policy, status_t, + private_auth_els_kernel_fc_sp_t *this, kernel_fc_sp_policy_id_t *id, + kernel_fc_sp_query_policy_t *data, time_t *use_time) +{ + DBG_ENTER; + return NOT_SUPPORTED; +} + +METHOD(kernel_fc_sp_t, del_policy, status_t, + private_auth_els_kernel_fc_sp_t *this, kernel_fc_sp_policy_id_t *id, + kernel_fc_sp_manage_policy_t *data) +{ + DBG_ENTER; + return SUCCESS; +} + +METHOD(kernel_fc_sp_t, bypass_socket, bool, + private_auth_els_kernel_fc_sp_t *this, int fd, int family) +{ + DBG_ENTER; + return TRUE; +} + +METHOD(kernel_fc_sp_t, enable_udp_decap, bool, + private_auth_els_kernel_fc_sp_t *this, int fd, int family, uint16_t port) +{ + DBG_ENTER; + return TRUE; +} + +METHOD(kernel_fc_sp_t, destroy, void, + private_auth_els_kernel_fc_sp_t *this) +{ + DESTROY_IF(this->rng); + DESTROY_IF(this->spi_lock); + free(this); +} + +/* + * Described in header. + */ +auth_els_kernel_fc_sp_t *auth_els_kernel_fc_sp_create() +{ + private_auth_els_kernel_fc_sp_t *this; + + INIT(this, + .public = { + .interface = { + .get_features = _get_features, + .get_spi = _get_spi, + .get_cpi = _get_cpi, + .add_sa = _add_sa, + .update_sa = _update_sa, + .query_sa = _query_sa, + .del_sa = _del_sa, + .add_policy = _add_policy, + .query_policy = _query_policy, + .del_policy = _del_policy, + .bypass_socket = _bypass_socket, + .enable_udp_decap = _enable_udp_decap, + .destroy = _destroy, + }, + }, + .rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK), + .spi_lock = rwlock_create(RWLOCK_TYPE_DEFAULT), + ); + + return &this->public; +} diff --git a/src/libcharon/plugins/auth_els/auth_els_kernel_fc_sp.h b/src/libcharon/plugins/auth_els/auth_els_kernel_fc_sp.h new file mode 100644 index 000000000..3a1ab787e --- /dev/null +++ b/src/libcharon/plugins/auth_els/auth_els_kernel_fc_sp.h @@ -0,0 +1,35 @@ +/* Copyright (C) 2019-2020 Marvell */ + +/** + * @defgroup auth_els-kernel-ipsec kernel ipsec + * @{ @ingroup auth_els + */ + +#ifndef AUTH_ELS_KERNEL_IPSEC_H_ +#define AUTH_ELS_KERNEL_IPSEC_H_ + +#include <kernel/kernel_fc_sp.h> +#include <sa/ike_sa.h> + +typedef struct auth_els_kernel_fc_sp_t auth_els_kernel_fc_sp_t; + +/** + * auth_els implementation of the kernel ipsec interface. + */ +struct auth_els_kernel_fc_sp_t { + + /** + * Implements kernel_fc_sp_t interface + */ + kernel_fc_sp_t interface; + +}; + +/** + * Create a auth_els kernel ipsec interface instance. + * + * @return auth_els_kernel_fc_sp_t instance + */ +auth_els_kernel_fc_sp_t *auth_els_kernel_fc_sp_create(); + +#endif /** AUTH_ELS_KERNEL_IPSEC_H_ @}*/ diff --git a/src/libcharon/plugins/auth_els/auth_els_plugin.c b/src/libcharon/plugins/auth_els/auth_els_plugin.c new file mode 100644 index 000000000..e59722622 --- /dev/null +++ b/src/libcharon/plugins/auth_els/auth_els_plugin.c @@ -0,0 +1,213 @@ +/* Copyright (C) 2019-2020 Marvell */ + +#include <stdint.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <stdio.h> +#include <unistd.h> +#include <dirent.h> +#include <signal.h> +#include <errno.h> +#include <linux/netlink.h> +#include <scsi/scsi_netlink_fc.h> +#include <scsi/scsi_netlink.h> +#include <pthread.h> + +#include <collections/linked_list.h> + +#include <processing/jobs/callback_job.h> +#include <credentials/credential_set.h> +#include <credentials/keys/shared_key.h> +#include <utils/identification.h> +#include <utils/backtrace.h> +#include <threading/thread.h> +#include <daemon.h> + +#include "auth_els_utils.h" +#include "auth_els_plugin.h" +#include "auth_els_ike.h" +#include "auth_els_socket.h" +#include "auth_els_kernel_fc_sp.h" +#include "auth_els_configs.h" + +/** + * private data of auth_els plugin + */ +struct private_auth_els_plugin_t { + + auth_els_plugin_t public; + auth_els_configs_t *configs; + + auth_els_ike_t *ike; + + int apidev_fd; +}; +typedef struct private_auth_els_plugin_t private_auth_els_plugin_t; + +// This plugin reference is being used for handling of signals because retreiving +// a context is too complicated. Use with caution otherwise. +private_auth_els_plugin_t *plugin_ref; + + +static void handle_system_fault(int sig_type, siginfo_t* si, void* arg) +{ + DBG_STD ("thread %u received %d", thread_current_id(), sig_type); + + backtrace_t *backtrace; + + backtrace = backtrace_create(2); + backtrace->log(backtrace, NULL, TRUE); + backtrace->log(backtrace, stderr, TRUE); + backtrace->destroy(backtrace); + + DBG_STD ("killing ourself, received critical signal"); + abort(); +} + +static void setup_signal_handlers (private_auth_els_plugin_t *plugin) +{ + struct sigaction sa; + + // fault handler + memset (&sa, 0, sizeof (struct sigaction)); // struct + sigemptyset(&sa.sa_mask); + sa.sa_sigaction = handle_system_fault; + sa.sa_flags = SA_SIGINFO; + sigaction(SIGSEGV, &sa, NULL); + sigaction(SIGFPE, &sa, NULL); + sigaction(SIGILL, &sa, NULL); + + sigaction(SIGINT, &sa, NULL); + sigaction(SIGQUIT, &sa, NULL); + sigaction(SIGABRT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGHUP, &sa, NULL); + //sigaction(SIGTSTP, &sa, NULL); +} + +/** + * Initialize plugin + */ +static bool initialize_plugin(private_auth_els_plugin_t *this) +{ + if (this->configs) + { + if (this->configs->reload_config(this->configs) == FALSE) + { + return FALSE; + } + } + + this->ike = auth_els_ike_create(); + + setup_signal_handlers (this); + + if (this->configs->get_vmware (this->configs)) + { + // VMWare does not need a reference because having the VMWare powered on + // provides the reference when the fake scsi device is created. + DBG_STD ("VMware setup: Skipping reference set for driver."); + } + + return TRUE; +} + +/** + * Initialize plugin and register listener + */ +static bool plugin_cb(private_auth_els_plugin_t *this, + plugin_feature_t *feature, bool reg, void *cb_data) +{ + if (reg) + { + if (!initialize_plugin(this)) + { + return FALSE; + } + charon->bus->add_listener(charon->bus, &this->ike->listener); + } + + return TRUE; +} + +METHOD(plugin_t, get_name, char*, + private_auth_els_plugin_t *this) +{ + return "auth-els"; +} + +METHOD(plugin_t, get_features, int, + private_auth_els_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK(kernel_fc_sp_register, auth_els_kernel_fc_sp_create), + PLUGIN_PROVIDE(CUSTOM, "kernel-fc-sp"), + PLUGIN_CALLBACK(socket_register, auth_els_socket_create), + PLUGIN_PROVIDE(CUSTOM, "socket"), + PLUGIN_DEPENDS(CUSTOM, "kernel-fc-sp"), + PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL), + PLUGIN_PROVIDE(CUSTOM, "auth_els"), + }; + *features = f; + + return countof(f); +} + +METHOD(plugin_t, reload, bool, + private_auth_els_plugin_t *this) +{ + if (this->configs->reload_config(this->configs) == FALSE) + { + return FALSE; + } + + return TRUE; +} + +METHOD(plugin_t, destroy, void, + private_auth_els_plugin_t *this) +{ + DBG_ENTER; + DESTROY_IF(this->ike); + + DESTROY_IF(this->configs); + free(this); + + DBG_STD ("Plugin destroy complete"); +} + +/** + * Plugin constructor + */ +plugin_t *auth_els_plugin_create() +{ + private_auth_els_plugin_t *this; + + if (!lib->caps->keep(lib->caps, CAP_CHOWN)) + { + DBG_FATAL ("creation failed"); + return NULL; + } + + INIT(this, + .public = { + .plugin = { + .get_name = _get_name, + .get_features = _get_features, + .reload = _reload, + .destroy = _destroy, + }, + }, + .apidev_fd = -1, + .configs = auth_els_configs_create(), + ); + + char auth_els_plugin_version[AUTH_MAX_STRING_VERSION_LEN + 1]; + + sprintf(auth_els_plugin_version, "%d.%02d.%04d%s", + AUTH_MAJOR_VERSION, AUTH_MINOR_VERSION, AUTH_BUILD_VERSION, AUTH_STRING_SUFFIX_VERSION); + DBG1(DBG_CFG, "auth_els version is %s.", + auth_els_plugin_version); + + return &this->public.plugin; +} diff --git a/src/libcharon/plugins/auth_els/auth_els_plugin.h b/src/libcharon/plugins/auth_els/auth_els_plugin.h new file mode 100644 index 000000000..584607abb --- /dev/null +++ b/src/libcharon/plugins/auth_els/auth_els_plugin.h @@ -0,0 +1,46 @@ +/* Copyright (C) 2019-2020 Marvell */ + +/** + * @defgroup auth_els auth_els + * @ingroup cplugins + * + * @defgroup auth_els_plugin auth_els_plugin + * @{ @ingroup auth_els + */ + +#ifndef AUTH_ELS_PLUGIN_H_ +#define AUTH_ELS_PLUGIN_H_ + +#include <plugins/plugin.h> + +#define AUTH_MAJOR_VERSION 1 +#define AUTH_MINOR_VERSION 5 +#define AUTH_BUILD_VERSION 2 +#define AUTH_STRING_SUFFIX_VERSION "-125-alpha1" +#define AUTH_MAX_STRING_VERSION_LEN 32 + +#define APIDEV_DEVICE "/dev/ql2xapidev" +#define MEMTRACE_MAX_BACKTRACE_DEPTH (64) +#define CHARON_EXECUTABLE "charon" +#define SHELL_BUF_SIZE 512 + +#define HOST_NO_UNASSIGNED 0xffff + +#define SWANCTL_LOAD_CERTS "swanctl -q" + + +/** + * Plugin to synchronize state in a high availability cluster. + */ +typedef struct auth_els_plugin_t auth_els_plugin_t; +struct auth_els_plugin_t { + + /** + * implements plugin interface + */ + plugin_t plugin; + +}; +typedef struct auth_els_plugin_t auth_els_plugin_t; + +#endif /** AUTH_ELS_PLUGIN_H_ @}*/ diff --git a/src/libcharon/plugins/auth_els/auth_els_socket.c b/src/libcharon/plugins/auth_els/auth_els_socket.c new file mode 100644 index 000000000..a87e03aa1 --- /dev/null +++ b/src/libcharon/plugins/auth_els/auth_els_socket.c @@ -0,0 +1,114 @@ +/* Copyright (C) 2019-2020 Marvell */ + +#include <utils/chunk.h> +#include <config/child_cfg.h> + +#include <errno.h> +#include <fcntl.h> +#include <getopt.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/ioctl.h> +#include <scsi/scsi.h> +#include <scsi/sg.h> +#include <linux/types.h> + +#include <linux/bsg.h> +#include <scsi/scsi_bsg_fc.h> + +#include <sys/types.h> +#include <sys/socket.h> +#include <errno.h> +#include <unistd.h> + +/* "readdir" etc. are defined here. */ +#include <dirent.h> +/* limits.h defines "PATH_MAX". */ +#include <limits.h> + +#include <daemon.h> +#include <networking/host.h> +#include <processing/jobs/callback_job.h> + +#include <pthread.h> + +#include "auth_els_socket.h" +#include "auth_els_utils.h" + +/** + * Data to pass to the send_message() callback job + */ +typedef struct { + chunk_t chunk; + int fd; +} job_data_t; + +typedef struct private_auth_els_socket_t private_auth_els_socket_t; +/** + * Private data of an auth_els_socket_t object. + */ +struct private_auth_els_socket_t { + + auth_els_socket_t public; + +}; + +METHOD(socket_t, supported_families, socket_family_t, + private_auth_els_socket_t *this) +{ + return SOCKET_FAMILY_FC; +} + +METHOD(socket_t, destroy, void, + private_auth_els_socket_t *this) +{ + free(this); +} + +METHOD(socket_t, receiver, status_t, + private_auth_els_socket_t *this, packet_t **packet) +{ + DBG_ENTER; + + // We don't use the receiver function, so just tell the core to stop trying. + // Receives are done when the driver gives us an ELS_RECV AEN. + return NOT_SUPPORTED; +} + +METHOD(socket_t, sender, status_t, + private_auth_els_socket_t *this, packet_t *packet) +{ + DBG_ENTER; + + return NOT_SUPPORTED; +} + +METHOD(socket_t, get_port, uint16_t, + private_auth_els_socket_t *this, bool nat_t) +{ + return 77; // dummy host number +} + +auth_els_socket_t *auth_els_socket_create() +{ + private_auth_els_socket_t *this; + + INIT(this, + .public = { + .socket = { + .send = _sender, + .receive = _receiver, + .supported_families = _supported_families, + .get_port = _get_port, + .destroy = _destroy, + }, + }, + ); + + return &this->public; +} \ No newline at end of file diff --git a/src/libcharon/plugins/auth_els/auth_els_socket.h b/src/libcharon/plugins/auth_els/auth_els_socket.h new file mode 100644 index 000000000..efef65723 --- /dev/null +++ b/src/libcharon/plugins/auth_els/auth_els_socket.h @@ -0,0 +1,29 @@ +/* Copyright (C) 2019-2020 Marvell */ + +/** + * @defgroup auth_els_socket auth_els_socket + * @{ @ingroup auth_els + */ + +#ifndef AUTH_ELS_SOCKET_H_ +#define AUTH_ELS_SOCKET_H_ + +#include <sa/ike_sa.h> +#include <collections/hashtable.h> +#include <network/socket.h> + +/** + * Socket to send/received SA synchronization data + */ +typedef struct auth_els_socket_t auth_els_socket_t; +struct auth_els_socket_t { + + socket_t socket; +}; + +/** + * Create a default auth_els_socket instance. + */ +auth_els_socket_t *auth_els_socket_create(); + +#endif /** AUTH_ELS_SOCKET_ @}*/ diff --git a/src/libcharon/plugins/auth_els/auth_els_utils.h b/src/libcharon/plugins/auth_els/auth_els_utils.h new file mode 100644 index 000000000..97aa8ef60 --- /dev/null +++ b/src/libcharon/plugins/auth_els/auth_els_utils.h @@ -0,0 +1,60 @@ +/* Copyright (C) 2019-2020 Marvell */ + +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: auth_els_utils.h + * Author: cwinkler + * + * Created on February 19, 2020, 8:02 AM + */ + +#ifndef AUTH_ELS_UTILS_H +#define AUTH_ELS_UTILS_H + +#include <pthread.h> + +#define DBG_ENTER { \ + char final_format[1024]; \ + sprintf (final_format, "%s: %s: %d: enter, thread_id: %lx", __FILE__, __func__, __LINE__, pthread_self()); \ + DBG1 (DBG_CFG, final_format); \ +} + +#define DBG_STD(format, ...) { \ + char final_format[1024]; \ + sprintf (final_format, "%s: %s: %d: %s, thread_id: %lx", __FILE__, __func__, __LINE__, format, pthread_self()); \ + DBG1 (DBG_CFG, final_format, ##__VA_ARGS__); \ +} + +#define DBG_FATAL(format, ...) { \ + char final_format[1024]; \ + sprintf (final_format, "%s: %s: %d: FATAL_ERROR: %s, thread_id: %lx", __FILE__, __func__, __LINE__, format, pthread_self()); \ + DBG0 (DBG_CFG, final_format, ##__VA_ARGS__); \ +} + +#define DBG_DRIVER(format, ...) { \ + char final_format[1024]; \ + sprintf (final_format, "%s: %s: %d: DRIVER ERROR: %s, thread_id: %lx", __FILE__, __func__, __LINE__, format, pthread_self()); \ + DBG0 (DBG_CFG, final_format, ##__VA_ARGS__); \ +} + +#define DBG_HOST(fchost, rport, format, ...) { \ + char final_format[1024]; \ + sprintf (final_format, "%s: %s: %d: host_no: %d, pid: %06x: rport_index: %d: %s, thread_id: %lx", \ + __FILE__, __func__, __LINE__, fchost->get_host_no(fchost), rport->port_id.b24, rport->rport_index, \ + format, pthread_self()); \ + DBG1 (DBG_CFG, final_format, ##__VA_ARGS__); \ +} + +#define DBG_HOST1(fchost_dispatcher, rport, format, ...) { \ + char final_format[1024]; \ + sprintf (final_format, "%s: %s: %d: host_no: %d, rport_index: %d: %s, thread_id: %lx", \ + __FILE__, __func__, __LINE__, fchost_dispatcher->host_no, rport->rport_index, format, pthread_self()); \ + DBG1 (DBG_CFG, final_format, ##__VA_ARGS__); \ +} +#endif /* AUTH_ELS_UTILS_H */ + diff --git a/src/libcharon/plugins/ha/ha_tunnel.c b/src/libcharon/plugins/ha/ha_tunnel.c index d7e83a06b..80f3a23f0 100644 --- a/src/libcharon/plugins/ha/ha_tunnel.c +++ b/src/libcharon/plugins/ha/ha_tunnel.c @@ -14,6 +14,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "ha_tunnel.h" #include "ha_plugin.h" @@ -194,7 +216,7 @@ static void setup_tunnel(private_ha_tunnel_t *this, ike_cfg_create_t ike = { .version = IKEV2, .local = local, - .local_port = charon->socket->get_port(charon->socket, FALSE), + .local_port = charon->socket->get_port(charon->socket, SOCKET_FAMILY_BOTH, FALSE), .remote = remote, .remote_port = IKEV2_UDP_PORT, .no_certreq = TRUE, diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c index 97309a6d2..7dcb15676 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c @@ -1126,7 +1126,7 @@ static void process_link(private_kernel_netlink_net_t *this, ); this->ifaces->insert_last(this->ifaces, entry); } - strncpy(entry->ifname, name, IFNAMSIZ); + strncpy(entry->ifname, name, IFNAMSIZ-1); entry->ifname[IFNAMSIZ-1] = '\0'; entry->usable = charon->kernel->is_interface_usable(charon->kernel, name); diff --git a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c index fe36885c1..7b1c9e517 100644 --- a/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c +++ b/src/libcharon/plugins/kernel_pfkey/kernel_pfkey_ipsec.c @@ -36,6 +36,28 @@ * THE SOFTWARE. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include <stdint.h> #include <sys/types.h> #include <sys/socket.h> @@ -2525,7 +2547,7 @@ static bool install_route(private_kernel_pfkey_ipsec_t *this, /* if we don't route via outbound interface and the remote traffic selector * covers the IKE peer, add an exclude route */ if (!streq(route->if_name, out_interface) && - charon->kernel->get_features(charon->kernel) & KERNEL_REQUIRE_EXCLUDE_ROUTE) + charon->kernel->get_features(charon->kernel, AF_INET) & KERNEL_REQUIRE_EXCLUDE_ROUTE) { if (out->dst_ts->is_host(out->dst_ts, dst)) { diff --git a/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c b/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c index df533810c..b5c2cb25e 100644 --- a/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c +++ b/src/libcharon/plugins/kernel_wfp/kernel_wfp_ipsec.c @@ -14,6 +14,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + /* Windows 7, for some fwpmu.h functionality */ #define _WIN32_WINNT 0x0601 @@ -816,6 +838,7 @@ static bool install_sps(private_kernel_wfp_ipsec_t *this, switch (sp->src->get_type(sp->src)) { case TS_IPV4_ADDR_RANGE: + case TS_FC_ADDR_RANGE: has_v4 = TRUE; break; case TS_IPV6_ADDR_RANGE: diff --git a/src/libcharon/plugins/load_tester/load_tester_config.c b/src/libcharon/plugins/load_tester/load_tester_config.c index 58e1cd98a..6fd2fd978 100644 --- a/src/libcharon/plugins/load_tester/load_tester_config.c +++ b/src/libcharon/plugins/load_tester/load_tester_config.c @@ -14,6 +14,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "load_tester_config.h" #include <netdb.h> @@ -748,7 +770,7 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, u_int num } else { - ike.local_port = charon->socket->get_port(charon->socket, FALSE); + ike.local_port = charon->socket->get_port(charon->socket, SOCKET_FAMILY_BOTH, FALSE); } ike_cfg = ike_cfg_create(&ike); ike_cfg->add_proposal(ike_cfg, this->proposal->clone(this->proposal, 0)); diff --git a/src/libcharon/plugins/medcli/medcli_config.c b/src/libcharon/plugins/medcli/medcli_config.c index f50f79d8b..90e482c99 100644 --- a/src/libcharon/plugins/medcli/medcli_config.c +++ b/src/libcharon/plugins/medcli/medcli_config.c @@ -14,6 +14,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #define _GNU_SOURCE #include <string.h> @@ -91,7 +113,7 @@ static peer_cfg_t *build_mediation_config(private_medcli_config_t *this, ike_cfg_create_t ike = { .version = IKEV2, .local = "0.0.0.0", - .local_port = charon->socket->get_port(charon->socket, FALSE), + .local_port = charon->socket->get_port(charon->socket, SOCKET_FAMILY_BOTH, FALSE), .remote_port = IKEV2_UDP_PORT, .no_certreq = TRUE, }; @@ -405,7 +427,7 @@ medcli_config_t *medcli_config_create(database_t *db) ike_cfg_create_t ike = { .version = IKEV2, .local = "0.0.0.0", - .local_port = charon->socket->get_port(charon->socket, FALSE), + .local_port = charon->socket->get_port(charon->socket, SOCKET_FAMILY_BOTH, FALSE), .remote = "0.0.0.0", .remote_port = IKEV2_UDP_PORT, .no_certreq = TRUE, diff --git a/src/libcharon/plugins/medsrv/medsrv_config.c b/src/libcharon/plugins/medsrv/medsrv_config.c index 4dd69f2d4..beac903b4 100644 --- a/src/libcharon/plugins/medsrv/medsrv_config.c +++ b/src/libcharon/plugins/medsrv/medsrv_config.c @@ -14,6 +14,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include <string.h> #include "medsrv_config.h" @@ -134,7 +156,7 @@ medsrv_config_t *medsrv_config_create(database_t *db) ike_cfg_create_t ike = { .version = IKEV2, .local = "0.0.0.0", - .local_port = charon->socket->get_port(charon->socket, FALSE), + .local_port = charon->socket->get_port(charon->socket, SOCKET_FAMILY_BOTH, FALSE), .remote = "0.0.0.0", .remote_port = IKEV2_UDP_PORT, .no_certreq = TRUE, diff --git a/src/libcharon/plugins/sql/sql_config.c b/src/libcharon/plugins/sql/sql_config.c index aef1e1c34..72d18bf1f 100644 --- a/src/libcharon/plugins/sql/sql_config.c +++ b/src/libcharon/plugins/sql/sql_config.c @@ -15,6 +15,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include <string.h> #include "sql_config.h" @@ -276,7 +298,7 @@ static ike_cfg_t *build_ike_cfg(private_sql_config_t *this, enumerator_t *e, ike_cfg_create_t ike = { .version = IKEV2, .local = local, - .local_port = charon->socket->get_port(charon->socket, FALSE), + .local_port = charon->socket->get_port(charon->socket, SOCKET_FAMILY_BOTH, FALSE), .remote = remote, .remote_port = IKEV2_UDP_PORT, .no_certreq = !certreq, diff --git a/src/libcharon/plugins/stroke/stroke_attribute.c b/src/libcharon/plugins/stroke/stroke_attribute.c index 0381beba1..6bed5d374 100644 --- a/src/libcharon/plugins/stroke/stroke_attribute.c +++ b/src/libcharon/plugins/stroke/stroke_attribute.c @@ -15,6 +15,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "stroke_attribute.h" #include <daemon.h> @@ -193,6 +215,7 @@ CALLBACK(attr_filter, bool, switch (host->get_family(host)) { case AF_INET: + case AF_NETLINK: *type = INTERNAL_IP4_DNS; break; case AF_INET6: diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c index 55db379ff..b7b11c536 100644 --- a/src/libcharon/plugins/stroke/stroke_config.c +++ b/src/libcharon/plugins/stroke/stroke_config.c @@ -15,6 +15,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "stroke_config.h" #include <daemon.h> @@ -65,6 +87,8 @@ METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*, private_stroke_config_t *this, identification_t *me, identification_t *other) { this->mutex->lock(this->mutex); + DBG1 (DBG_CFG, "stroke: %p: create peer_cfg enum: list: %p, list count: %d", + this, this->list, this->list->get_count (this->list)); return enumerator_create_cleaner(this->list->create_enumerator(this->list), (void*)this->mutex->unlock, this->mutex); } @@ -292,7 +316,7 @@ static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg } if (ike.local_port == IKEV2_UDP_PORT) { - ike.local_port = charon->socket->get_port(charon->socket, FALSE); + ike.local_port = charon->socket->get_port(charon->socket, SOCKET_FAMILY_BOTH, FALSE); } ike_cfg = ike_cfg_create(&ike); @@ -1179,7 +1203,7 @@ METHOD(stroke_config_t, add, void, else { /* add config to backend */ - DBG1(DBG_CFG, "added configuration '%s'", msg->add_conn.name); + DBG1(DBG_CFG, "stroke: %p: added configuration '%s', peer_cfg: %p, list: %p", this, msg->add_conn.name, peer_cfg, this->list); this->mutex->lock(this->mutex); this->list->insert_last(this->list, peer_cfg); this->mutex->unlock(this->mutex); diff --git a/src/libcharon/plugins/stroke/stroke_list.c b/src/libcharon/plugins/stroke/stroke_list.c index 4c9f75cf7..c36d1e1d2 100644 --- a/src/libcharon/plugins/stroke/stroke_list.c +++ b/src/libcharon/plugins/stroke/stroke_list.c @@ -15,6 +15,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "stroke_list.h" #include <inttypes.h> @@ -657,11 +679,14 @@ METHOD(stroke_list_t, status, void, half_open); enumerator = charon->controller->create_ike_sa_enumerator( charon->controller, wait); + int ike_num = 0, child_num = 0; while (enumerator->enumerate(enumerator, &ike_sa) && ferror(out) == 0) { bool ike_printed = FALSE; enumerator_t *children = ike_sa->create_child_sa_enumerator(ike_sa); + fprintf(out, "ike_sa %d\n--------\n", ike_num); + if (name == NULL || streq(name, ike_sa->get_name(ike_sa))) { log_ike_sa(out, ike_sa, all); @@ -669,8 +694,10 @@ METHOD(stroke_list_t, status, void, ike_printed = TRUE; } + child_num = 0; while (children->enumerate(children, (void**)&child_sa)) { + fprintf(out, "\nchild_sa %d-%d\n------------\n", ike_num, child_num++); if (name == NULL || streq(name, child_sa->get_name(child_sa))) { if (!ike_printed) @@ -680,9 +707,12 @@ METHOD(stroke_list_t, status, void, ike_printed = TRUE; } log_child_sa(out, child_sa, all); + fprintf(out, "\n\n"); } } children->destroy(children); + + ike_num++; } enumerator->destroy(enumerator); diff --git a/src/libcharon/plugins/uci/uci_config.c b/src/libcharon/plugins/uci/uci_config.c index 3a7fc7a63..afbf644bf 100644 --- a/src/libcharon/plugins/uci/uci_config.c +++ b/src/libcharon/plugins/uci/uci_config.c @@ -16,6 +16,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #define _GNU_SOURCE #include <string.h> @@ -130,7 +152,7 @@ METHOD(enumerator_t, peer_enumerator_enumerate, bool, ike_cfg_create_t ike = { .version = IKEV2, .local = "0.0.0.0", - .local_port = charon->socket->get_port(charon->socket, FALSE), + .local_port = charon->socket->get_port(charon->socket, SOCKET_FAMILY_BOTH, FALSE), .remote = "0.0.0.0", .remote_port = IKEV2_UDP_PORT, .no_certreq = TRUE, @@ -255,7 +277,7 @@ METHOD(enumerator_t, ike_enumerator_enumerate, bool, ike_cfg_create_t ike = { .version = IKEV2, .local = "0.0.0.0", - .local_port = charon->socket->get_port(charon->socket, FALSE), + .local_port = charon->socket->get_port(charon->socket, SOCKET_FAMILY_BOTH, FALSE), .remote = "0.0.0.0", .remote_port = IKEV2_UDP_PORT, .no_certreq = TRUE, diff --git a/src/libcharon/plugins/vici/vici_attribute.c b/src/libcharon/plugins/vici/vici_attribute.c index 97fe5d2a4..88c632db3 100644 --- a/src/libcharon/plugins/vici/vici_attribute.c +++ b/src/libcharon/plugins/vici/vici_attribute.c @@ -15,6 +15,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "vici_attribute.h" #include "vici_builder.h" @@ -466,6 +488,7 @@ CALLBACK(pool_li, bool, switch (host->get_family(host)) { case AF_INET: + case AF_NETLINK: type = keys[index].v4; break; case AF_INET6: @@ -480,7 +503,7 @@ CALLBACK(pool_li, bool, } else { - if (host->get_family(host) == AF_INET) + if (host->get_family(host) == AF_INET || host->get_family(host) == AF_NETLINK) { /* IPv4 attributes contain a subnet mask */ uint32_t netmask = 0; diff --git a/src/libcharon/plugins/vici/vici_config.c b/src/libcharon/plugins/vici/vici_config.c index ab382eca5..f778310bf 100644 --- a/src/libcharon/plugins/vici/vici_config.c +++ b/src/libcharon/plugins/vici/vici_config.c @@ -38,6 +38,28 @@ * THE SOFTWARE. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #define _GNU_SOURCE #include "vici_config.h" @@ -761,7 +783,7 @@ CALLBACK(parse_ts, bool, if (host_create_from_range(buf, &lower, &upper)) { - type = (lower->get_family(lower) == AF_INET) ? + type = (lower->get_family(lower) == AF_INET || lower->get_family(lower) == AF_NETLINK) ? TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE; ts = traffic_selector_create_from_bytes(proto, type, lower->get_address(lower), from, @@ -1710,7 +1732,18 @@ CALLBACK(parse_hosts, bool, { return FALSE; } - host = host_create_from_string(buf, 0); + + if (strstr (buf, "-fcsp")) + { + buf[strlen(buf) - 5] = '\0'; + host = host_create_from_string_fc(buf, 0); + DBG1 (DBG_CFG, "Found FC host: %p", host); + } + else + { + host = host_create_from_string(buf, 0); + } + if (!host) { return FALSE; @@ -2527,7 +2560,7 @@ CALLBACK(config_sn, bool, } if (!peer.local_port) { - peer.local_port = charon->socket->get_port(charon->socket, FALSE); + peer.local_port = charon->socket->get_port(charon->socket, SOCKET_FAMILY_BOTH, FALSE); } if (peer.rekey_time == LFT_UNDEFINED && peer.reauth_time == LFT_UNDEFINED) diff --git a/src/libcharon/plugins/vici/vici_control.c b/src/libcharon/plugins/vici/vici_control.c index 7b8ff1215..67d929989 100644 --- a/src/libcharon/plugins/vici/vici_control.c +++ b/src/libcharon/plugins/vici/vici_control.c @@ -15,6 +15,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "vici_control.h" #include "vici_builder.h" @@ -479,7 +501,7 @@ static traffic_selector_t *parse_peer_ip(char *ip) if (host_create_from_range(ip, &from, &to)) { - if (to->get_family(to) == AF_INET) + if (to->get_family(to) == AF_INET || to->get_family(to) == AF_NETLINK) { type = TS_IPV4_ADDR_RANGE; } diff --git a/src/libcharon/processing/jobs/migrate_job.c b/src/libcharon/processing/jobs/migrate_job.c index 8cc43a099..2f8ac535a 100644 --- a/src/libcharon/processing/jobs/migrate_job.c +++ b/src/libcharon/processing/jobs/migrate_job.c @@ -14,6 +14,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "migrate_job.h" #include <daemon.h> @@ -104,7 +126,7 @@ METHOD(job_t, execute, job_requeue_t, ike_sa->set_kmaddress(ike_sa, this->local, this->remote); host = this->local->clone(this->local); - host->set_port(host, charon->socket->get_port(charon->socket, FALSE)); + host->set_port(host, charon->socket->get_port(charon->socket, SOCKET_FAMILY_BOTH, FALSE)); ike_sa->set_my_host(ike_sa, host); host = this->remote->clone(this->remote); diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c index 2c77ee2c6..253822326 100644 --- a/src/libcharon/sa/child_sa.c +++ b/src/libcharon/sa/child_sa.c @@ -18,6 +18,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #define _GNU_SOURCE #include "child_sa.h" @@ -702,6 +724,7 @@ static bool update_usetime(private_child_sa_t *this, bool inbound) .label = label_for(this, LABEL_USE_POLICY), }; kernel_ipsec_query_policy_t query = {}; + query.family = this->my_addr->get_family (this->my_addr); if (charon->kernel->query_policy(charon->kernel, &id, &query, &in) == SUCCESS) @@ -729,7 +752,8 @@ static bool update_usetime(private_child_sa_t *this, bool inbound) .interface = this->config->get_interface(this->config), .label = label_for(this, LABEL_USE_POLICY), }; - kernel_ipsec_query_policy_t query = {}; + kernel_ipsec_query_policy_t query; + query.family = this->my_addr->get_family (this->my_addr); if (charon->kernel->query_policy(charon->kernel, &id, &query, &out) == SUCCESS) @@ -811,6 +835,12 @@ METHOD(child_sa_t, get_lifetime, time_t, return hard ? this->expire_time : this->rekey_time; } +METHOD(child_sa_t, set_rekey_time, void, + private_child_sa_t *this, time_t rekey_time) +{ + this->rekey_time = rekey_time; +} + METHOD(child_sa_t, get_installtime, time_t, private_child_sa_t *this) { @@ -1025,7 +1055,7 @@ static bool require_policy_update() { kernel_feature_t f; - f = charon->kernel->get_features(charon->kernel); + f = charon->kernel->get_features(charon->kernel, AF_INET); return !(f & KERNEL_NO_POLICY_UPDATES); } @@ -1412,7 +1442,8 @@ METHOD(child_sa_t, install_policies, status_t, */ static bool install_outbound_immediately(private_child_sa_t *this) { - if (charon->kernel->get_features(charon->kernel) & KERNEL_POLICY_SPI) + int family = this->my_addr->get_family (this->my_addr); + if (charon->kernel->get_features(charon->kernel, family) & KERNEL_POLICY_SPI) { if (this->config->get_label_mode(this->config) == SEC_LABEL_MODE_SELINUX) { @@ -2028,6 +2059,7 @@ child_sa_t *child_sa_create(host_t *me, host_t *other, child_cfg_t *config, .get_proposal = _get_proposal, .set_proposal = _set_proposal, .get_lifetime = _get_lifetime, + .set_rekey_time = _set_rekey_time, .get_installtime = _get_installtime, .get_usestats = _get_usestats, .get_mark = _get_mark, diff --git a/src/libcharon/sa/child_sa.h b/src/libcharon/sa/child_sa.h index 37f00277e..79c7b78f7 100644 --- a/src/libcharon/sa/child_sa.h +++ b/src/libcharon/sa/child_sa.h @@ -16,6 +16,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + /** * @defgroup child_sa child_sa * @{ @ingroup sa @@ -335,6 +357,16 @@ struct child_sa_t { */ time_t (*get_lifetime)(child_sa_t *this, bool hard); + /** + * Set the absolute time when the CHILD_SA gets rekeyed. + * Note: since the rekeying is actually controlled in the kernel, + * this api is here to report what is expected, not to actually affect the rekey action. + * + * @param rekey_time absolute time when rekey should happen. + * @return void + */ + void (*set_rekey_time)(child_sa_t *this, time_t rekey_time); + /** * Get the absolute time when this SA has been installed. * diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c index 0d554204d..47fb037c4 100644 --- a/src/libcharon/sa/ike_sa.c +++ b/src/libcharon/sa/ike_sa.c @@ -39,6 +39,28 @@ * THE SOFTWARE. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include <string.h> #include <sys/stat.h> #include <errno.h> @@ -1131,10 +1153,10 @@ METHOD(ike_sa_t, float_ports, void, this->other_host->set_port(this->other_host, IKEV2_NATT_PORT); } if (this->my_host->get_port(this->my_host) == - charon->socket->get_port(charon->socket, FALSE)) + charon->socket->get_port(charon->socket, SOCKET_FAMILY_BOTH, FALSE)) { this->my_host->set_port(this->my_host, - charon->socket->get_port(charon->socket, TRUE)); + charon->socket->get_port(charon->socket, SOCKET_FAMILY_BOTH, TRUE)); } } @@ -1447,6 +1469,7 @@ static void resolve_hosts(private_ike_sa_t *this) switch (charon->socket->supported_families(charon->socket)) { case SOCKET_FAMILY_IPV4: + case SOCKET_FAMILY_FC: family = AF_INET; break; case SOCKET_FAMILY_IPV6: @@ -1498,7 +1521,7 @@ static void resolve_hosts(private_ike_sa_t *this) if (this->local_host) { host = this->local_host->clone(this->local_host); - host->set_port(host, charon->socket->get_port(charon->socket, FALSE)); + host->set_port(host, charon->socket->get_port(charon->socket, host->get_family (host), FALSE)); } else { @@ -2652,6 +2675,7 @@ static bool is_any_path_valid(private_ike_sa_t *this) switch (charon->socket->supported_families(charon->socket)) { case SOCKET_FAMILY_IPV4: + case SOCKET_FAMILY_FC: family = AF_INET; break; case SOCKET_FAMILY_IPV6: @@ -3106,8 +3130,8 @@ METHOD(ike_sa_t, destroy, void, /* * Described in header. */ -ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator, - ike_version_t version) +ike_sa_t * ike_sa_create_with_family(ike_sa_id_t *ike_sa_id, bool initiator, + ike_version_t version, int family) { private_ike_sa_t *this; static refcount_t unique_id = 0; @@ -3219,8 +3243,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator, }, .ike_sa_id = ike_sa_id->clone(ike_sa_id), .version = version, - .my_host = host_create_any(AF_INET), - .other_host = host_create_any(AF_INET), + .my_host = host_create_any(family), + .other_host = host_create_any(family), .my_id = identification_create_from_encoding(ID_ANY, chunk_empty), .other_id = identification_create_from_encoding(ID_ANY, chunk_empty), .keymat = keymat_create(version, initiator), @@ -3254,7 +3278,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator, this->task_manager = task_manager_create(&this->public); this->my_host->set_port(this->my_host, - charon->socket->get_port(charon->socket, FALSE)); + charon->socket->get_port(charon->socket, this->my_host->get_family (this->my_host), FALSE)); if (!this->task_manager || !this->keymat) { @@ -3265,6 +3289,15 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator, return &this->public; } +/* + * Described in header. + */ +ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator, + ike_version_t version) +{ + return ike_sa_create_with_family (ike_sa_id, initiator, version, AF_INET); +} + /** * Check if we have a an address pool configured. */ diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h index 58b1f9f3d..ebcd3738a 100644 --- a/src/libcharon/sa/ike_sa.h +++ b/src/libcharon/sa/ike_sa.h @@ -17,6 +17,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + /** * @defgroup ike_sa ike_sa * @{ @ingroup sa @@ -1256,6 +1278,9 @@ struct ike_sa_t { ike_sa_t *ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator, ike_version_t version); +ike_sa_t * ike_sa_create_with_family(ike_sa_id_t *ike_sa_id, bool initiator, + ike_version_t version, int family); + /** * Check if the given IKE_SA can be reauthenticated actively or if config * parameters or the authentication method prevent it. diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c index e860784de..f7a6f3023 100644 --- a/src/libcharon/sa/ike_sa_manager.c +++ b/src/libcharon/sa/ike_sa_manager.c @@ -16,6 +16,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include <string.h> #include <inttypes.h> @@ -1238,8 +1260,8 @@ METHOD(ike_sa_manager_t, checkout, ike_sa_t*, return ike_sa; } -METHOD(ike_sa_manager_t, create_new, ike_sa_t*, - private_ike_sa_manager_t* this, ike_version_t version, bool initiator) +METHOD(ike_sa_manager_t, create_new_with_family, ike_sa_t*, + private_ike_sa_manager_t* this, ike_version_t version, bool initiator, int family) { ike_sa_id_t *ike_sa_id; ike_sa_t *ike_sa; @@ -1263,7 +1285,7 @@ METHOD(ike_sa_manager_t, create_new, ike_sa_t*, { ike_sa_id = ike_sa_id_create(ike_version, 0, spi, FALSE); } - ike_sa = ike_sa_create(ike_sa_id, initiator, version); + ike_sa = ike_sa_create_with_family(ike_sa_id, initiator, version, family); ike_sa_id->destroy(ike_sa_id); if (ike_sa) @@ -1274,6 +1296,12 @@ METHOD(ike_sa_manager_t, create_new, ike_sa_t*, return ike_sa; } +METHOD(ike_sa_manager_t, create_new, ike_sa_t*, + private_ike_sa_manager_t* this, ike_version_t version, bool initiator) +{ + return create_new_with_family (this, version, initiator, AF_INET); +} + METHOD(ike_sa_manager_t, checkout_new, void, private_ike_sa_manager_t *this, ike_sa_t *ike_sa) { @@ -1303,8 +1331,8 @@ static uint32_t get_message_id_or_hash(message_t *message) return message->get_message_id(message); } -METHOD(ike_sa_manager_t, checkout_by_message, ike_sa_t*, - private_ike_sa_manager_t* this, message_t *message) +METHOD(ike_sa_manager_t, checkout_by_message_with_family, ike_sa_t*, + private_ike_sa_manager_t* this, message_t *message, int family) { u_int segment; entry_t *entry; @@ -1376,7 +1404,7 @@ METHOD(ike_sa_manager_t, checkout_by_message, ike_sa_t*, this->public.get_count(&this->public) < this->ikesa_limit) { id->set_responder_spi(id, our_spi); - ike_sa = ike_sa_create(id, FALSE, ike_version); + ike_sa = ike_sa_create_with_family(id, FALSE, ike_version, family); if (ike_sa) { entry = entry_create(); @@ -1493,6 +1521,12 @@ typedef struct { bool working; } config_entry_t; +METHOD(ike_sa_manager_t, checkout_by_message, ike_sa_t*, + private_ike_sa_manager_t* this, message_t *message) +{ + return checkout_by_message_with_family (this, message, AF_INET); +} + METHOD(ike_sa_manager_t, checkout_by_config, ike_sa_t*, private_ike_sa_manager_t *this, peer_cfg_t *peer_cfg) { @@ -2506,7 +2540,9 @@ ike_sa_manager_t *ike_sa_manager_create() .create_new = _create_new, .checkout_new = _checkout_new, .checkout = _checkout, + .create_new_with_family = _create_new_with_family, .checkout_by_message = _checkout_by_message, + .checkout_by_message_with_family = _checkout_by_message_with_family, .checkout_by_config = _checkout_by_config, .checkout_by_id = _checkout_by_id, .checkout_by_name = _checkout_by_name, diff --git a/src/libcharon/sa/ike_sa_manager.h b/src/libcharon/sa/ike_sa_manager.h index 004cc2216..5361765e7 100644 --- a/src/libcharon/sa/ike_sa_manager.h +++ b/src/libcharon/sa/ike_sa_manager.h @@ -16,6 +16,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + /** * @defgroup ike_sa_manager ike_sa_manager * @{ @ingroup sa @@ -86,6 +108,18 @@ struct ike_sa_manager_t { */ ike_sa_t* (*checkout) (ike_sa_manager_t* this, ike_sa_id_t *sa_id); + /** + * Create and check out a new IKE_SA. + * + * @param version IKE version of this SA + * @param initiator TRUE for initiator, FALSE otherwise + * @param family Address family (AF_xx) + * @returns created and checked out IKE_SA + */ + ike_sa_t* (*create_new_with_family) (ike_sa_manager_t* this, ike_version_t version, + bool initiator, int family); + + /** * Track an initial IKE message as responder by increasing the number of * half-open IKE_SAs. @@ -122,6 +156,8 @@ struct ike_sa_manager_t { */ ike_sa_t* (*checkout_by_message) (ike_sa_manager_t* this, message_t *message); + ike_sa_t* (*checkout_by_message_with_family) (ike_sa_manager_t* this, message_t *message, int family); + /** * Checkout an IKE_SA for initiation by a peer_config. * diff --git a/src/libcharon/sa/ikev1/tasks/informational.c b/src/libcharon/sa/ikev1/tasks/informational.c index f89770753..b507a3a4a 100644 --- a/src/libcharon/sa/ikev1/tasks/informational.c +++ b/src/libcharon/sa/ikev1/tasks/informational.c @@ -14,6 +14,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "informational.h" #include <daemon.h> @@ -118,7 +140,7 @@ METHOD(task_t, process_r, status_t, /* Cisco boxes reject the first message from 4500 */ me = this->ike_sa->get_my_host(this->ike_sa); me->set_port(me, charon->socket->get_port( - charon->socket, FALSE)); + charon->socket, SOCKET_FAMILY_BOTH, FALSE)); this->ike_sa->set_other_host(this->ike_sa, redirect); status = this->ike_sa->reauth(this->ike_sa); enumerator->destroy(enumerator); diff --git a/src/libcharon/sa/ikev1/tasks/isakmp_natd.c b/src/libcharon/sa/ikev1/tasks/isakmp_natd.c index 01bfabf95..a00d20281 100644 --- a/src/libcharon/sa/ikev1/tasks/isakmp_natd.c +++ b/src/libcharon/sa/ikev1/tasks/isakmp_natd.c @@ -38,6 +38,28 @@ * THE SOFTWARE. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "isakmp_natd.h" #include <string.h> @@ -104,7 +126,7 @@ static bool force_encap(ike_cfg_t *ike_cfg) { if (!ike_cfg->force_encap(ike_cfg)) { - return charon->kernel->get_features(charon->kernel) & + return charon->kernel->get_features(charon->kernel, AF_INET) & KERNEL_REQUIRE_UDP_ENCAPSULATION; } return TRUE; diff --git a/src/libcharon/sa/ikev2/task_manager_v2.c b/src/libcharon/sa/ikev2/task_manager_v2.c index f1228ab07..bf5fdf469 100644 --- a/src/libcharon/sa/ikev2/task_manager_v2.c +++ b/src/libcharon/sa/ikev2/task_manager_v2.c @@ -15,6 +15,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "task_manager_v2.h" #include <math.h> @@ -2365,13 +2387,13 @@ METHOD(task_manager_t, queue_child, void, if (args) { - task = child_create_create(this->ike_sa, cfg, FALSE, args->src, args->dst); + task = child_create_create(this->ike_sa, cfg->get_ref(cfg), FALSE, args->src, args->dst); task->use_reqid(task, args->reqid); task->use_label(task, args->label); } else { - task = child_create_create(this->ike_sa, cfg, FALSE, NULL, NULL); + task = child_create_create(this->ike_sa, cfg->get_ref(cfg), FALSE, NULL, NULL); } queue_task(this, &task->task); } diff --git a/src/libcharon/sa/ikev2/tasks/child_create.c b/src/libcharon/sa/ikev2/tasks/child_create.c index 1c0d7cc77..cdf59911f 100644 --- a/src/libcharon/sa/ikev2/tasks/child_create.c +++ b/src/libcharon/sa/ikev2/tasks/child_create.c @@ -16,6 +16,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "child_create.h" #include <daemon.h> @@ -869,7 +891,10 @@ static bool build_payloads(private_child_create_t *this, message_t *message) break; } - features = charon->kernel->get_features(charon->kernel); + host_t *my_host = this->ike_sa->get_my_host (this->ike_sa); + int family = my_host->get_family (my_host); + + features = charon->kernel->get_features(charon->kernel, family); if (!(features & KERNEL_ESP_V3_TFC)) { message->add_notify(message, FALSE, ESP_TFC_PADDING_NOT_SUPPORTED, diff --git a/src/libcharon/sa/ikev2/tasks/ike_mobike.c b/src/libcharon/sa/ikev2/tasks/ike_mobike.c index 5cfc72d78..bc82d3ce3 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_mobike.c +++ b/src/libcharon/sa/ikev2/tasks/ike_mobike.c @@ -15,6 +15,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "ike_mobike.h" #include <string.h> @@ -279,9 +301,9 @@ static void apply_port(host_t *host, host_t *old, uint16_t port, bool local) { port = old->get_port(old); } - else if (local && port == charon->socket->get_port(charon->socket, FALSE)) + else if (local && port == charon->socket->get_port(charon->socket, SOCKET_FAMILY_BOTH, FALSE)) { - port = charon->socket->get_port(charon->socket, TRUE); + port = charon->socket->get_port(charon->socket, SOCKET_FAMILY_BOTH, TRUE); } else if (!local && port == IKEV2_UDP_PORT) { @@ -327,6 +349,7 @@ METHOD(ike_mobike_t, transmit, bool, switch (charon->socket->supported_families(charon->socket)) { case SOCKET_FAMILY_IPV4: + case SOCKET_FAMILY_FC: family = AF_INET; break; case SOCKET_FAMILY_IPV6: diff --git a/src/libcharon/sa/ikev2/tasks/ike_natd.c b/src/libcharon/sa/ikev2/tasks/ike_natd.c index 72d057e62..8f43a73bc 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_natd.c +++ b/src/libcharon/sa/ikev2/tasks/ike_natd.c @@ -15,6 +15,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "ike_natd.h" #include <string.h> @@ -91,7 +113,7 @@ static bool force_encap(ike_cfg_t *ike_cfg) { if (!ike_cfg->force_encap(ike_cfg)) { - return charon->kernel->get_features(charon->kernel) & + return charon->kernel->get_features(charon->kernel, AF_INET) & KERNEL_REQUIRE_UDP_ENCAPSULATION; } return TRUE; @@ -108,6 +130,18 @@ static chunk_t generate_natd_hash(private_ike_natd_t *this, uint64_t spi_i, spi_r; uint16_t port; + // For FC, the port is not a valid comparison point because that port + // is not used to make the address tuple. It is only used as a local host identifier. + socket_family_t family = charon->socket->supported_families(charon->socket); + if (family != SOCKET_FAMILY_FC) + { + port = htons(host->get_port(host)); + } + else + { + port = 0; + } + /* prepare all required chunks */ spi_i = ike_sa_id->get_initiator_spi(ike_sa_id); spi_r = ike_sa_id->get_responder_spi(ike_sa_id); @@ -115,7 +149,6 @@ static chunk_t generate_natd_hash(private_ike_natd_t *this, spi_i_chunk.len = sizeof(spi_i); spi_r_chunk.ptr = (void*)&spi_r; spi_r_chunk.len = sizeof(spi_r); - port = htons(host->get_port(host)); port_chunk.ptr = (void*)&port; port_chunk.len = sizeof(port); addr_chunk = host->get_address(host); diff --git a/src/libstrongswan/networking/host.c b/src/libstrongswan/networking/host.c index f2768dc10..386bfdde3 100644 --- a/src/libstrongswan/networking/host.c +++ b/src/libstrongswan/networking/host.c @@ -17,6 +17,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "host.h" #include <utils/debug.h> @@ -85,6 +107,7 @@ METHOD(host_t, is_anyaddr, bool, switch (this->address.sa_family) { case AF_INET: + case AF_NETLINK: { return memeq(zeroes, &(this->address4.sin_addr.s_addr), IPV4_LEN); } @@ -122,19 +145,23 @@ int host_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, void *address; uint16_t port; int len; + int family; address = &this->address6.sin6_addr; port = this->address6.sin6_port; + family = this->address.sa_family; switch (this->address.sa_family) { case AF_INET: + case AF_NETLINK: address = &this->address4.sin_addr; port = this->address4.sin_port; + family = AF_INET; // inet_ntop does not recognize AF_NETLINK /* fall */ case AF_INET6: - if (inet_ntop(this->address.sa_family, address, + if (inet_ntop(family, address, buffer, sizeof(buffer)) == NULL) { snprintf(buffer, sizeof(buffer), @@ -167,6 +194,7 @@ METHOD(host_t, get_address, chunk_t, switch (this->address.sa_family) { case AF_INET: + case AF_NETLINK: { address.ptr = (char*)&(this->address4.sin_addr.s_addr); address.len = IPV4_LEN; @@ -198,6 +226,7 @@ METHOD(host_t, get_port, uint16_t, switch (this->address.sa_family) { case AF_INET: + case AF_NETLINK: { return ntohs(this->address4.sin_port); } @@ -218,6 +247,7 @@ METHOD(host_t, set_port, void, switch (this->address.sa_family) { case AF_INET: + case AF_NETLINK: { this->address4.sin_port = htons(port); break; @@ -259,6 +289,7 @@ static bool ip_equals(private_host_t *this, private_host_t *other) switch (this->address.sa_family) { case AF_INET: + case AF_NETLINK: { return memeq(&this->address4.sin_addr, &other->address4.sin_addr, sizeof(this->address4.sin_addr)); @@ -287,6 +318,7 @@ static bool equals(private_host_t *this, private_host_t *other) switch (this->address.sa_family) { case AF_INET: + case AF_NETLINK: { return (this->address4.sin_port == other->address4.sin_port); } @@ -395,6 +427,7 @@ host_t *host_create_from_string_and_family(char *string, int family, addr.v6.sin6_family = AF_INET6; return host_create_from_sockaddr((sockaddr_t*)&addr); case AF_INET: + case AF_NETLINK: if (strchr(string, ':')) { /* do not try to convert v6 addresses for v4 family */ return NULL; @@ -406,7 +439,7 @@ host_t *host_create_from_string_and_family(char *string, int family, return NULL; } addr.v4.sin_port = htons(port); - addr.v4.sin_family = AF_INET; + addr.v4.sin_family = family == AF_NETLINK ? AF_NETLINK : AF_INET; return host_create_from_sockaddr((sockaddr_t*)&addr); default: return NULL; @@ -421,6 +454,11 @@ host_t *host_create_from_string(char *string, uint16_t port) return host_create_from_string_and_family(string, AF_UNSPEC, port); } +host_t *host_create_from_string_fc(char *string, uint16_t port) +{ + return host_create_from_string_and_family(string, AF_NETLINK, port); +} + /* * Described in header. */ @@ -431,6 +469,7 @@ host_t *host_create_from_sockaddr(sockaddr_t *sockaddr) switch (sockaddr->sa_family) { case AF_INET: + case AF_NETLINK: { memcpy(&this->address4, (struct sockaddr_in*)sockaddr, sizeof(struct sockaddr_in)); @@ -482,6 +521,7 @@ host_t *host_create_from_chunk(int family, chunk_t address, uint16_t port) switch (family) { case AF_INET: + case AF_NETLINK: if (address.len < IPV4_LEN) { return NULL; @@ -516,6 +556,7 @@ host_t *host_create_from_chunk(int family, chunk_t address, uint16_t port) switch (family) { case AF_INET: + case AF_NETLINK: memcpy(&this->address4.sin_addr.s_addr, address.ptr, address.len); this->address4.sin_port = htons(port); this->socklen = sizeof(struct sockaddr_in); @@ -665,6 +706,7 @@ host_t *host_create_any(int family) switch (family) { case AF_INET: + case AF_NETLINK: { this->socklen = sizeof(struct sockaddr_in); update_sa_len(this); diff --git a/src/libstrongswan/networking/host.h b/src/libstrongswan/networking/host.h index 6abd93743..a129ddc67 100644 --- a/src/libstrongswan/networking/host.h +++ b/src/libstrongswan/networking/host.h @@ -17,6 +17,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + /** * @defgroup host host * @{ @ingroup networking @@ -140,6 +162,15 @@ struct host_t { */ host_t *host_create_from_string(char *string, uint16_t port); +/** + * Constructor to create a host_t object from an address string and set family to AF_NETLINK. + * + * @param string string of an address, such as "152.96.193.130" + * @param port port number + * @return host_t, NULL if string not an address. + */ +host_t *host_create_from_string_fc(char *string, uint16_t port); + /** * Same as host_create_from_string(), but with the option to enforce a family. * diff --git a/src/libstrongswan/selectors/traffic_selector.c b/src/libstrongswan/selectors/traffic_selector.c index fe61e3768..6dbcc15e2 100644 --- a/src/libstrongswan/selectors/traffic_selector.c +++ b/src/libstrongswan/selectors/traffic_selector.c @@ -16,6 +16,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include <string.h> #include <stdio.h> @@ -28,14 +50,15 @@ #define IPV4_LEN 4 #define IPV6_LEN 16 -#define TS_IP_LEN(this) ({ ((this)->type == TS_IPV4_ADDR_RANGE) ? IPV4_LEN : IPV6_LEN; }) +#define PORTID_LEN 3 +#define TS_IP_LEN(this) ({ (((this)->type == TS_IPV4_ADDR_RANGE) ? IPV4_LEN : (((this)->type == TS_FC_ADDR_RANGE) ? PORTID_LEN: IPV6_LEN) ); }) #define NON_SUBNET_ADDRESS_RANGE 255 -ENUM_BEGIN(ts_type_name, TS_IPV4_ADDR_RANGE, TS_IPV6_ADDR_RANGE, +ENUM_BEGIN(ts_type_name, TS_IPV4_ADDR_RANGE, TS_SECLABEL, "TS_IPV4_ADDR_RANGE", - "TS_IPV6_ADDR_RANGE"); -ENUM_NEXT(ts_type_name, TS_SECLABEL, TS_SECLABEL, TS_IPV6_ADDR_RANGE, + "TS_IPV6_ADDR_RANGE", + "TS_FC_ADDR_RANGE", "TS_SECLABEL"); ENUM_END(ts_type_name, TS_SECLABEL); @@ -241,7 +264,7 @@ int traffic_selector_printf_hook(printf_hook_data_t *data, len = TS_IP_LEN(this); memset(from, 0, len); memset(to, 0xFF, len); - if (this->dynamic && + if (this->dynamic && (this->type != TS_FC_ADDR_RANGE) && memeq(this->from, from, len) && memeq(this->to, to, len)) { written += print_in_hook(data, "dynamic"); @@ -252,6 +275,11 @@ int traffic_selector_printf_hook(printf_hook_data_t *data, { inet_ntop(AF_INET, &this->from, from_str, sizeof(from_str)); } + else if (this->type == TS_FC_ADDR_RANGE) + { + written += print_in_hook(data, "%x%x%x..%x%x%x", this->from[0], this->from[1], this->from[2], + this->to[0], this->to[1], this->to[2]); + } else { inet_ntop(AF_INET6, &this->from, from_str, sizeof(from_str)); @@ -319,6 +347,12 @@ int traffic_selector_printf_hook(printf_hook_data_t *data, { written += print_icmp(data, this->from_port); } + else if (this->type == TS_FC_ADDR_RANGE) + { + written += print_in_hook(data, "%d-%d", + this->from_port, this->to_port); + + } else { serv = getservbyport(htons(this->from_port), serv_proto); @@ -486,7 +520,8 @@ METHOD(traffic_selector_t, is_host, bool, int family = host->get_family(host); if ((family == AF_INET && this->type == TS_IPV4_ADDR_RANGE) || - (family == AF_INET6 && this->type == TS_IPV6_ADDR_RANGE)) + (family == AF_INET6 && this->type == TS_IPV6_ADDR_RANGE) || + (family == AF_NETLINK && this->type == TS_IPV6_ADDR_RANGE)) { addr = host->get_address(host); if (memeq(addr.ptr, this->from, addr.len) && @@ -522,8 +557,11 @@ METHOD(traffic_selector_t, is_dynamic, bool, METHOD(traffic_selector_t, set_address, void, private_traffic_selector_t *this, host_t *host) { - this->type = host->get_family(host) == AF_INET ? TS_IPV4_ADDR_RANGE + if (this->type != TS_FC_ADDR_RANGE) + { + this->type = host->get_family(host) == AF_INET ? TS_IPV4_ADDR_RANGE : TS_IPV6_ADDR_RANGE; + } if (host->is_anyaddr(host)) { @@ -536,8 +574,11 @@ METHOD(traffic_selector_t, set_address, void, chunk_t from = host->get_address(host); memcpy(this->from, from.ptr, from.len); memcpy(this->to, from.ptr, from.len); + if (this->type != TS_FC_ADDR_RANGE) + { this->netbits = from.len * 8; } + } this->dynamic = FALSE; } @@ -547,6 +588,15 @@ METHOD(traffic_selector_t, is_contained_in, bool, private_traffic_selector_t *subset; bool contained_in = FALSE; + if (this->type == TS_FC_ADDR_RANGE) + { + if (equals(this, other)) + { + contained_in = TRUE; + } + return contained_in; + } + subset = (private_traffic_selector_t*)get_subset(this, other); if (subset) @@ -565,6 +615,7 @@ METHOD(traffic_selector_t, includes, bool, { chunk_t addr; int family = host->get_family(host); + uint16_t port_index = 0; if ((family == AF_INET && this->type == TS_IPV4_ADDR_RANGE) || (family == AF_INET6 && this->type == TS_IPV6_ADDR_RANGE)) @@ -575,6 +626,13 @@ METHOD(traffic_selector_t, includes, bool, memcmp(this->to, addr.ptr, addr.len) >= 0; } + if (this->type == TS_FC_ADDR_RANGE) + { + port_index = host->get_port(host); + + return ((this->from_port == port_index) || (this->to_port == port_index)); + } + return FALSE; } @@ -889,7 +947,7 @@ static private_traffic_selector_t *traffic_selector_create(uint8_t protocol, private_traffic_selector_t *this; /* sanity check */ - if (type != TS_IPV4_ADDR_RANGE && type != TS_IPV6_ADDR_RANGE) + if (type != TS_IPV4_ADDR_RANGE && type != TS_IPV6_ADDR_RANGE && type != TS_FC_ADDR_RANGE) { return NULL; } @@ -926,3 +984,19 @@ static private_traffic_selector_t *traffic_selector_create(uint8_t protocol, } return this; } + +traffic_selector_t *traffic_selector_create_from_fcsp2_format(chunk_t start_address, uint16_t start_port, + chunk_t end_address, uint16_t end_port) +{ + ts_type_t type = TS_FC_ADDR_RANGE; + private_traffic_selector_t *this = traffic_selector_create(IPPROTO_RAW, type, + start_port, end_port); + + memset(this->from, 0x0, start_address.len); + memcpy(this->from, start_address.ptr, start_address.len); + + memset(this->to, 0x0, end_address.len); + memcpy(this->to, end_address.ptr, end_address.len); + + return &this->public; +} diff --git a/src/libstrongswan/selectors/traffic_selector.h b/src/libstrongswan/selectors/traffic_selector.h index 367b4fff9..2197246e7 100644 --- a/src/libstrongswan/selectors/traffic_selector.h +++ b/src/libstrongswan/selectors/traffic_selector.h @@ -16,6 +16,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + /** * @defgroup traffic_selector traffic_selector * @{ @ingroup selectors @@ -53,6 +75,15 @@ enum ts_type_t { */ TS_IPV6_ADDR_RANGE = 8, + /** + * A range of FC addresses, represented by two three (3) + * octet values. The first value is the beginning FC address + * (inclusive) and the second value is the ending FC address + * (inclusive). All addresses falling between the two specified + * addresses are considered to be within the list. + */ + TS_FC_ADDR_RANGE = 9, + /** * A security label. */ @@ -422,4 +453,22 @@ traffic_selector_t *traffic_selector_create_dynamic(uint8_t protocol, int traffic_selector_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec, const void *const *args); +/** + * Create a new traffic selector using data read from the net. + * + * There exists a mix of network and host order in the params. + * But the parser gives us this data in fcsp format, so we + * don't have to convert twice. + * + * @param start_address start of address range, network order + * @param start_type starting type of following addresses + * @param end_address end of address range, network order + * @param end_rctl Ending R_CTL + * @param start_rctl Starting R_CTL + * @param end_type ending type of following address + * @return traffic_selector_t object + */ +traffic_selector_t *traffic_selector_create_from_fcsp2_format(chunk_t start_address, uint16_t start_port, + chunk_t end_address, uint16_t end_port); + #endif /** TRAFFIC_SELECTOR_H_ @}*/ diff --git a/src/libstrongswan/utils/identification.c b/src/libstrongswan/utils/identification.c index 6ddaf6c3e..3f9c27d93 100644 --- a/src/libstrongswan/utils/identification.c +++ b/src/libstrongswan/utils/identification.c @@ -17,6 +17,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include <string.h> #include <stdio.h> #include <errno.h> @@ -37,7 +59,7 @@ ENUM_NEXT(id_match_names, ID_MATCH_PERFECT, ID_MATCH_PERFECT, ID_MATCH_MAX_WILDC "MATCH_PERFECT"); ENUM_END(id_match_names, ID_MATCH_PERFECT); -ENUM_BEGIN(id_type_names, ID_ANY, ID_KEY_ID, +ENUM_BEGIN(id_type_names, ID_ANY, ID_KEY_Q_NAME, "ID_ANY", "ID_IPV4_ADDR", "ID_FQDN", @@ -49,8 +71,9 @@ ENUM_BEGIN(id_type_names, ID_ANY, ID_KEY_ID, "ID_IPV6_ADDR_RANGE", "ID_DER_ASN1_DN", "ID_DER_ASN1_GN", - "ID_KEY_ID"); -ENUM_NEXT(id_type_names, ID_DER_ASN1_GN_URI, ID_DER_ASN1_GN_URI, ID_KEY_ID, + "ID_KEY_ID", + "ID_KEY_Q_NAME"); +ENUM_NEXT(id_type_names, ID_DER_ASN1_GN_URI, ID_DER_ASN1_GN_URI, ID_KEY_Q_NAME, "ID_DER_ASN1_GN_URI"); ENUM_END(id_type_names, ID_DER_ASN1_GN_URI); @@ -1306,6 +1329,10 @@ int identification_printf_hook(printf_hook_data_t *data, case ID_DER_ASN1_GN: snprintf(buf, BUF_LEN, "(ASN.1 general name)"); break; + case ID_KEY_Q_NAME: + snprintf(buf, sizeof(buf), "%.*s", (int)this->encoded.len, + this->encoded.ptr); + break; case ID_KEY_ID: if (chunk_printable(this->encoded, NULL, '?') && this->encoded.len != HASH_SIZE_SHA1) @@ -1378,6 +1405,7 @@ static private_identification_t *identification_create(id_type_t type) break; case ID_FQDN: case ID_RFC822_ADDR: + case ID_KEY_Q_NAME: this->public.hash = _hash_binary; this->public.equals = _equals_strcasecmp; this->public.matches = _matches_string; @@ -1441,6 +1469,7 @@ static private_identification_t* create_from_string_with_prefix_type(char *str) { "asn1gn:", ID_DER_ASN1_GN }, { "xmppaddr:", ID_DER_ASN1_GN }, { "keyid:", ID_KEY_ID }, + { "0x", ID_KEY_Q_NAME }, }; private_identification_t *this; int i; diff --git a/src/libstrongswan/utils/identification.h b/src/libstrongswan/utils/identification.h index a85b7c538..ffdc08416 100644 --- a/src/libstrongswan/utils/identification.h +++ b/src/libstrongswan/utils/identification.h @@ -16,6 +16,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + /** * @defgroup identification identification * @{ @ingroup utils @@ -126,6 +148,12 @@ enum id_type_t { */ ID_KEY_ID = 11, + /** + * ID data is a qualifier name string. + * The string MUST NOT contain any terminators. + */ + ID_KEY_Q_NAME = 12, + /** * Private ID type which represents a GeneralName of type URI */ diff --git a/src/libstrongswan/utils/parser_helper.c b/src/libstrongswan/utils/parser_helper.c index 69800a781..f77a4fb56 100644 --- a/src/libstrongswan/utils/parser_helper.c +++ b/src/libstrongswan/utils/parser_helper.c @@ -14,6 +14,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include <limits.h> #include <ctype.h> #include <stdarg.h> @@ -24,6 +46,9 @@ #include <collections/array.h> +#include <stdlib.h> +#include <unistd.h> + typedef struct private_parser_helper_t private_parser_helper_t; typedef struct parser_helper_file_t parser_helper_file_t; @@ -92,6 +117,42 @@ static parser_helper_file_t *current_file(private_parser_helper_t *this) return NULL; } +#ifdef _WIN32 +static bool get_install_dir(char *install_dir) +{ + char path[PATH_MAX], *pos; + HMODULE module; + + module = GetModuleHandle(NULL); + if (!module) + { + return FALSE; + } + if (!GetModuleFileName(module, path, sizeof(path))) + { + return FALSE; + } + pos = strrchr(path, '\\'); + if (!pos) + { + return FALSE; + } + *pos = 0; + + pos = strstr(path, "\\usr\\"); + if (!pos) + { + return FALSE; + } + *pos = 0; + + memset(install_dir, 0, sizeof(install_dir)); + strcpy(install_dir, path); + + return TRUE; +} +#endif + METHOD(parser_helper_t, file_next, FILE*, private_parser_helper_t *this) { @@ -111,18 +172,48 @@ METHOD(parser_helper_t, file_next, FILE*, { while (file->matches->enumerate(file->matches, &name, NULL)) { + char fname[PATH_MAX] = { 0 }; + memcpy(fname, name, strlen(name)); + +#ifdef _WIN32 + int len = 0; + if (get_install_dir(fname)) + { + len = strlen(fname); + if(strstr(name, "/etc/strongswan.conf") != NULL) + { + strcpy((&fname[len]), name); + } + else + { + memset(fname, 0, PATH_MAX); + memcpy(fname, name, strlen(name)); + } + } + else + { + memset(fname, 0, PATH_MAX); + memcpy(fname, name, strlen(name)); + } + for (int i = 0; i < strlen(fname); i++) + { + if(fname[i] == '/') + { + fname[i] = '\\'; + } + } +#endif INIT(next, - .name = strdup(name), - .file = fopen(name, "r"), + .name = strdup(fname), + .file = fopen(fname, "r"), ); - if (next->file && fstat(fileno(next->file), &st) == 0 && S_ISREG(st.st_mode)) { array_insert(this->files, ARRAY_TAIL, next); return next->file; } - PARSER_DBG2(&this->public, "unable to open '%s'", name); + PARSER_DBG2(&this->public, "unable to open '%s'", fname); parser_helper_file_destroy(next); } file->matches->destroy(file->matches); @@ -168,6 +259,21 @@ METHOD(parser_helper_t, file_include, void, free(dir); } +#ifdef _WIN32 + if(strstr(pat, "/etc/strongswan.conf") != NULL) + { + char fname[PATH_MAX] = { 0 }; + int len = 0; + memcpy(fname, pat, strlen(pat)); + if (get_install_dir(fname)) + { + len = strlen(fname); + strcpy((&fname[len]), pat); + memset(pat, 0, sizeof(pat)); + memcpy(pat, fname, strlen(fname)); + } + } +#endif file->matches = enumerator_create_glob(pat); if (!file->matches) { /* if glob(3) is not available, try to load pattern directly */ diff --git a/src/libstrongswan/utils/utils.h b/src/libstrongswan/utils/utils.h index c7ccd3afa..1b9d18570 100644 --- a/src/libstrongswan/utils/utils.h +++ b/src/libstrongswan/utils/utils.h @@ -15,6 +15,28 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + /** * @defgroup utils_i utils * @{ @ingroup utils @@ -38,6 +60,8 @@ #ifdef WIN32 # include "compat/windows.h" +#define WIN32_LEAN_AND_MEAN +#include <windows.h> #else # include <arpa/inet.h> # include <sys/socket.h> @@ -48,6 +72,11 @@ # include <signal.h> #endif +#ifdef WIN32 +#define AF_NETLINK 16 +#define PF_NETLINK AF_NETLINK +#endif + #include "utils/types.h" #include "enum.h" #include "utils/atomics.h" diff --git a/src/swanctl/swanctl.c b/src/swanctl/swanctl.c index a3bbc28fd..d43336921 100644 --- a/src/swanctl/swanctl.c +++ b/src/swanctl/swanctl.c @@ -15,9 +15,32 @@ * for more details. */ +/* + * Copyright (C) 2019-2022 Marvell + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + #include "swanctl.h" #include "command.h" +#include <stdlib.h> #include <unistd.h> #include <library.h> @@ -28,6 +51,43 @@ */ char *swanctl_dir; +#ifdef _WIN32 +static bool get_install_dir(char *install_dir) +{ + char path[PATH_MAX], *pos; + HMODULE module; + + module = GetModuleHandle(NULL); + if (!module) + { + return FALSE; + } + if (!GetModuleFileName(module, path, sizeof(path))) + { + return FALSE; + } + + pos = strrchr(path, '\\'); + if (!pos) + { + return FALSE; + } + *pos = 0; + + pos = strstr(path, "\\usr\\"); + if (!pos) + { + return FALSE; + } + *pos = 0; + + memset(install_dir, 0, sizeof(install_dir)); + strcpy(install_dir, path); + + return TRUE; +} +#endif + /* * Described in header */ @@ -35,6 +95,7 @@ settings_t *load_swanctl_conf(char *file) { settings_t *cfg; char buf[PATH_MAX]; + char fname[PATH_MAX] = { 0 }; if (!file) { @@ -48,6 +109,39 @@ settings_t *load_swanctl_conf(char *file) DIRECTORY_SEPARATOR, SWANCTL_CONF); } + memcpy(fname, file, strlen(file)); +#ifdef _WIN32 + int len = 0; + if (get_install_dir(fname)) + { + len = strlen(fname); + if(strstr(file, "/etc/swanctl\\swanctl.conf") != NULL) + { + strcpy((&fname[len]), file); + } + else + { + memset(fname, 0, PATH_MAX); + memcpy(fname, file, strlen(file)); + } + } + else + { + memset(fname, 0, PATH_MAX); + memcpy(fname, file, strlen(file)); + } + for (int i = 0; i < strlen(fname); i++) + { + if(fname[i] == '/') + { + fname[i] = '\\'; + } + } + memset(file, 0, PATH_MAX); + memcpy(file, fname, strlen(fname)); +#endif + //DBG1(DBG_CFG, "STAGING swanctl - load_swanctl_conf - file=%s", file); + cfg = settings_create(file); if (!cfg) { -- 2.31.1.windows.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor