+++ /dev/null
-/* Libreswan config file parser keywords processor
- *
- * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
- * Copyright (C) 2003-2007 Michael Richardson <mcr@xelerance.com>
- * Copyright (C) 2007-2008 Paul Wouters <paul@xelerance.com>
- * Copyright (C) 2012-2013 Paul Wouters <paul@libreswan.org>
- * Copyright (C) 2012 Kim B. Heino <b@bbbs.net>
- * Copyright (C) 2012 Philippe Vouters <philippe.vouters@laposte.net>
- * Copyright (C) 2013 David McCullough <ucdevel@gmail.com>
- * Copyright (C) 2013-2019 D. Hugh Redelmeier <hugh@mimosa.com>
- * Copyright (C) 2013-2018 Paul Wouters <pwouters@redhat.com>
- * Copyright (C) 2013-2016 Antony Antony <antony@phenome.org>
- * Copyright (C) 2016, Andrew Cagney <cagney@gnu.org>
- * Copyright (C) 2017 Mayank Totale <mtotale@gmail.com>
- * Copyright (C) 2020, Yulia Kuzovkova <ukuzovkova@gmail.com>
- * Copyright (C) 2020 Nupur Agrawal <nupur202000@gmail.com>
- *
- * 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 <https://www.gnu.org/licenses/gpl2.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.
- *
- */
-
-#ifndef IPSECCONF_CONFIG_CONN_H
-#define IPSECCONF_CONFIG_CONN_H
-
-/*
- * Keyword value indexes. The value is stored in:
- *
- * + the keyword table determines: the keyword type; where it is valid
- * and where the value is stored are stored:
- *
- * "config setup; keyword=": in .setup.{strings,options,set}[].
- * "conn ...' keyword=": in .{strings,options,set}[]
- * "conn ; left...": in .{left,right}.{strings,options,set}[]
- *
- * + The original string is always stored in .strings[] and should be
- * used when logging errors.
- *
- * + .set[] is made non-zero (either k_set or k_default); code tests
- * for non-zero to determine if a value is present
- *
- * + for historic reasons, some of the enums have strange prefixes
- * and/or strange grouping. For instance, KSF_* options only appear
- * in "config setup" so if the same option used between multiple
- * sections the prefix should be changed.
- */
-
-enum config_conn_keyword {
- /* zero is reserved */
-
- /*
- * Generic keywords, add more here.
- */
- KWS_DEBUG = 1,
- KWS_HOST,
- KWS_NEXTHOP,
-
- KWS_RSASIGKEY,
- KWS_ECDSAKEY,
- KWS_EDDSAKEY,
- KWS_PUBKEY,
-
- KWS_IPSEC_INTERFACE,
-
- KWS_CLONES, /* RFC 9611 */
-
- /*
- * By convention, these are connection strings (KSCF is
- * Keyword String Connection Flag?). The initial ones come in
- * left/right variants.
- */
-
- KWS_GROUNDHOG, /* left/right */
- KWS_UPDOWN, /* left/right */
- KWS_ID, /* left/right */
- KWS_CERT, /* left/right */
- KWS_CKAID, /* left/right */
- KWS_CA, /* left/right */
- KWS_PROTOPORT, /* left/right */
- KWS_SOURCEIP, /* left/right */
- KWS_VTI, /* left/right */
- KWS_INTERFACE_IP, /* left/right */
- KWS_USERNAME, /* left/right */
- KWS_ADDRESSPOOL, /* left/right */
- KWS_SUBNET, /* left/right */
- KWS_SUBNETS, /* left/right */
-
- KWS_AUTHBY,
-
- KWS_PPK_IDS,
- KWS_MODECFGDNS,
- KWS_MODECFGDOMAINS,
-
- KWS_IKE,
- KWS_ESP,
- KWS_AH,
- KWS_PHASE2,
- KWS_PHASE2ALG,
-
- KWS_MODECFGBANNER,
- KSCF_ALSO,
- KWS_REDIRECT_TO,
- KWS_ACCEPT_REDIRECT_TO,
- KWS_CONNALIAS,
- KWS_SEC_LABEL,
-
- KWS_MARK,
- KWS_MARK_IN,
- KWS_MARK_OUT,
-
- KWS_VTI_INTERFACE,
- KWS_VTI_ROUTING, /* let updown do routing into VTI device */
- KWS_VTI_SHARED, /* VTI device is shared - enable checks and disable cleanup */
-
- KWS_DPDDELAY,
- KWS_DPDTIMEOUT,
-
- /*
- * By convention, these are connection numeric (or boolean)
- * values (KNCF is Keyword Numeric Connection Flag?). The
- * initial ones come in left/right variants.
- */
-
- KWS_XAUTHSERVER, /* left/right */
- KWS_XAUTHCLIENT, /* left/right */
- KWS_MODECFGSERVER, /* left/right */
- KWS_MODECFGCLIENT, /* left/right */
- KWS_CAT, /* left/right */
- KWS_SENDCERT, /* left/right */
- KWS_IKEPORT, /* left/right: IKE Port that must be used */
- KWS_AUTH, /* left/right */
- KWS_AUTHEAP, /* left/right */
-
- KWS_PFS_REKEY_WORKAROUND,
-
- KNCF_FAILURESHUNT,
- KNCF_NEGOTIATIONSHUNT,
- KNCF_TYPE,
- KWS_MOBIKE,
- KWS_MTU,
- KWS_PRIORITY,
- KWS_TFC,
-
- KWS_IPTFS,
- KWS_IPTFS_FRAGMENTATION,
- KWS_IPTFS_PACKET_SIZE,
- KWS_IPTFS_MAX_QUEUE_SIZE,
- KWS_IPTFS_REORDER_WINDOW,
- KWS_IPTFS_INIT_DELAY,
- KWS_IPTFS_DROP_TIME,
-
- KNCF_AUTO,
-
- KWS_REQID,
- KWS_SENDCA,
- KWS_METRIC,
- KWS_PFS,
- KWS_SHA2_TRUNCBUG,
- KWS_SHARE_LEASE,
- KWS_MS_DH_DOWNGRADE,
- KWS_REQUIRE_ID_ON_CERTIFICATE,
- KWS_DNS_MATCH_ID,
-
- KWS_IPSEC_LIFETIME,
- KWS_IKELIFETIME,
- KWS_RETRANSMIT_TIMEOUT,
- KWS_RETRANSMIT_INTERVAL,
- KWS_IPSEC_MAX_BYTES,
- KWS_IPSEC_MAX_PACKETS,
-
- KWS_REKEY,
- KWS_REAUTH,
- KWS_REKEYMARGIN,
- KWS_REKEYFUZZ,
- KWS_COMPRESS,
- KWS_REPLAY_WINDOW,
- KWS_AGGRESSIVE,
- KWS_MODECFGPULL,
- KWS_ENCAPSULATION,
- KWS_IKEv2, /* obsolete, use KEYEXCHANGE */
- KWS_KEYEXCHANGE,
- KWS_PPK,
- KWS_INTERMEDIATE, /* enable support for Intermediate Exchange */
- KWS_ESN,
- KWS_DECAP_DSCP,
- KWS_ENCAP_DSCP,
- KWS_NOPMTUDISC,
- KWS_NARROWING,
- KWS_PAM_AUTHORIZE,
- KWS_SEND_REDIRECT, /* this and next word are used for IKEv2 Redirect Mechanism */
- KWS_ACCEPT_REDIRECT, /* see RFC 5685 for more details */
- KWS_HOSTADDRFAMILY,
- KWS_OVERLAPIP, /* Allow overlapping IPsec policies */
- KWS_XAUTHBY, /* method of xauth user auth - file, pam or alwaysok */
- KWS_XAUTHFAIL, /* method of failing, soft or hard */
- KWS_FRAGMENTATION, /* Enable support for IKE fragmentation */
- KWS_NAT_KEEPALIVE, /* per conn enabling/disabling of sending keep-alives */
- KWS_INITIAL_CONTACT, /* send initial contact VID */
-
- /* cisco unity stuff */
- KWS_REMOTE_PEER_TYPE, /* Cisco interop: remote peer type */
- KWS_CISCO_UNITY, /* send cisco unity VID */
- KWS_NM_CONFIGURED, /* Network Manager support */
- KWS_CISCO_SPLIT, /* send cisco unity VID */
-
- KWS_SEND_ESP_TFC_PADDING_NOT_SUPPORTED,
- KWS_REJECT_SIMULTANEOUS_IKE_AUTH,
- KWS_FAKE_STRONGSWAN, /* send strongswan VID (required for twofish/serpent) */
- KWS_SEND_VENDORID, /* per conn sending of our own libreswan vendorid */
- KWS_IKEPAD, /* pad IKE packets to 4 bytes */
- KWS_NAT_IKEv1_METHOD, /* ikev1 NAT-T payloads to send/process */
- KWS_NFLOG_GROUP, /* Enable per-conn nflog device */
- KWS_NIC_OFFLOAD, /* xfrm offload to network device */
- KWS_ENABLE_TCP, /* TCP (yes/no/fallback) */
- KWS_TCP_REMOTEPORT, /* TCP remote port - default 4500 */
- KWS_IGNORE_PEER_DNS, /* Accept DNS nameservers from peer */
- KWS_SESSION_RESUMPTION, /* RFC 5723 IKE_RESUME */
-
-#define CONFIG_CONN_KEYWORD_ROOF (KWS_SESSION_RESUMPTION + 1)
-};
-
-#endif
+++ /dev/null
-/* ipsec.conf's config setup for Libreswan
- *
- * Copyright (C) 2025 Andrew Cagney
- *
- * 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 <https://www.gnu.org/licenses/gpl2.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.
- */
-
-#ifndef CONFIG_SETUP_H
-#define CONFIG_SETUP_H
-
-#include <stdint.h>
-
-#include "lset.h"
-#include "deltatime.h"
-
-enum yn_options;
-struct logger;
-struct ipsec_conf;
-
-enum config_setup_keyword {
- /* zero is reserved */
-
- /*
- * By convention, these are global configuration strings and
- * only appear in the "config setup" section (KSF == Keyword
- * String Flag?).
- */
- KSF_CURLIFACE = 1,
- KSF_VIRTUAL_PRIVATE,
- KSF_DUMPDIR,
- KSF_STATSBIN,
- KSF_IPSECDIR,
- KSF_NSSDIR,
- KSF_SECRETSFILE,
- KSF_MYVENDORID,
- KSF_LOGFILE,
- KSF_RUNDIR, /* placeholder, no option */
- KSF_DNSSEC_ROOTKEY_FILE,
- KSF_DNSSEC_ANCHORS,
- KYN_DNSSEC_ENABLE,
- KSF_PROTOSTACK,
- KBF_GLOBAL_REDIRECT,
- KSF_GLOBAL_REDIRECT_TO,
- KSF_OCSP_URI,
- KSF_OCSP_TRUSTNAME,
- KSF_EXPIRE_SHUNT_INTERVAL,
- KSF_DNS_RESOLVER,
-
- /*
- * By convention, these are global configuration numeric (and
- * boolean) values and only appear in the "config setup"
- * section (KBF == Keyword Boolean Flag?).
- *
- * KYN implies yn_options.
- */
- KYN_UNIQUEIDS,
- KYN_LOGTIME,
- KYN_LOGAPPEND,
- KYN_LOGIP,
- KYN_LOGSTDERR, /*no matching option*/
- KYN_AUDIT_LOG,
- KBF_IKE_SOCKET_BUFSIZE,
- KYN_IKE_SOCKET_ERRQUEUE,
- KBF_EXPIRE_LIFETIME,
- KYN_CRL_STRICT,
- KBF_CRL_CHECKINTERVAL,
- KBF_CRL_TIMEOUT_SECONDS,
- KYN_OCSP_STRICT,
- KYN_OCSP_ENABLE,
- KBF_OCSP_TIMEOUT_SECONDS,
- KBF_OCSP_CACHE_SIZE,
- KBF_OCSP_CACHE_MIN_AGE_SECONDS,
- KBF_OCSP_CACHE_MAX_AGE_SECONDS,
- KBF_OCSP_METHOD,
- KBF_SEEDBITS,
- KYN_DROP_OPPO_NULL,
- KBF_KEEP_ALIVE,
- KBF_NHELPERS,
- KBF_SHUNTLIFETIME,
- KBF_DDOS_IKE_THRESHOLD,
- KBF_MAX_HALFOPEN_IKE,
- KBF_NFLOG_ALL, /* Enable global nflog device */
- KBF_DDOS_MODE, /* set DDOS mode */
- KBF_SECCOMP, /* set SECCOMP mode */
-
- KSF_LISTEN, /* address(s) to listen on */
- KYN_LISTEN_TCP, /* listen on TCP port 4500 - default no */
- KYN_LISTEN_UDP, /* listen on UDP port 500/4500 - default yes */
-
- KBF_IKEv1_POLICY, /* global ikev1 policy - default drop */
- KSF_PLUTODEBUG,
- KYN_IPSEC_INTERFACE_MANAGED,
-
-#define CONFIG_SETUP_KEYWORD_ROOF (KYN_IPSEC_INTERFACE_MANAGED+1)
-};
-
-bool load_config_setup(const char *file,
- struct logger *logger,
- unsigned verbosity);
-bool parse_ipsec_conf_config_setup(const struct ipsec_conf *cfgp,
- struct logger *logger);
-
-const struct config_setup *config_setup_singleton(void);
-void free_config_setup(void);
-
-void update_setup_string(enum config_setup_keyword kw, const char *string);
-void update_setup_yn(enum config_setup_keyword kw, enum yn_options yn);
-void update_setup_deltatime(enum config_setup_keyword kw, deltatime_t deltatime);
-void update_setup_option(enum config_setup_keyword kw, uintmax_t option);
-
-const char *config_setup_string(const struct config_setup *setup, enum config_setup_keyword field);
-const char *config_setup_string_or_unset(const struct config_setup *setup, enum config_setup_keyword field, const char *unset);
-bool config_setup_yn(const struct config_setup *setup, enum config_setup_keyword field);
-deltatime_t config_setup_deltatime(const struct config_setup *setup, enum config_setup_keyword field);
-uintmax_t config_setup_option(const struct config_setup *setup, enum config_setup_keyword field);
-
-const char *config_setup_ipsecdir(void);
-const char *config_setup_secretsfile(void);
-const char *config_setup_nssdir(void);
-const char *config_setup_dumpdir(void);
-const char *config_setup_vendorid(void);
-lset_t config_setup_debugging(struct logger *logger);
-
-#endif
#include <sys/queue.h> /* for TAILQ_ENTRY() */
#include <stdint.h>
-#include "ipsecconf/config_setup.h"
-#include "ipsecconf/config_conn.h"
+#include "ipsecconf/setup.h"
+#include "ipsecconf/conn.h"
#include "deltatime.h"
#include "ip_address.h"
--- /dev/null
+/* Libreswan config file parser keywords processor
+ *
+ * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
+ * Copyright (C) 2003-2007 Michael Richardson <mcr@xelerance.com>
+ * Copyright (C) 2007-2008 Paul Wouters <paul@xelerance.com>
+ * Copyright (C) 2012-2013 Paul Wouters <paul@libreswan.org>
+ * Copyright (C) 2012 Kim B. Heino <b@bbbs.net>
+ * Copyright (C) 2012 Philippe Vouters <philippe.vouters@laposte.net>
+ * Copyright (C) 2013 David McCullough <ucdevel@gmail.com>
+ * Copyright (C) 2013-2019 D. Hugh Redelmeier <hugh@mimosa.com>
+ * Copyright (C) 2013-2018 Paul Wouters <pwouters@redhat.com>
+ * Copyright (C) 2013-2016 Antony Antony <antony@phenome.org>
+ * Copyright (C) 2016, Andrew Cagney <cagney@gnu.org>
+ * Copyright (C) 2017 Mayank Totale <mtotale@gmail.com>
+ * Copyright (C) 2020, Yulia Kuzovkova <ukuzovkova@gmail.com>
+ * Copyright (C) 2020 Nupur Agrawal <nupur202000@gmail.com>
+ *
+ * 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 <https://www.gnu.org/licenses/gpl2.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.
+ *
+ */
+
+#ifndef IPSECCONF_CONFIG_CONN_H
+#define IPSECCONF_CONFIG_CONN_H
+
+/*
+ * Keyword value indexes. The value is stored in:
+ *
+ * + the keyword table determines: the keyword type; where it is valid
+ * and where the value is stored are stored:
+ *
+ * "config setup; keyword=": in .setup.{strings,options,set}[].
+ * "conn ...' keyword=": in .{strings,options,set}[]
+ * "conn ; left...": in .{left,right}.{strings,options,set}[]
+ *
+ * + The original string is always stored in .strings[] and should be
+ * used when logging errors.
+ *
+ * + .set[] is made non-zero (either k_set or k_default); code tests
+ * for non-zero to determine if a value is present
+ *
+ * + for historic reasons, some of the enums have strange prefixes
+ * and/or strange grouping. For instance, KSF_* options only appear
+ * in "config setup" so if the same option used between multiple
+ * sections the prefix should be changed.
+ */
+
+enum config_conn_keyword {
+ /* zero is reserved */
+
+ /*
+ * Generic keywords, add more here.
+ */
+ KWS_DEBUG = 1,
+ KWS_HOST,
+ KWS_NEXTHOP,
+
+ KWS_RSASIGKEY,
+ KWS_ECDSAKEY,
+ KWS_EDDSAKEY,
+ KWS_PUBKEY,
+
+ KWS_IPSEC_INTERFACE,
+
+ KWS_CLONES, /* RFC 9611 */
+
+ /*
+ * By convention, these are connection strings (KSCF is
+ * Keyword String Connection Flag?). The initial ones come in
+ * left/right variants.
+ */
+
+ KWS_GROUNDHOG, /* left/right */
+ KWS_UPDOWN, /* left/right */
+ KWS_ID, /* left/right */
+ KWS_CERT, /* left/right */
+ KWS_CKAID, /* left/right */
+ KWS_CA, /* left/right */
+ KWS_PROTOPORT, /* left/right */
+ KWS_SOURCEIP, /* left/right */
+ KWS_VTI, /* left/right */
+ KWS_INTERFACE_IP, /* left/right */
+ KWS_USERNAME, /* left/right */
+ KWS_ADDRESSPOOL, /* left/right */
+ KWS_SUBNET, /* left/right */
+ KWS_SUBNETS, /* left/right */
+
+ KWS_AUTHBY,
+
+ KWS_PPK_IDS,
+ KWS_MODECFGDNS,
+ KWS_MODECFGDOMAINS,
+
+ KWS_IKE,
+ KWS_ESP,
+ KWS_AH,
+ KWS_PHASE2,
+ KWS_PHASE2ALG,
+
+ KWS_MODECFGBANNER,
+ KSCF_ALSO,
+ KWS_REDIRECT_TO,
+ KWS_ACCEPT_REDIRECT_TO,
+ KWS_CONNALIAS,
+ KWS_SEC_LABEL,
+
+ KWS_MARK,
+ KWS_MARK_IN,
+ KWS_MARK_OUT,
+
+ KWS_VTI_INTERFACE,
+ KWS_VTI_ROUTING, /* let updown do routing into VTI device */
+ KWS_VTI_SHARED, /* VTI device is shared - enable checks and disable cleanup */
+
+ KWS_DPDDELAY,
+ KWS_DPDTIMEOUT,
+
+ /*
+ * By convention, these are connection numeric (or boolean)
+ * values (KNCF is Keyword Numeric Connection Flag?). The
+ * initial ones come in left/right variants.
+ */
+
+ KWS_XAUTHSERVER, /* left/right */
+ KWS_XAUTHCLIENT, /* left/right */
+ KWS_MODECFGSERVER, /* left/right */
+ KWS_MODECFGCLIENT, /* left/right */
+ KWS_CAT, /* left/right */
+ KWS_SENDCERT, /* left/right */
+ KWS_IKEPORT, /* left/right: IKE Port that must be used */
+ KWS_AUTH, /* left/right */
+ KWS_AUTHEAP, /* left/right */
+
+ KWS_PFS_REKEY_WORKAROUND,
+
+ KNCF_FAILURESHUNT,
+ KNCF_NEGOTIATIONSHUNT,
+ KNCF_TYPE,
+ KWS_MOBIKE,
+ KWS_MTU,
+ KWS_PRIORITY,
+ KWS_TFC,
+
+ KWS_IPTFS,
+ KWS_IPTFS_FRAGMENTATION,
+ KWS_IPTFS_PACKET_SIZE,
+ KWS_IPTFS_MAX_QUEUE_SIZE,
+ KWS_IPTFS_REORDER_WINDOW,
+ KWS_IPTFS_INIT_DELAY,
+ KWS_IPTFS_DROP_TIME,
+
+ KNCF_AUTO,
+
+ KWS_REQID,
+ KWS_SENDCA,
+ KWS_METRIC,
+ KWS_PFS,
+ KWS_SHA2_TRUNCBUG,
+ KWS_SHARE_LEASE,
+ KWS_MS_DH_DOWNGRADE,
+ KWS_REQUIRE_ID_ON_CERTIFICATE,
+ KWS_DNS_MATCH_ID,
+
+ KWS_IPSEC_LIFETIME,
+ KWS_IKELIFETIME,
+ KWS_RETRANSMIT_TIMEOUT,
+ KWS_RETRANSMIT_INTERVAL,
+ KWS_IPSEC_MAX_BYTES,
+ KWS_IPSEC_MAX_PACKETS,
+
+ KWS_REKEY,
+ KWS_REAUTH,
+ KWS_REKEYMARGIN,
+ KWS_REKEYFUZZ,
+ KWS_COMPRESS,
+ KWS_REPLAY_WINDOW,
+ KWS_AGGRESSIVE,
+ KWS_MODECFGPULL,
+ KWS_ENCAPSULATION,
+ KWS_IKEv2, /* obsolete, use KEYEXCHANGE */
+ KWS_KEYEXCHANGE,
+ KWS_PPK,
+ KWS_INTERMEDIATE, /* enable support for Intermediate Exchange */
+ KWS_ESN,
+ KWS_DECAP_DSCP,
+ KWS_ENCAP_DSCP,
+ KWS_NOPMTUDISC,
+ KWS_NARROWING,
+ KWS_PAM_AUTHORIZE,
+ KWS_SEND_REDIRECT, /* this and next word are used for IKEv2 Redirect Mechanism */
+ KWS_ACCEPT_REDIRECT, /* see RFC 5685 for more details */
+ KWS_HOSTADDRFAMILY,
+ KWS_OVERLAPIP, /* Allow overlapping IPsec policies */
+ KWS_XAUTHBY, /* method of xauth user auth - file, pam or alwaysok */
+ KWS_XAUTHFAIL, /* method of failing, soft or hard */
+ KWS_FRAGMENTATION, /* Enable support for IKE fragmentation */
+ KWS_NAT_KEEPALIVE, /* per conn enabling/disabling of sending keep-alives */
+ KWS_INITIAL_CONTACT, /* send initial contact VID */
+
+ /* cisco unity stuff */
+ KWS_REMOTE_PEER_TYPE, /* Cisco interop: remote peer type */
+ KWS_CISCO_UNITY, /* send cisco unity VID */
+ KWS_NM_CONFIGURED, /* Network Manager support */
+ KWS_CISCO_SPLIT, /* send cisco unity VID */
+
+ KWS_SEND_ESP_TFC_PADDING_NOT_SUPPORTED,
+ KWS_REJECT_SIMULTANEOUS_IKE_AUTH,
+ KWS_FAKE_STRONGSWAN, /* send strongswan VID (required for twofish/serpent) */
+ KWS_SEND_VENDORID, /* per conn sending of our own libreswan vendorid */
+ KWS_IKEPAD, /* pad IKE packets to 4 bytes */
+ KWS_NAT_IKEv1_METHOD, /* ikev1 NAT-T payloads to send/process */
+ KWS_NFLOG_GROUP, /* Enable per-conn nflog device */
+ KWS_NIC_OFFLOAD, /* xfrm offload to network device */
+ KWS_ENABLE_TCP, /* TCP (yes/no/fallback) */
+ KWS_TCP_REMOTEPORT, /* TCP remote port - default 4500 */
+ KWS_IGNORE_PEER_DNS, /* Accept DNS nameservers from peer */
+ KWS_SESSION_RESUMPTION, /* RFC 5723 IKE_RESUME */
+
+#define CONFIG_CONN_KEYWORD_ROOF (KWS_SESSION_RESUMPTION + 1)
+};
+
+#endif
--- /dev/null
+/* ipsec.conf's config setup for Libreswan
+ *
+ * Copyright (C) 2025 Andrew Cagney
+ *
+ * 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 <https://www.gnu.org/licenses/gpl2.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.
+ */
+
+#ifndef CONFIG_SETUP_H
+#define CONFIG_SETUP_H
+
+#include <stdint.h>
+
+#include "lset.h"
+#include "deltatime.h"
+
+enum yn_options;
+struct logger;
+struct ipsec_conf;
+
+enum config_setup_keyword {
+ /* zero is reserved */
+
+ /*
+ * By convention, these are global configuration strings and
+ * only appear in the "config setup" section (KSF == Keyword
+ * String Flag?).
+ */
+ KSF_CURLIFACE = 1,
+ KSF_VIRTUAL_PRIVATE,
+ KSF_DUMPDIR,
+ KSF_STATSBIN,
+ KSF_IPSECDIR,
+ KSF_NSSDIR,
+ KSF_SECRETSFILE,
+ KSF_MYVENDORID,
+ KSF_LOGFILE,
+ KSF_RUNDIR, /* placeholder, no option */
+ KSF_DNSSEC_ROOTKEY_FILE,
+ KSF_DNSSEC_ANCHORS,
+ KYN_DNSSEC_ENABLE,
+ KSF_PROTOSTACK,
+ KBF_GLOBAL_REDIRECT,
+ KSF_GLOBAL_REDIRECT_TO,
+ KSF_OCSP_URI,
+ KSF_OCSP_TRUSTNAME,
+ KSF_EXPIRE_SHUNT_INTERVAL,
+ KSF_DNS_RESOLVER,
+
+ /*
+ * By convention, these are global configuration numeric (and
+ * boolean) values and only appear in the "config setup"
+ * section (KBF == Keyword Boolean Flag?).
+ *
+ * KYN implies yn_options.
+ */
+ KYN_UNIQUEIDS,
+ KYN_LOGTIME,
+ KYN_LOGAPPEND,
+ KYN_LOGIP,
+ KYN_LOGSTDERR, /*no matching option*/
+ KYN_AUDIT_LOG,
+ KBF_IKE_SOCKET_BUFSIZE,
+ KYN_IKE_SOCKET_ERRQUEUE,
+ KBF_EXPIRE_LIFETIME,
+ KYN_CRL_STRICT,
+ KBF_CRL_CHECKINTERVAL,
+ KBF_CRL_TIMEOUT_SECONDS,
+ KYN_OCSP_STRICT,
+ KYN_OCSP_ENABLE,
+ KBF_OCSP_TIMEOUT_SECONDS,
+ KBF_OCSP_CACHE_SIZE,
+ KBF_OCSP_CACHE_MIN_AGE_SECONDS,
+ KBF_OCSP_CACHE_MAX_AGE_SECONDS,
+ KBF_OCSP_METHOD,
+ KBF_SEEDBITS,
+ KYN_DROP_OPPO_NULL,
+ KBF_KEEP_ALIVE,
+ KBF_NHELPERS,
+ KBF_SHUNTLIFETIME,
+ KBF_DDOS_IKE_THRESHOLD,
+ KBF_MAX_HALFOPEN_IKE,
+ KBF_NFLOG_ALL, /* Enable global nflog device */
+ KBF_DDOS_MODE, /* set DDOS mode */
+ KBF_SECCOMP, /* set SECCOMP mode */
+
+ KSF_LISTEN, /* address(s) to listen on */
+ KYN_LISTEN_TCP, /* listen on TCP port 4500 - default no */
+ KYN_LISTEN_UDP, /* listen on UDP port 500/4500 - default yes */
+
+ KBF_IKEv1_POLICY, /* global ikev1 policy - default drop */
+ KSF_PLUTODEBUG,
+ KYN_IPSEC_INTERFACE_MANAGED,
+
+#define CONFIG_SETUP_KEYWORD_ROOF (KYN_IPSEC_INTERFACE_MANAGED+1)
+};
+
+bool load_config_setup(const char *file,
+ struct logger *logger,
+ unsigned verbosity);
+bool parse_ipsec_conf_config_setup(const struct ipsec_conf *cfgp,
+ struct logger *logger);
+
+const struct config_setup *config_setup_singleton(void);
+void free_config_setup(void);
+
+void update_setup_string(enum config_setup_keyword kw, const char *string);
+void update_setup_yn(enum config_setup_keyword kw, enum yn_options yn);
+void update_setup_deltatime(enum config_setup_keyword kw, deltatime_t deltatime);
+void update_setup_option(enum config_setup_keyword kw, uintmax_t option);
+
+const char *config_setup_string(const struct config_setup *setup, enum config_setup_keyword field);
+const char *config_setup_string_or_unset(const struct config_setup *setup, enum config_setup_keyword field, const char *unset);
+bool config_setup_yn(const struct config_setup *setup, enum config_setup_keyword field);
+deltatime_t config_setup_deltatime(const struct config_setup *setup, enum config_setup_keyword field);
+uintmax_t config_setup_option(const struct config_setup *setup, enum config_setup_keyword field);
+
+const char *config_setup_ipsecdir(void);
+const char *config_setup_secretsfile(void);
+const char *config_setup_nssdir(void);
+const char *config_setup_dumpdir(void);
+const char *config_setup_vendorid(void);
+lset_t config_setup_debugging(struct logger *logger);
+
+#endif
#include "xauthby.h"
#include "xauthfail.h"
#include "ddos_mode.h"
-#include "ipsecconf/config_conn.h" /* for CONFIG_CONN_KEYWORD_ROOF */
+#include "ipsecconf/conn.h" /* for CONFIG_CONN_KEYWORD_ROOF */
#ifndef DEFAULT_CTL_SOCKET
# define DEFAULT_CTL_SOCKET IPSEC_RUNDIR "/pluto.ctl"
$(OBJS): | $(builddir)/ipsecconf/
-OBJS += ipsecconf/config_conn.o
-OBJS += ipsecconf/config_setup.o
+OBJS += ipsecconf/conn.o
+OBJS += ipsecconf/setup.o
OBJS += ipsecconf/confread.o
OBJS += ipsecconf/confwrite.o
OBJS += ipsecconf/interfaces.o
+++ /dev/null
-/*
- * Libreswan config file parser (keywords.c)
- * Copyright (C) 2003-2006 Michael Richardson <mcr@xelerance.com>
- * Copyright (C) 2007-2010 Paul Wouters <paul@xelerance.com>
- * Copyright (C) 2012 Paul Wouters <paul@libreswan.org>
- * Copyright (C) 2013-2019 Paul Wouters <pwouters@redhat.com>
- * Copyright (C) 2013-2019 D. Hugh Redelmeier <hugh@mimosa.com>
- * Copyright (C) 2013 David McCullough <ucdevel@gmail.com>
- * Copyright (C) 2013-2016 Antony Antony <antony@phenome.org>
- * Copyright (C) 2016-2022 Andrew Cagney
- * Copyright (C) 2017 Mayank Totale <mtotale@gmail.com>
- * Copyright (C) 2020 Yulia Kuzovkova <ukuzovkova@gmail.com>
- * Copyright (C) 2020 Nupur Agrawal <nupur202000@gmail.com>
- *
- * 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 <https://www.gnu.org/licenses/gpl2.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include "constants.h" /* for yn_option_names; */
-#include "lswcdefs.h" /* for elemsof() */
-
-#include "ipsecconf/config_conn.h"
-#include "ipsecconf/keywords.h"
-#include "xauthby.h"
-#include "xauthfail.h"
-#include "shunt.h"
-#include "sparse_names.h"
-#include "encap_proto.h"
-
-/*
- * Values for right= and left=
- */
-
-static const struct keyword_def config_conn_keyword[] = {
-#define K(KEYNAME, VALIDITY, TYPE, FIELD, ...) [FIELD] = { .keyname = KEYNAME, .field = FIELD, .type = TYPE, .validity = VALIDITY, ##__VA_ARGS__ }
-#define U(KEYNAME, VALIDITY, TYPE, FIELD, ...) [FIELD] = { .keyname = KEYNAME, .field = FIELD, .type = kt_nosup, }
-
- /*
- * This is "left=" and "right="
- */
- K("", kv_leftright, kt_string, KWS_HOST),
-
- K("debug", LEMPTY, kt_string, KWS_DEBUG),
-
- K("subnet", kv_leftright, kt_string, KWS_SUBNET),
- K("subnets", kv_leftright, kt_appendlist, KWS_SUBNETS),
- K("sourceip", kv_leftright, kt_string, KWS_SOURCEIP),
- K("ikeport", kv_leftright, kt_string, KWS_IKEPORT),
- K("interface-ip", kv_leftright, kt_string, KWS_INTERFACE_IP),
- K("vti", kv_leftright, kt_string, KWS_VTI),
- K("nexthop", kv_leftright, kt_string, KWS_NEXTHOP),
- K("updown", kv_leftright, kt_string, KWS_UPDOWN),
- K("id", kv_leftright, kt_string, KWS_ID),
-
- K("rsasigkey", kv_leftright, kt_string, KWS_RSASIGKEY),
- K("ecdsakey", kv_leftright, kt_string, KWS_ECDSAKEY),
- K("eddsakey", kv_leftright, kt_string, KWS_EDDSAKEY),
- K("pubkey", kv_leftright, kt_string, KWS_PUBKEY),
-
- K("cert", kv_leftright, kt_string, KWS_CERT),
- K("ckaid", kv_leftright, kt_string, KWS_CKAID),
- K("sendcert", kv_leftright, kt_string, KWS_SENDCERT),
- K("ca", kv_leftright, kt_string, KWS_CA),
- K("xauthserver", kv_leftright, kt_string, KWS_XAUTHSERVER),
- K("xauthclient", kv_leftright, kt_string, KWS_XAUTHCLIENT),
- K("modecfgserver", kv_leftright, kt_string, KWS_MODECFGSERVER),
- K("modecfgclient", kv_leftright, kt_string, KWS_MODECFGCLIENT),
- K("username", kv_leftright, kt_string, KWS_USERNAME),
- K("addresspool", kv_leftright, kt_string, KWS_ADDRESSPOOL),
- K("auth", kv_leftright, kt_string, KWS_AUTH),
-
-#ifdef USE_CAT
-# define S K
-#else
-# define S U
-#endif
- S("cat", kv_leftright, kt_string, KWS_CAT),
-#undef S
-
- K("protoport", kv_leftright, kt_string, KWS_PROTOPORT),
- K("autheap", kv_leftright, kt_string, KWS_AUTHEAP),
- K("groundhog", kv_leftright, kt_string, KWS_GROUNDHOG),
-
- /* these are conn statements which are not left/right */
-
- K("auto", LEMPTY, kt_sparse_name, KNCF_AUTO, .sparse_names = &autostart_names),
- K("also", kv_duplicateok, kt_also, KSCF_ALSO),
- K("hostaddrfamily", LEMPTY, kt_string, KWS_HOSTADDRFAMILY),
- K("type", LEMPTY, kt_sparse_name, KNCF_TYPE, .sparse_names = &type_option_names),
- K("authby", LEMPTY, kt_string, KWS_AUTHBY),
- K("keyexchange", LEMPTY, kt_string, KWS_KEYEXCHANGE),
- K("ikev2", LEMPTY, kt_string, KWS_IKEv2),
- K("ppk", LEMPTY, kt_string, KWS_PPK),
- K("ppk-ids", LEMPTY, kt_string, KWS_PPK_IDS),
- K("intermediate", LEMPTY, kt_string, KWS_INTERMEDIATE),
- K("esn", LEMPTY, kt_string, KWS_ESN),
- K("decap-dscp", LEMPTY, kt_string, KWS_DECAP_DSCP),
- K("encap-dscp", LEMPTY, kt_string, KWS_ENCAP_DSCP),
- K("nopmtudisc", LEMPTY, kt_string, KWS_NOPMTUDISC),
- K("fragmentation", LEMPTY, kt_string, KWS_FRAGMENTATION),
- K("mobike", LEMPTY, kt_string, KWS_MOBIKE),
- K("narrowing", LEMPTY, kt_string, KWS_NARROWING),
- K("pam-authorize", LEMPTY, kt_string, KWS_PAM_AUTHORIZE),
- K("send-redirect", LEMPTY, kt_string, KWS_SEND_REDIRECT),
- K("redirect-to", LEMPTY, kt_string, KWS_REDIRECT_TO),
- K("accept-redirect", LEMPTY, kt_string, KWS_ACCEPT_REDIRECT),
- K("accept-redirect-to", LEMPTY, kt_string, KWS_ACCEPT_REDIRECT_TO),
- K("pfs", LEMPTY, kt_string, KWS_PFS),
- K("session-resumption", LEMPTY, kt_string, KWS_SESSION_RESUMPTION),
-
- K("nat-keepalive", LEMPTY, kt_string, KWS_NAT_KEEPALIVE),
-
- K("initial-contact", LEMPTY, kt_string, KWS_INITIAL_CONTACT),
- K("send-esp-tfc-padding-not-supported", LEMPTY, kt_string, KWS_SEND_ESP_TFC_PADDING_NOT_SUPPORTED),
- K("reject-simultaneous-ike-auth", LEMPTY, kt_string, KWS_REJECT_SIMULTANEOUS_IKE_AUTH),
-
- K("iptfs", LEMPTY, kt_string, KWS_IPTFS),
- K("iptfs-fragmentation", LEMPTY, kt_string, KWS_IPTFS_FRAGMENTATION),
- K("iptfs-packet-size", LEMPTY, kt_string, KWS_IPTFS_PACKET_SIZE),
- K("iptfs-max-queue-size", LEMPTY, kt_string, KWS_IPTFS_MAX_QUEUE_SIZE),
- K("iptfs-reorder-window", LEMPTY, kt_string, KWS_IPTFS_REORDER_WINDOW),
- K("iptfs-init-delay", LEMPTY, kt_string, KWS_IPTFS_INIT_DELAY),
- K("iptfs-drop-time", LEMPTY, kt_string, KWS_IPTFS_DROP_TIME),
-
- K("fake-strongswan", LEMPTY, kt_string, KWS_FAKE_STRONGSWAN),
- K("send-vendorid", LEMPTY, kt_string, KWS_SEND_VENDORID),
- K("sha2-truncbug", LEMPTY, kt_string, KWS_SHA2_TRUNCBUG),
- K("share-lease", LEMPTY, kt_string, KWS_SHARE_LEASE),
- K("ms-dh-downgrade", LEMPTY, kt_string, KWS_MS_DH_DOWNGRADE),
- K("pfs-rekey-workaround", LEMPTY, kt_string, KWS_PFS_REKEY_WORKAROUND),
- K("require-id-on-certificate", LEMPTY, kt_string, KWS_REQUIRE_ID_ON_CERTIFICATE),
- K("dns-match-id,", LEMPTY, kt_string, KWS_DNS_MATCH_ID),
- K("ipsec-max-bytes", LEMPTY, kt_string, KWS_IPSEC_MAX_BYTES),
- K("ipsec-max-packets", LEMPTY, kt_string, KWS_IPSEC_MAX_PACKETS),
- K("ipsec-lifetime", LEMPTY, kt_string, KWS_IPSEC_LIFETIME),
-
- K("retransmit-timeout", LEMPTY, kt_string, KWS_RETRANSMIT_TIMEOUT),
- K("retransmit-interval", LEMPTY, kt_string, KWS_RETRANSMIT_INTERVAL),
-
- K("ikepad", LEMPTY, kt_string, KWS_IKEPAD),
- K("nat-ikev1-method", LEMPTY, kt_string, KWS_NAT_IKEv1_METHOD),
-
- K("sec-label", LEMPTY, kt_string, KWS_SEC_LABEL),
-
- /* Cisco interop: remote peer type */
- K("remote-peer-type", LEMPTY, kt_string, KWS_REMOTE_PEER_TYPE),
- /* Network Manager support */
- K("nm-configured", LEMPTY, kt_string, KWS_NM_CONFIGURED),
- K("cisco-unity", LEMPTY, kt_string, KWS_CISCO_UNITY),
- K("cisco-split", LEMPTY, kt_string, KWS_CISCO_SPLIT),
-
- K("xauthby", LEMPTY, kt_string, KWS_XAUTHBY),
- K("xauthfail", LEMPTY, kt_string, KWS_XAUTHFAIL),
- K("modecfgpull", LEMPTY, kt_string, KWS_MODECFGPULL),
- K("modecfgdns", LEMPTY, kt_string, KWS_MODECFGDNS),
- K("modecfgdomains", LEMPTY, kt_string, KWS_MODECFGDOMAINS),
- K("modecfgbanner", LEMPTY, kt_string, KWS_MODECFGBANNER),
- K("ignore-peer-dns", LEMPTY, kt_string, KWS_IGNORE_PEER_DNS),
-
- K("mark", LEMPTY, kt_string, KWS_MARK),
- K("mark-in", LEMPTY, kt_string, KWS_MARK_IN),
- K("mark-out", LEMPTY, kt_string, KWS_MARK_OUT),
-
- K("vti-interface", LEMPTY, kt_string, KWS_VTI_INTERFACE),
- K("vti-routing", LEMPTY, kt_string, KWS_VTI_ROUTING),
- K("vti-shared", LEMPTY, kt_string, KWS_VTI_SHARED),
-
- K("ipsec-interface", LEMPTY, kt_string, KWS_IPSEC_INTERFACE),
-
- K("clones", LEMPTY, kt_string, KWS_CLONES),
-
- K("nic-offload", LEMPTY, kt_string, KWS_NIC_OFFLOAD),
-
- K("encapsulation", LEMPTY, kt_string, KWS_ENCAPSULATION),
-
- K("overlapip", LEMPTY, kt_string, KWS_OVERLAPIP),
- K("reauth", LEMPTY, kt_string, KWS_REAUTH),
- K("rekey", LEMPTY, kt_string, KWS_REKEY),
- K("rekeymargin", LEMPTY, kt_string, KWS_REKEYMARGIN),
- K("rekeyfuzz", LEMPTY, kt_string, KWS_REKEYFUZZ),
- K("replay-window", LEMPTY, kt_string, KWS_REPLAY_WINDOW),
- K("ikelifetime", LEMPTY, kt_string, KWS_IKELIFETIME),
- K("failureshunt", LEMPTY, kt_sparse_name, KNCF_FAILURESHUNT, .sparse_names = &failure_shunt_names),
- K("negotiationshunt", LEMPTY, kt_sparse_name, KNCF_NEGOTIATIONSHUNT, .sparse_names = &negotiation_shunt_names),
-
- K("enable-tcp", LEMPTY, kt_string, KWS_ENABLE_TCP),
- K("tcp-remoteport", LEMPTY, kt_string, KWS_TCP_REMOTEPORT),
-
- K("connalias", LEMPTY, kt_appendstring, KWS_CONNALIAS),
-
- /* attributes of the phase1 policy */
- K("ike", LEMPTY, kt_string, KWS_IKE),
- /* attributes of the phase2 policy */
- K("esp", LEMPTY, kt_string, KWS_ESP),
- K("ah", LEMPTY, kt_string, KWS_AH),
- K("phase2", LEMPTY, kt_string, KWS_PHASE2),
- K("phase2alg", LEMPTY, kt_string, KWS_PHASE2ALG),
-
- K("compress", LEMPTY, kt_string, KWS_COMPRESS),
-
- /* route metric */
- K("metric", LEMPTY, kt_string, KWS_METRIC),
-
- /* DPD */
- K("dpddelay", LEMPTY, kt_string, KWS_DPDDELAY),
- K("ikev1-dpdtimeout", LEMPTY, kt_string, KWS_DPDTIMEOUT),
-
- K("sendca", LEMPTY, kt_string, KWS_SENDCA),
-
- K("mtu", LEMPTY, kt_string, KWS_MTU),
- K("priority", LEMPTY, kt_string, KWS_PRIORITY),
- K("tfc", LEMPTY, kt_string, KWS_TFC),
- K("reqid", LEMPTY, kt_string, KWS_REQID),
-
-#ifdef USE_NFLOG
-# define S K
-#else
-# define S U
-#endif
- S("nflog-group", LEMPTY, kt_string, KWS_NFLOG_GROUP),
-#undef S
-
- K("aggressive", LEMPTY, kt_string, KWS_AGGRESSIVE),
-
- /*
- * Force first alias/obsolete keyword into slot following all
- * defined keywords. Else compiler tries to store it into above
- * keyword's slot + 1, which is likely occupied by another keyword.
- * The result is a nonsensical error.
- */
- [CONFIG_CONN_KEYWORD_ROOF] =
-
- /* alias for compatibility - undocumented on purpose */
-
-#define A(KEYNAME, VALIDITY, TYPE, FIELD, ...) { .keyname = KEYNAME, .validity = VALIDITY|kv_alias, .type = TYPE, .field = FIELD, ##__VA_ARGS__ }
-
- A("aggrmode", LEMPTY, kt_string, KWS_AGGRESSIVE),
- A("keylife", LEMPTY, kt_string, KWS_IPSEC_LIFETIME), /* old name */
- A("lifetime", LEMPTY, kt_string, KWS_IPSEC_LIFETIME), /* old name */
- A("phase2alg", LEMPTY, kt_string, KWS_ESP), /* obsolete */
- A("dpdtimeout", LEMPTY, kt_string, KWS_DPDTIMEOUT), /* old name */
-#ifdef USE_NFLOG
- A("nflog", LEMPTY, kt_string, KWS_NFLOG_GROUP), /* old-name */
-#endif
- A("salifetime", LEMPTY, kt_string, KWS_IPSEC_LIFETIME), /* old name */
- /* xauthusername is still used in NetworkManager-libreswan :/ */
- A("xauthusername", kv_leftright, kt_string, KWS_USERNAME), /* old alias */
- A("ah", LEMPTY, kt_string, KWS_ESP),
- A("policy-label", LEMPTY, kt_string, KWS_SEC_LABEL), /* obsolete variant */
- /* another alias used by NetworkManager-libreswan :/ */
- A("remote_peer_type", LEMPTY, kt_string, KWS_REMOTE_PEER_TYPE),
- A("send-no-esp-tfc", LEMPTY, kt_string, KWS_SEND_ESP_TFC_PADDING_NOT_SUPPORTED), /*compat, but forever*/
-
- /* obsolete config setup options */
-
-#define O(KEYNAME, ...) { .keyname = KEYNAME, .type = kt_obsolete, }
-
- O("dpdaction"),
- O("clientaddrfamily"),
- O("keyingtries"),
-
-#undef U
-#undef O
-#undef A
-#undef K
-};
-
-const struct keywords_def config_conn_keywords = {
- .len = elemsof(config_conn_keyword),
- .item = config_conn_keyword,
-};
+++ /dev/null
-/* ipsec.conf's config setup for Libreswan
- *
- * Copyright (C) 2025 Andrew Cagney
- *
- * 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 <https://www.gnu.org/licenses/gpl2.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include <stdbool.h>
-
-#include "ipsecconf/config_setup.h"
-#include "ipsecconf/keywords.h"
-#include "ipsecconf/confread.h"
-#include "ipsecconf/parser.h"
-#include "passert.h"
-#include "lswalloc.h"
-#include "lset.h"
-#include "lmod.h"
-#include "lswlog.h"
-#include "lswversion.h"
-#include "ocsp_method.h"
-#include "global_redirect.h"
-#ifdef USE_SECCOMP
-#include "seccomp_mode.h"
-#endif
-#include "ddos_mode.h"
-#include "timescale.h"
-
-/**
- * Set up hardcoded defaults, from data in programs/pluto/constants.h
- *
- * @param cfg starter_config struct
- * @return void
- */
-
-static bool config_setup_is_set;
-static struct config_setup config_setup;
-
-void update_setup_string(enum config_setup_keyword kw, const char *string)
-{
- config_setup_singleton();
- passert(kw < elemsof(config_setup.values));
- struct keyword_value *kv = &config_setup.values[kw];
- pfreeany(kv->string);
- kv->string = clone_str(string, "kv");
- kv->set = k_set;
-}
-
-void update_setup_yn(enum config_setup_keyword kw, enum yn_options yn)
-{
- config_setup_singleton();
- passert(kw < elemsof(config_setup.values));
- struct keyword_value *kv = &config_setup.values[kw];
- kv->option = yn;
- kv->set = k_set;
-}
-
-void update_setup_deltatime(enum config_setup_keyword kw, deltatime_t deltatime)
-{
- config_setup_singleton();
- passert(kw < elemsof(config_setup.values));
- struct keyword_value *kv = &config_setup.values[kw];
- kv->deltatime = deltatime;
- kv->set = k_set;
-}
-
-void update_setup_option(enum config_setup_keyword kw, uintmax_t option)
-{
- config_setup_singleton();
- passert(kw < elemsof(config_setup.values));
- struct keyword_value *kv = &config_setup.values[kw];
- kv->option = option;
- kv->set = k_set;
-}
-
-const struct config_setup *config_setup_singleton(void)
-{
- if (!config_setup_is_set) {
- config_setup_is_set = true;
-
- /*
- * Note: these calls .set=k_set. The damage is undone
- * at the end.
- */
-
- update_setup_option(KBF_NHELPERS, -1);
-
- update_setup_option(KBF_DDOS_MODE, DDOS_AUTO);
- update_setup_option(KBF_DDOS_IKE_THRESHOLD, DEFAULT_IKE_SA_DDOS_THRESHOLD);
- update_setup_option(KBF_MAX_HALFOPEN_IKE, DEFAULT_MAXIMUM_HALFOPEN_IKE_SA);
-
- update_setup_option(KBF_IKEv1_POLICY, GLOBAL_IKEv1_DROP);
- update_setup_option(KBF_OCSP_CACHE_SIZE, OCSP_DEFAULT_CACHE_SIZE);
-#ifdef USE_SECCOMP
- update_setup_option(KBF_SECCOMP, SECCOMP_DISABLED);
-#endif
-
- update_setup_string(KSF_NSSDIR, IPSEC_NSSDIR);
- update_setup_string(KSF_SECRETSFILE, IPSEC_SECRETS);
- update_setup_string(KSF_DUMPDIR, IPSEC_RUNDIR);
- update_setup_string(KSF_IPSECDIR, IPSEC_CONFDDIR);
- update_setup_string(KSF_MYVENDORID, ipsec_version_vendorid());
-
- update_setup_string(KSF_DNSSEC_ROOTKEY_FILE, DEFAULT_DNSSEC_ROOTKEY_FILE);
- update_setup_yn(KYN_DNSSEC_ENABLE, YN_YES);
-
- update_setup_yn(KYN_LOGIP, YN_YES);
- update_setup_yn(KYN_LOGTIME, YN_YES);
- update_setup_yn(KYN_LOGAPPEND, YN_YES);
-#ifdef USE_LOGFILE
- update_setup_string(KSF_LOGFILE, LOGFILE);
-#endif
-
- update_setup_string(KSF_RUNDIR, IPSEC_RUNDIR);
-
- update_setup_deltatime(KBF_CRL_TIMEOUT_SECONDS, deltatime(5/*seconds*/));
-
- /* x509_ocsp */
- update_setup_deltatime(KBF_OCSP_TIMEOUT_SECONDS, deltatime(OCSP_DEFAULT_TIMEOUT));
- update_setup_deltatime(KBF_OCSP_CACHE_MIN_AGE_SECONDS, deltatime(OCSP_DEFAULT_CACHE_MIN_AGE));
- update_setup_deltatime(KBF_OCSP_CACHE_MAX_AGE_SECONDS, deltatime(OCSP_DEFAULT_CACHE_MAX_AGE));
- update_setup_option(KBF_OCSP_METHOD, OCSP_METHOD_GET);
- update_setup_option(KBF_OCSP_CACHE_SIZE, OCSP_DEFAULT_CACHE_SIZE);
-
- update_setup_yn(KYN_AUDIT_LOG, YN_YES);
- update_setup_yn(KYN_UNIQUEIDS, YN_YES);
-
- update_setup_deltatime(KSF_EXPIRE_SHUNT_INTERVAL, deltatime(DEFAULT_EXPIRE_SHUNT_INTERVAL_SECONDS));
- update_setup_deltatime(KBF_SHUNTLIFETIME, deltatime(DEFAULT_SHUNT_LIFETIME_SECONDS));
-
- update_setup_option(KBF_GLOBAL_REDIRECT, GLOBAL_REDIRECT_NO);
-
- update_setup_yn(KYN_IKE_SOCKET_ERRQUEUE, YN_YES);
- update_setup_option(KBF_IKE_SOCKET_BUFSIZE, 0); /*redundant*/
-
- update_setup_yn(KYN_LISTEN_UDP, YN_YES);
- update_setup_yn(KYN_LISTEN_TCP, YN_NO);
-
- update_setup_string(KSF_PROTOSTACK,
-#ifdef KERNEL_XFRM
- "xfrm"
-#endif
-#ifdef KERNEL_PFKEYV2
- "pfkeyv2"
-#endif
- );
-
- update_setup_string(KSF_DNS_RESOLVER, "file");
-
- /*
- * Clear .set, which is set by update_setup*(). Don't
- * use k_default as that is intended for 'conn
- * %default' section and seems to make for general
- * confusion.
- */
- FOR_EACH_ELEMENT(kv, config_setup.values) {
- kv->set = k_unset;
- }
-
- }
- return &config_setup;
-}
-
-void free_config_setup(void)
-{
- for (unsigned i = 0; i < elemsof(config_setup.values); i++) {
- pfreeany(config_setup.values[i].string);
- }
- config_setup_is_set = false;
-}
-
-const char *config_setup_string(const struct config_setup *setup,
- enum config_setup_keyword field)
-{
- passert(field < elemsof(setup->values));
- return setup->values[field].string;
-}
-
-const char *config_setup_string_or_unset(const struct config_setup *setup,
- enum config_setup_keyword field,
- const char *unset)
-{
- const char *string = config_setup_string(setup, field);
- if (string == NULL) {
- return unset;
- }
- return string;
-}
-
-bool config_setup_yn(const struct config_setup *setup,
- enum config_setup_keyword field)
-{
- passert(field < elemsof(setup->values));
- enum yn_options yn = setup->values[field].option;
- switch (yn) {
- case 0: return false;
- case YN_NO: return false;
- case YN_YES: return true;
- }
- bad_case(yn);
-}
-
-deltatime_t config_setup_deltatime(const struct config_setup *setup,
- enum config_setup_keyword field)
-{
- passert(field < elemsof(setup->values));
- return setup->values[field].deltatime;
-}
-
-uintmax_t config_setup_option(const struct config_setup *setup,
- enum config_setup_keyword field)
-{
- passert(field < elemsof(setup->values));
- /* being .set doesn't matter, as default is zero */
- return setup->values[field].option;
-}
-
-const char *config_setup_ipsecdir(void)
-{
- return config_setup_string(config_setup_singleton(), KSF_IPSECDIR);
-}
-
-const char *config_setup_secretsfile(void)
-{
- return config_setup_string(config_setup_singleton(), KSF_SECRETSFILE);
-}
-
-const char *config_setup_nssdir(void)
-{
- return config_setup_string(config_setup_singleton(), KSF_NSSDIR);
-}
-
-const char *config_setup_dumpdir(void)
-{
- return config_setup_string(config_setup_singleton(), KSF_DUMPDIR);
-}
-
-const char *config_setup_vendorid(void)
-{
- return config_setup_string(config_setup_singleton(), KSF_MYVENDORID);
-}
-
-lset_t config_setup_debugging(struct logger *logger)
-{
- /*
- * Use ttolmod() since it both knows how to parse a comma
- * separated list and can handle no-XXX (ex: all,no-xauth).
- * The final set of enabled bits is returned in .set.
- */
- lmod_t result = {0};
- const char *plutodebug = config_setup_string(config_setup_singleton(), KSF_PLUTODEBUG);
- if (!ttolmod(shunk1(plutodebug), &result, &debug_lmod_info, true/*enable*/)) {
- /*
- * If the lookup failed, complain.
- *
- * XXX: the error diagnostic is a little vague -
- * should lmod_arg() instead return the error?
- */
- llog(RC_LOG, logger, "plutodebug='%s' invalid, keyword ignored",
- plutodebug);
- return LEMPTY;
- }
-
- return result.set;
-}
-
-/**
- * Load a parsed config
- *
- * @param cfg starter_config structure
- * @param cfgp config_parsed (ie: valid) struct
- * @param perr pointer to store errors in
- */
-
-static void llog_bad(struct logger *logger, const struct ipsec_conf_keyval *kv, diag_t d)
-{
- llog(ERROR_STREAM, logger,
- PRI_KEYVAL_SAL": error: %s",
- pri_keyval_sal(kv), str_diag(d));
-}
-
-bool parse_ipsec_conf_config_setup(const struct ipsec_conf *cfgp,
- struct logger *logger)
-{
- config_setup_singleton();
-
- const struct keyval_entry *kw;
-
- TAILQ_FOREACH(kw, &cfgp->config_setup, next) {
- /**
- * the parser already made sure that only config keywords were used,
- * but we double check!
- */
- const struct ipsec_conf_keyval *kv = &kw->keyval;
- enum config_setup_keyword f = kv->key->field;
- shunk_t value = shunk1(kv->val);
- diag_t d = NULL;
-
- PASSERT(logger, f < elemsof(config_setup.values));
- if (config_setup.values[f].set) {
- llog(WARNING_STREAM, logger,
- PRI_KEYVAL_SAL": overriding earlier 'config setup' keyword with new value: %s=%s",
- pri_keyval_sal(kv),
- kv->key->keyname, kv->val);
- }
-
- switch (kv->key->type) {
- case kt_string:
- {
- /* all treated as strings for now */
- update_setup_string(f, kv->val);
- continue;
- }
-
- case kt_sparse_name:
- {
- uintmax_t number;
- d = parse_kt_sparse_name(kv, value, &number,
- ERROR_STREAM, logger);
- if (d != NULL) {
- llog_bad(logger, kv, d);
- pfree_diag(&d);
- return false;
- }
-
- update_setup_option(f, number);
- continue;
- }
-
- case kt_unsigned:
- {
- uintmax_t number;
- d = parse_kt_unsigned(kv, value, &number);
- if (d != NULL) {
- llog_bad(logger, kv, d);
- pfree_diag(&d);
- return false;
- }
-
- update_setup_option(f, number);
- continue;
- }
-
- case kt_seconds:
- {
- deltatime_t deltatime;
- d = parse_kt_deltatime(kv, value, &deltatime);
- if (d != NULL) {
- llog_bad(logger, kv, d);
- pfree_diag(&d);
- return false;
- }
-
- update_setup_deltatime(f, deltatime);
- continue;
- }
-
- case kt_obsolete:
- {
- llog(WARNING_STREAM, logger,
- PRI_KEYVAL_SAL": obsolete keyword ignored: %s=%s",
- pri_keyval_sal(kv), kv->key->keyname, kv->val);
- continue;
- }
-
- case kt_also:
- case kt_appendstring:
- case kt_appendlist:
- case kt_nosup:
- break;
-
- }
-
- bad_case(kv->key->type);
- }
-
- return true;
-}
-
-bool load_config_setup(const char *file,
- struct logger *logger,
- unsigned verbosity)
-{
-
- /*
- * Load file
- */
- struct ipsec_conf *ipsec_conf = alloc_ipsec_conf();
- if (!ipsec_conf_add_file(ipsec_conf, file, logger, verbosity)) {
- return false;
- }
-
- /**
- * Load setup
- */
- if (!parse_ipsec_conf_config_setup(ipsec_conf, logger)) {
- pfree_ipsec_conf(&ipsec_conf);
- return false;
- }
-
- pfree_ipsec_conf(&ipsec_conf);
- return true;
-}
-
-static const struct keyword_def config_setup_keyword[] = {
-#define K(KEYNAME, TYPE, FIELD, ...) [FIELD] = { .keyname = KEYNAME, .field = FIELD, .type = TYPE, ##__VA_ARGS__ }
-#define U(KEYNAME, TYPE, FIELD, ...) [FIELD] = { .keyname = KEYNAME, .field = FIELD, .type = kt_nosup, }
-
- K("ikev1-policy", kt_sparse_name, KBF_IKEv1_POLICY, .sparse_names = &global_ikev1_policy_names),
- K("curl-iface", kt_string, KSF_CURLIFACE),
-
- K("myvendorid", kt_string, KSF_MYVENDORID),
-
- K("plutodebug", kt_string, KSF_PLUTODEBUG),
-
- K("logfile", kt_string, KSF_LOGFILE),
- K("logtime", kt_sparse_name, KYN_LOGTIME, .sparse_names = &yn_option_names),
- K("logappend", kt_sparse_name, KYN_LOGAPPEND, .sparse_names = &yn_option_names),
- K("logip", kt_sparse_name, KYN_LOGIP, .sparse_names = &yn_option_names),
- K("audit-log", kt_sparse_name, KYN_AUDIT_LOG, .sparse_names = &yn_option_names),
-
-#ifdef USE_DNSSEC
-# define S K
-#else
-# define S U
-#endif
- S("dnssec-enable", kt_sparse_name, KYN_DNSSEC_ENABLE, .sparse_names = &yn_option_names),
- S("dnssec-rootkey-file", kt_string, KSF_DNSSEC_ROOTKEY_FILE),
- S("dnssec-anchors", kt_string, KSF_DNSSEC_ANCHORS),
-#undef S
-
- K("dumpdir", kt_string, KSF_DUMPDIR),
- K("ipsecdir", kt_string, KSF_IPSECDIR),
- K("nssdir", kt_string, KSF_NSSDIR),
-
- /* these are only allowed on the command line */
- K("rundir", kt_string, KSF_RUNDIR, .validity = kv_optarg_only),
- K("logstderr", kt_string, KYN_LOGSTDERR, .validity = kv_optarg_only),
-
- K("secretsfile", kt_string, KSF_SECRETSFILE),
- K("statsbin", kt_string, KSF_STATSBIN),
- K("uniqueids", kt_sparse_name, KYN_UNIQUEIDS, .sparse_names = &yn_option_names),
- K("shuntlifetime", kt_seconds, KBF_SHUNTLIFETIME),
-
- K("global-redirect", kt_sparse_name, KBF_GLOBAL_REDIRECT, .sparse_names = &global_redirect_names),
- K("global-redirect-to", kt_string, KSF_GLOBAL_REDIRECT_TO),
-
- K("crl-strict", kt_sparse_name, KYN_CRL_STRICT, .sparse_names = &yn_option_names),
- K("crlcheckinterval", kt_seconds, KBF_CRL_CHECKINTERVAL),
- K("crl-timeout", kt_seconds, KBF_CRL_TIMEOUT_SECONDS),
-
- K("ocsp-strict", kt_sparse_name, KYN_OCSP_STRICT, .sparse_names = &yn_option_names),
- K("ocsp-enable", kt_sparse_name, KYN_OCSP_ENABLE, .sparse_names = &yn_option_names),
- K("ocsp-uri", kt_string, KSF_OCSP_URI),
- K("ocsp-timeout", kt_seconds, KBF_OCSP_TIMEOUT_SECONDS),
- K("ocsp-trustname", kt_string, KSF_OCSP_TRUSTNAME),
- K("ocsp-cache-size", kt_unsigned, KBF_OCSP_CACHE_SIZE),
- K("ocsp-cache-min-age", kt_seconds, KBF_OCSP_CACHE_MIN_AGE_SECONDS),
- K("ocsp-cache-max-age", kt_seconds, KBF_OCSP_CACHE_MAX_AGE_SECONDS),
- K("ocsp-method", kt_sparse_name, KBF_OCSP_METHOD, .sparse_names = &ocsp_method_names),
-
-#ifdef USE_SECCOMP
-# define S K
-#else
-# define S U
-#endif
- S("seccomp", kt_sparse_name, KBF_SECCOMP, .sparse_names = &seccomp_mode_names),
-#undef S
-
- K("ddos-mode", kt_sparse_name, KBF_DDOS_MODE, .sparse_names = &ddos_mode_names),
- K("ddos-ike-threshold", kt_unsigned, KBF_DDOS_IKE_THRESHOLD),
- K("max-halfopen-ike", kt_unsigned, KBF_MAX_HALFOPEN_IKE),
-
- K("ike-socket-bufsize", kt_unsigned, KBF_IKE_SOCKET_BUFSIZE),
- K("ike-socket-errqueue", kt_sparse_name, KYN_IKE_SOCKET_ERRQUEUE, .sparse_names = &yn_option_names),
-
-#ifdef XFRM_LIFETIME_DEFAULT
-# define S K
-#else
-# define S U
-#endif
- S("expire-lifetime", kt_seconds, KBF_EXPIRE_LIFETIME),
-#undef S
-
- K("virtual-private", kt_string, KSF_VIRTUAL_PRIVATE),
- K("seedbits", kt_unsigned, KBF_SEEDBITS),
- K("keep-alive", kt_seconds, KBF_KEEP_ALIVE),
-
- K("listen-tcp", kt_sparse_name, KYN_LISTEN_TCP, .sparse_names = &yn_option_names),
- K("listen-udp", kt_sparse_name, KYN_LISTEN_UDP, .sparse_names = &yn_option_names),
-
- K("listen", kt_string, KSF_LISTEN),
- K("protostack", kt_string, KSF_PROTOSTACK),
- K("nhelpers", kt_unsigned, KBF_NHELPERS),
- K("drop-oppo-null", kt_sparse_name, KYN_DROP_OPPO_NULL, .sparse_names = &yn_option_names),
- K("expire-shunt-interval", kt_seconds, KSF_EXPIRE_SHUNT_INTERVAL),
-
- K("dns-resolver", kt_string, KSF_DNS_RESOLVER),
-
- K("ipsec-interface-managed", kt_sparse_name, KYN_IPSEC_INTERFACE_MANAGED, .sparse_names = &yn_option_names),
-
-#ifdef USE_NFLOG
-# define S K
-#else
-# define S U
-#endif
- S("nflog-all", kt_unsigned, KBF_NFLOG_ALL),
-#undef S
-
- /*
- * Force first alias/obsolete keyword into slot following all
- * defined keywords. Else compiler tries to store it into above
- * keyword's slot + 1, which is likely occupied by another keyword.
- * The result is a nonsensical error.
- */
- [CONFIG_SETUP_KEYWORD_ROOF] =
-
- /* alias for compatibility - undocumented on purpose */
-
-#define A(KEYNAME, TYPE, FIELD, ...) { .keyname = KEYNAME, .validity = kv_alias, .type = TYPE, .field = FIELD, ##__VA_ARGS__ }
-
- A("curl-timeout", kt_seconds, KBF_CRL_TIMEOUT_SECONDS), /* legacy */
-#ifdef XFRM_LIFETIME_DEFAULT
- A("xfrmlifetime", kt_seconds, KBF_EXPIRE_LIFETIME), /* legacy */
-#endif
-
- /* obsolete config setup options */
-
-#define O(KEYNAME, ...) { .keyname = KEYNAME, .type = kt_obsolete, }
-
- O("syslog"), /* never went anywhere! */
- O("plutostderrlog"), /* obsolete name, but very common :/ */
- O("virtual_private"), /* obsolete variant, very common */
- O("interfaces"), /* obsoleted but often present keyword */
- O("ikev1-secctx-attr-type"), /* obsolete: not a value, a type */
- O("secctx-attr-type"),
-
-#undef U
-#undef O
-#undef A
-#undef K
-};
-
-const struct keywords_def config_setup_keywords = {
- .len = elemsof(config_setup_keyword),
- .item = config_setup_keyword,
-};
#include "hunk.h" /* for char_is_space() */
#include "ip_cidr.h"
#include "ttodata.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#include "ipsecconf/parser.h"
#include "ipsecconf/confread.h"
--- /dev/null
+/*
+ * Libreswan config file parser (keywords.c)
+ * Copyright (C) 2003-2006 Michael Richardson <mcr@xelerance.com>
+ * Copyright (C) 2007-2010 Paul Wouters <paul@xelerance.com>
+ * Copyright (C) 2012 Paul Wouters <paul@libreswan.org>
+ * Copyright (C) 2013-2019 Paul Wouters <pwouters@redhat.com>
+ * Copyright (C) 2013-2019 D. Hugh Redelmeier <hugh@mimosa.com>
+ * Copyright (C) 2013 David McCullough <ucdevel@gmail.com>
+ * Copyright (C) 2013-2016 Antony Antony <antony@phenome.org>
+ * Copyright (C) 2016-2022 Andrew Cagney
+ * Copyright (C) 2017 Mayank Totale <mtotale@gmail.com>
+ * Copyright (C) 2020 Yulia Kuzovkova <ukuzovkova@gmail.com>
+ * Copyright (C) 2020 Nupur Agrawal <nupur202000@gmail.com>
+ *
+ * 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 <https://www.gnu.org/licenses/gpl2.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "constants.h" /* for yn_option_names; */
+#include "lswcdefs.h" /* for elemsof() */
+
+#include "ipsecconf/conn.h"
+#include "ipsecconf/keywords.h"
+#include "xauthby.h"
+#include "xauthfail.h"
+#include "shunt.h"
+#include "sparse_names.h"
+#include "encap_proto.h"
+
+/*
+ * Values for right= and left=
+ */
+
+static const struct keyword_def config_conn_keyword[] = {
+#define K(KEYNAME, VALIDITY, TYPE, FIELD, ...) [FIELD] = { .keyname = KEYNAME, .field = FIELD, .type = TYPE, .validity = VALIDITY, ##__VA_ARGS__ }
+#define U(KEYNAME, VALIDITY, TYPE, FIELD, ...) [FIELD] = { .keyname = KEYNAME, .field = FIELD, .type = kt_nosup, }
+
+ /*
+ * This is "left=" and "right="
+ */
+ K("", kv_leftright, kt_string, KWS_HOST),
+
+ K("debug", LEMPTY, kt_string, KWS_DEBUG),
+
+ K("subnet", kv_leftright, kt_string, KWS_SUBNET),
+ K("subnets", kv_leftright, kt_appendlist, KWS_SUBNETS),
+ K("sourceip", kv_leftright, kt_string, KWS_SOURCEIP),
+ K("ikeport", kv_leftright, kt_string, KWS_IKEPORT),
+ K("interface-ip", kv_leftright, kt_string, KWS_INTERFACE_IP),
+ K("vti", kv_leftright, kt_string, KWS_VTI),
+ K("nexthop", kv_leftright, kt_string, KWS_NEXTHOP),
+ K("updown", kv_leftright, kt_string, KWS_UPDOWN),
+ K("id", kv_leftright, kt_string, KWS_ID),
+
+ K("rsasigkey", kv_leftright, kt_string, KWS_RSASIGKEY),
+ K("ecdsakey", kv_leftright, kt_string, KWS_ECDSAKEY),
+ K("eddsakey", kv_leftright, kt_string, KWS_EDDSAKEY),
+ K("pubkey", kv_leftright, kt_string, KWS_PUBKEY),
+
+ K("cert", kv_leftright, kt_string, KWS_CERT),
+ K("ckaid", kv_leftright, kt_string, KWS_CKAID),
+ K("sendcert", kv_leftright, kt_string, KWS_SENDCERT),
+ K("ca", kv_leftright, kt_string, KWS_CA),
+ K("xauthserver", kv_leftright, kt_string, KWS_XAUTHSERVER),
+ K("xauthclient", kv_leftright, kt_string, KWS_XAUTHCLIENT),
+ K("modecfgserver", kv_leftright, kt_string, KWS_MODECFGSERVER),
+ K("modecfgclient", kv_leftright, kt_string, KWS_MODECFGCLIENT),
+ K("username", kv_leftright, kt_string, KWS_USERNAME),
+ K("addresspool", kv_leftright, kt_string, KWS_ADDRESSPOOL),
+ K("auth", kv_leftright, kt_string, KWS_AUTH),
+
+#ifdef USE_CAT
+# define S K
+#else
+# define S U
+#endif
+ S("cat", kv_leftright, kt_string, KWS_CAT),
+#undef S
+
+ K("protoport", kv_leftright, kt_string, KWS_PROTOPORT),
+ K("autheap", kv_leftright, kt_string, KWS_AUTHEAP),
+ K("groundhog", kv_leftright, kt_string, KWS_GROUNDHOG),
+
+ /* these are conn statements which are not left/right */
+
+ K("auto", LEMPTY, kt_sparse_name, KNCF_AUTO, .sparse_names = &autostart_names),
+ K("also", kv_duplicateok, kt_also, KSCF_ALSO),
+ K("hostaddrfamily", LEMPTY, kt_string, KWS_HOSTADDRFAMILY),
+ K("type", LEMPTY, kt_sparse_name, KNCF_TYPE, .sparse_names = &type_option_names),
+ K("authby", LEMPTY, kt_string, KWS_AUTHBY),
+ K("keyexchange", LEMPTY, kt_string, KWS_KEYEXCHANGE),
+ K("ikev2", LEMPTY, kt_string, KWS_IKEv2),
+ K("ppk", LEMPTY, kt_string, KWS_PPK),
+ K("ppk-ids", LEMPTY, kt_string, KWS_PPK_IDS),
+ K("intermediate", LEMPTY, kt_string, KWS_INTERMEDIATE),
+ K("esn", LEMPTY, kt_string, KWS_ESN),
+ K("decap-dscp", LEMPTY, kt_string, KWS_DECAP_DSCP),
+ K("encap-dscp", LEMPTY, kt_string, KWS_ENCAP_DSCP),
+ K("nopmtudisc", LEMPTY, kt_string, KWS_NOPMTUDISC),
+ K("fragmentation", LEMPTY, kt_string, KWS_FRAGMENTATION),
+ K("mobike", LEMPTY, kt_string, KWS_MOBIKE),
+ K("narrowing", LEMPTY, kt_string, KWS_NARROWING),
+ K("pam-authorize", LEMPTY, kt_string, KWS_PAM_AUTHORIZE),
+ K("send-redirect", LEMPTY, kt_string, KWS_SEND_REDIRECT),
+ K("redirect-to", LEMPTY, kt_string, KWS_REDIRECT_TO),
+ K("accept-redirect", LEMPTY, kt_string, KWS_ACCEPT_REDIRECT),
+ K("accept-redirect-to", LEMPTY, kt_string, KWS_ACCEPT_REDIRECT_TO),
+ K("pfs", LEMPTY, kt_string, KWS_PFS),
+ K("session-resumption", LEMPTY, kt_string, KWS_SESSION_RESUMPTION),
+
+ K("nat-keepalive", LEMPTY, kt_string, KWS_NAT_KEEPALIVE),
+
+ K("initial-contact", LEMPTY, kt_string, KWS_INITIAL_CONTACT),
+ K("send-esp-tfc-padding-not-supported", LEMPTY, kt_string, KWS_SEND_ESP_TFC_PADDING_NOT_SUPPORTED),
+ K("reject-simultaneous-ike-auth", LEMPTY, kt_string, KWS_REJECT_SIMULTANEOUS_IKE_AUTH),
+
+ K("iptfs", LEMPTY, kt_string, KWS_IPTFS),
+ K("iptfs-fragmentation", LEMPTY, kt_string, KWS_IPTFS_FRAGMENTATION),
+ K("iptfs-packet-size", LEMPTY, kt_string, KWS_IPTFS_PACKET_SIZE),
+ K("iptfs-max-queue-size", LEMPTY, kt_string, KWS_IPTFS_MAX_QUEUE_SIZE),
+ K("iptfs-reorder-window", LEMPTY, kt_string, KWS_IPTFS_REORDER_WINDOW),
+ K("iptfs-init-delay", LEMPTY, kt_string, KWS_IPTFS_INIT_DELAY),
+ K("iptfs-drop-time", LEMPTY, kt_string, KWS_IPTFS_DROP_TIME),
+
+ K("fake-strongswan", LEMPTY, kt_string, KWS_FAKE_STRONGSWAN),
+ K("send-vendorid", LEMPTY, kt_string, KWS_SEND_VENDORID),
+ K("sha2-truncbug", LEMPTY, kt_string, KWS_SHA2_TRUNCBUG),
+ K("share-lease", LEMPTY, kt_string, KWS_SHARE_LEASE),
+ K("ms-dh-downgrade", LEMPTY, kt_string, KWS_MS_DH_DOWNGRADE),
+ K("pfs-rekey-workaround", LEMPTY, kt_string, KWS_PFS_REKEY_WORKAROUND),
+ K("require-id-on-certificate", LEMPTY, kt_string, KWS_REQUIRE_ID_ON_CERTIFICATE),
+ K("dns-match-id,", LEMPTY, kt_string, KWS_DNS_MATCH_ID),
+ K("ipsec-max-bytes", LEMPTY, kt_string, KWS_IPSEC_MAX_BYTES),
+ K("ipsec-max-packets", LEMPTY, kt_string, KWS_IPSEC_MAX_PACKETS),
+ K("ipsec-lifetime", LEMPTY, kt_string, KWS_IPSEC_LIFETIME),
+
+ K("retransmit-timeout", LEMPTY, kt_string, KWS_RETRANSMIT_TIMEOUT),
+ K("retransmit-interval", LEMPTY, kt_string, KWS_RETRANSMIT_INTERVAL),
+
+ K("ikepad", LEMPTY, kt_string, KWS_IKEPAD),
+ K("nat-ikev1-method", LEMPTY, kt_string, KWS_NAT_IKEv1_METHOD),
+
+ K("sec-label", LEMPTY, kt_string, KWS_SEC_LABEL),
+
+ /* Cisco interop: remote peer type */
+ K("remote-peer-type", LEMPTY, kt_string, KWS_REMOTE_PEER_TYPE),
+ /* Network Manager support */
+ K("nm-configured", LEMPTY, kt_string, KWS_NM_CONFIGURED),
+ K("cisco-unity", LEMPTY, kt_string, KWS_CISCO_UNITY),
+ K("cisco-split", LEMPTY, kt_string, KWS_CISCO_SPLIT),
+
+ K("xauthby", LEMPTY, kt_string, KWS_XAUTHBY),
+ K("xauthfail", LEMPTY, kt_string, KWS_XAUTHFAIL),
+ K("modecfgpull", LEMPTY, kt_string, KWS_MODECFGPULL),
+ K("modecfgdns", LEMPTY, kt_string, KWS_MODECFGDNS),
+ K("modecfgdomains", LEMPTY, kt_string, KWS_MODECFGDOMAINS),
+ K("modecfgbanner", LEMPTY, kt_string, KWS_MODECFGBANNER),
+ K("ignore-peer-dns", LEMPTY, kt_string, KWS_IGNORE_PEER_DNS),
+
+ K("mark", LEMPTY, kt_string, KWS_MARK),
+ K("mark-in", LEMPTY, kt_string, KWS_MARK_IN),
+ K("mark-out", LEMPTY, kt_string, KWS_MARK_OUT),
+
+ K("vti-interface", LEMPTY, kt_string, KWS_VTI_INTERFACE),
+ K("vti-routing", LEMPTY, kt_string, KWS_VTI_ROUTING),
+ K("vti-shared", LEMPTY, kt_string, KWS_VTI_SHARED),
+
+ K("ipsec-interface", LEMPTY, kt_string, KWS_IPSEC_INTERFACE),
+
+ K("clones", LEMPTY, kt_string, KWS_CLONES),
+
+ K("nic-offload", LEMPTY, kt_string, KWS_NIC_OFFLOAD),
+
+ K("encapsulation", LEMPTY, kt_string, KWS_ENCAPSULATION),
+
+ K("overlapip", LEMPTY, kt_string, KWS_OVERLAPIP),
+ K("reauth", LEMPTY, kt_string, KWS_REAUTH),
+ K("rekey", LEMPTY, kt_string, KWS_REKEY),
+ K("rekeymargin", LEMPTY, kt_string, KWS_REKEYMARGIN),
+ K("rekeyfuzz", LEMPTY, kt_string, KWS_REKEYFUZZ),
+ K("replay-window", LEMPTY, kt_string, KWS_REPLAY_WINDOW),
+ K("ikelifetime", LEMPTY, kt_string, KWS_IKELIFETIME),
+ K("failureshunt", LEMPTY, kt_sparse_name, KNCF_FAILURESHUNT, .sparse_names = &failure_shunt_names),
+ K("negotiationshunt", LEMPTY, kt_sparse_name, KNCF_NEGOTIATIONSHUNT, .sparse_names = &negotiation_shunt_names),
+
+ K("enable-tcp", LEMPTY, kt_string, KWS_ENABLE_TCP),
+ K("tcp-remoteport", LEMPTY, kt_string, KWS_TCP_REMOTEPORT),
+
+ K("connalias", LEMPTY, kt_appendstring, KWS_CONNALIAS),
+
+ /* attributes of the phase1 policy */
+ K("ike", LEMPTY, kt_string, KWS_IKE),
+ /* attributes of the phase2 policy */
+ K("esp", LEMPTY, kt_string, KWS_ESP),
+ K("ah", LEMPTY, kt_string, KWS_AH),
+ K("phase2", LEMPTY, kt_string, KWS_PHASE2),
+ K("phase2alg", LEMPTY, kt_string, KWS_PHASE2ALG),
+
+ K("compress", LEMPTY, kt_string, KWS_COMPRESS),
+
+ /* route metric */
+ K("metric", LEMPTY, kt_string, KWS_METRIC),
+
+ /* DPD */
+ K("dpddelay", LEMPTY, kt_string, KWS_DPDDELAY),
+ K("ikev1-dpdtimeout", LEMPTY, kt_string, KWS_DPDTIMEOUT),
+
+ K("sendca", LEMPTY, kt_string, KWS_SENDCA),
+
+ K("mtu", LEMPTY, kt_string, KWS_MTU),
+ K("priority", LEMPTY, kt_string, KWS_PRIORITY),
+ K("tfc", LEMPTY, kt_string, KWS_TFC),
+ K("reqid", LEMPTY, kt_string, KWS_REQID),
+
+#ifdef USE_NFLOG
+# define S K
+#else
+# define S U
+#endif
+ S("nflog-group", LEMPTY, kt_string, KWS_NFLOG_GROUP),
+#undef S
+
+ K("aggressive", LEMPTY, kt_string, KWS_AGGRESSIVE),
+
+ /*
+ * Force first alias/obsolete keyword into slot following all
+ * defined keywords. Else compiler tries to store it into above
+ * keyword's slot + 1, which is likely occupied by another keyword.
+ * The result is a nonsensical error.
+ */
+ [CONFIG_CONN_KEYWORD_ROOF] =
+
+ /* alias for compatibility - undocumented on purpose */
+
+#define A(KEYNAME, VALIDITY, TYPE, FIELD, ...) { .keyname = KEYNAME, .validity = VALIDITY|kv_alias, .type = TYPE, .field = FIELD, ##__VA_ARGS__ }
+
+ A("aggrmode", LEMPTY, kt_string, KWS_AGGRESSIVE),
+ A("keylife", LEMPTY, kt_string, KWS_IPSEC_LIFETIME), /* old name */
+ A("lifetime", LEMPTY, kt_string, KWS_IPSEC_LIFETIME), /* old name */
+ A("phase2alg", LEMPTY, kt_string, KWS_ESP), /* obsolete */
+ A("dpdtimeout", LEMPTY, kt_string, KWS_DPDTIMEOUT), /* old name */
+#ifdef USE_NFLOG
+ A("nflog", LEMPTY, kt_string, KWS_NFLOG_GROUP), /* old-name */
+#endif
+ A("salifetime", LEMPTY, kt_string, KWS_IPSEC_LIFETIME), /* old name */
+ /* xauthusername is still used in NetworkManager-libreswan :/ */
+ A("xauthusername", kv_leftright, kt_string, KWS_USERNAME), /* old alias */
+ A("ah", LEMPTY, kt_string, KWS_ESP),
+ A("policy-label", LEMPTY, kt_string, KWS_SEC_LABEL), /* obsolete variant */
+ /* another alias used by NetworkManager-libreswan :/ */
+ A("remote_peer_type", LEMPTY, kt_string, KWS_REMOTE_PEER_TYPE),
+ A("send-no-esp-tfc", LEMPTY, kt_string, KWS_SEND_ESP_TFC_PADDING_NOT_SUPPORTED), /*compat, but forever*/
+
+ /* obsolete config setup options */
+
+#define O(KEYNAME, ...) { .keyname = KEYNAME, .type = kt_obsolete, }
+
+ O("dpdaction"),
+ O("clientaddrfamily"),
+ O("keyingtries"),
+
+#undef U
+#undef O
+#undef A
+#undef K
+};
+
+const struct keywords_def config_conn_keywords = {
+ .len = elemsof(config_conn_keyword),
+ .item = config_conn_keyword,
+};
*/
#include "ipsecconf/keywords.h"
-#include "ipsecconf/config_setup.h"
-#include "ipsecconf/config_conn.h"
+#include "ipsecconf/setup.h"
+#include "ipsecconf/conn.h"
#include "lswlog.h"
#include "lswalloc.h"
--- /dev/null
+/* ipsec.conf's config setup for Libreswan
+ *
+ * Copyright (C) 2025 Andrew Cagney
+ *
+ * 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 <https://www.gnu.org/licenses/gpl2.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include <stdbool.h>
+
+#include "ipsecconf/setup.h"
+#include "ipsecconf/keywords.h"
+#include "ipsecconf/confread.h"
+#include "ipsecconf/parser.h"
+#include "passert.h"
+#include "lswalloc.h"
+#include "lset.h"
+#include "lmod.h"
+#include "lswlog.h"
+#include "lswversion.h"
+#include "ocsp_method.h"
+#include "global_redirect.h"
+#ifdef USE_SECCOMP
+#include "seccomp_mode.h"
+#endif
+#include "ddos_mode.h"
+#include "timescale.h"
+
+/**
+ * Set up hardcoded defaults, from data in programs/pluto/constants.h
+ *
+ * @param cfg starter_config struct
+ * @return void
+ */
+
+static bool config_setup_is_set;
+static struct config_setup config_setup;
+
+void update_setup_string(enum config_setup_keyword kw, const char *string)
+{
+ config_setup_singleton();
+ passert(kw < elemsof(config_setup.values));
+ struct keyword_value *kv = &config_setup.values[kw];
+ pfreeany(kv->string);
+ kv->string = clone_str(string, "kv");
+ kv->set = k_set;
+}
+
+void update_setup_yn(enum config_setup_keyword kw, enum yn_options yn)
+{
+ config_setup_singleton();
+ passert(kw < elemsof(config_setup.values));
+ struct keyword_value *kv = &config_setup.values[kw];
+ kv->option = yn;
+ kv->set = k_set;
+}
+
+void update_setup_deltatime(enum config_setup_keyword kw, deltatime_t deltatime)
+{
+ config_setup_singleton();
+ passert(kw < elemsof(config_setup.values));
+ struct keyword_value *kv = &config_setup.values[kw];
+ kv->deltatime = deltatime;
+ kv->set = k_set;
+}
+
+void update_setup_option(enum config_setup_keyword kw, uintmax_t option)
+{
+ config_setup_singleton();
+ passert(kw < elemsof(config_setup.values));
+ struct keyword_value *kv = &config_setup.values[kw];
+ kv->option = option;
+ kv->set = k_set;
+}
+
+const struct config_setup *config_setup_singleton(void)
+{
+ if (!config_setup_is_set) {
+ config_setup_is_set = true;
+
+ /*
+ * Note: these calls .set=k_set. The damage is undone
+ * at the end.
+ */
+
+ update_setup_option(KBF_NHELPERS, -1);
+
+ update_setup_option(KBF_DDOS_MODE, DDOS_AUTO);
+ update_setup_option(KBF_DDOS_IKE_THRESHOLD, DEFAULT_IKE_SA_DDOS_THRESHOLD);
+ update_setup_option(KBF_MAX_HALFOPEN_IKE, DEFAULT_MAXIMUM_HALFOPEN_IKE_SA);
+
+ update_setup_option(KBF_IKEv1_POLICY, GLOBAL_IKEv1_DROP);
+ update_setup_option(KBF_OCSP_CACHE_SIZE, OCSP_DEFAULT_CACHE_SIZE);
+#ifdef USE_SECCOMP
+ update_setup_option(KBF_SECCOMP, SECCOMP_DISABLED);
+#endif
+
+ update_setup_string(KSF_NSSDIR, IPSEC_NSSDIR);
+ update_setup_string(KSF_SECRETSFILE, IPSEC_SECRETS);
+ update_setup_string(KSF_DUMPDIR, IPSEC_RUNDIR);
+ update_setup_string(KSF_IPSECDIR, IPSEC_CONFDDIR);
+ update_setup_string(KSF_MYVENDORID, ipsec_version_vendorid());
+
+ update_setup_string(KSF_DNSSEC_ROOTKEY_FILE, DEFAULT_DNSSEC_ROOTKEY_FILE);
+ update_setup_yn(KYN_DNSSEC_ENABLE, YN_YES);
+
+ update_setup_yn(KYN_LOGIP, YN_YES);
+ update_setup_yn(KYN_LOGTIME, YN_YES);
+ update_setup_yn(KYN_LOGAPPEND, YN_YES);
+#ifdef USE_LOGFILE
+ update_setup_string(KSF_LOGFILE, LOGFILE);
+#endif
+
+ update_setup_string(KSF_RUNDIR, IPSEC_RUNDIR);
+
+ update_setup_deltatime(KBF_CRL_TIMEOUT_SECONDS, deltatime(5/*seconds*/));
+
+ /* x509_ocsp */
+ update_setup_deltatime(KBF_OCSP_TIMEOUT_SECONDS, deltatime(OCSP_DEFAULT_TIMEOUT));
+ update_setup_deltatime(KBF_OCSP_CACHE_MIN_AGE_SECONDS, deltatime(OCSP_DEFAULT_CACHE_MIN_AGE));
+ update_setup_deltatime(KBF_OCSP_CACHE_MAX_AGE_SECONDS, deltatime(OCSP_DEFAULT_CACHE_MAX_AGE));
+ update_setup_option(KBF_OCSP_METHOD, OCSP_METHOD_GET);
+ update_setup_option(KBF_OCSP_CACHE_SIZE, OCSP_DEFAULT_CACHE_SIZE);
+
+ update_setup_yn(KYN_AUDIT_LOG, YN_YES);
+ update_setup_yn(KYN_UNIQUEIDS, YN_YES);
+
+ update_setup_deltatime(KSF_EXPIRE_SHUNT_INTERVAL, deltatime(DEFAULT_EXPIRE_SHUNT_INTERVAL_SECONDS));
+ update_setup_deltatime(KBF_SHUNTLIFETIME, deltatime(DEFAULT_SHUNT_LIFETIME_SECONDS));
+
+ update_setup_option(KBF_GLOBAL_REDIRECT, GLOBAL_REDIRECT_NO);
+
+ update_setup_yn(KYN_IKE_SOCKET_ERRQUEUE, YN_YES);
+ update_setup_option(KBF_IKE_SOCKET_BUFSIZE, 0); /*redundant*/
+
+ update_setup_yn(KYN_LISTEN_UDP, YN_YES);
+ update_setup_yn(KYN_LISTEN_TCP, YN_NO);
+
+ update_setup_string(KSF_PROTOSTACK,
+#ifdef KERNEL_XFRM
+ "xfrm"
+#endif
+#ifdef KERNEL_PFKEYV2
+ "pfkeyv2"
+#endif
+ );
+
+ update_setup_string(KSF_DNS_RESOLVER, "file");
+
+ /*
+ * Clear .set, which is set by update_setup*(). Don't
+ * use k_default as that is intended for 'conn
+ * %default' section and seems to make for general
+ * confusion.
+ */
+ FOR_EACH_ELEMENT(kv, config_setup.values) {
+ kv->set = k_unset;
+ }
+
+ }
+ return &config_setup;
+}
+
+void free_config_setup(void)
+{
+ for (unsigned i = 0; i < elemsof(config_setup.values); i++) {
+ pfreeany(config_setup.values[i].string);
+ }
+ config_setup_is_set = false;
+}
+
+const char *config_setup_string(const struct config_setup *setup,
+ enum config_setup_keyword field)
+{
+ passert(field < elemsof(setup->values));
+ return setup->values[field].string;
+}
+
+const char *config_setup_string_or_unset(const struct config_setup *setup,
+ enum config_setup_keyword field,
+ const char *unset)
+{
+ const char *string = config_setup_string(setup, field);
+ if (string == NULL) {
+ return unset;
+ }
+ return string;
+}
+
+bool config_setup_yn(const struct config_setup *setup,
+ enum config_setup_keyword field)
+{
+ passert(field < elemsof(setup->values));
+ enum yn_options yn = setup->values[field].option;
+ switch (yn) {
+ case 0: return false;
+ case YN_NO: return false;
+ case YN_YES: return true;
+ }
+ bad_case(yn);
+}
+
+deltatime_t config_setup_deltatime(const struct config_setup *setup,
+ enum config_setup_keyword field)
+{
+ passert(field < elemsof(setup->values));
+ return setup->values[field].deltatime;
+}
+
+uintmax_t config_setup_option(const struct config_setup *setup,
+ enum config_setup_keyword field)
+{
+ passert(field < elemsof(setup->values));
+ /* being .set doesn't matter, as default is zero */
+ return setup->values[field].option;
+}
+
+const char *config_setup_ipsecdir(void)
+{
+ return config_setup_string(config_setup_singleton(), KSF_IPSECDIR);
+}
+
+const char *config_setup_secretsfile(void)
+{
+ return config_setup_string(config_setup_singleton(), KSF_SECRETSFILE);
+}
+
+const char *config_setup_nssdir(void)
+{
+ return config_setup_string(config_setup_singleton(), KSF_NSSDIR);
+}
+
+const char *config_setup_dumpdir(void)
+{
+ return config_setup_string(config_setup_singleton(), KSF_DUMPDIR);
+}
+
+const char *config_setup_vendorid(void)
+{
+ return config_setup_string(config_setup_singleton(), KSF_MYVENDORID);
+}
+
+lset_t config_setup_debugging(struct logger *logger)
+{
+ /*
+ * Use ttolmod() since it both knows how to parse a comma
+ * separated list and can handle no-XXX (ex: all,no-xauth).
+ * The final set of enabled bits is returned in .set.
+ */
+ lmod_t result = {0};
+ const char *plutodebug = config_setup_string(config_setup_singleton(), KSF_PLUTODEBUG);
+ if (!ttolmod(shunk1(plutodebug), &result, &debug_lmod_info, true/*enable*/)) {
+ /*
+ * If the lookup failed, complain.
+ *
+ * XXX: the error diagnostic is a little vague -
+ * should lmod_arg() instead return the error?
+ */
+ llog(RC_LOG, logger, "plutodebug='%s' invalid, keyword ignored",
+ plutodebug);
+ return LEMPTY;
+ }
+
+ return result.set;
+}
+
+/**
+ * Load a parsed config
+ *
+ * @param cfg starter_config structure
+ * @param cfgp config_parsed (ie: valid) struct
+ * @param perr pointer to store errors in
+ */
+
+static void llog_bad(struct logger *logger, const struct ipsec_conf_keyval *kv, diag_t d)
+{
+ llog(ERROR_STREAM, logger,
+ PRI_KEYVAL_SAL": error: %s",
+ pri_keyval_sal(kv), str_diag(d));
+}
+
+bool parse_ipsec_conf_config_setup(const struct ipsec_conf *cfgp,
+ struct logger *logger)
+{
+ config_setup_singleton();
+
+ const struct keyval_entry *kw;
+
+ TAILQ_FOREACH(kw, &cfgp->config_setup, next) {
+ /**
+ * the parser already made sure that only config keywords were used,
+ * but we double check!
+ */
+ const struct ipsec_conf_keyval *kv = &kw->keyval;
+ enum config_setup_keyword f = kv->key->field;
+ shunk_t value = shunk1(kv->val);
+ diag_t d = NULL;
+
+ PASSERT(logger, f < elemsof(config_setup.values));
+ if (config_setup.values[f].set) {
+ llog(WARNING_STREAM, logger,
+ PRI_KEYVAL_SAL": overriding earlier 'config setup' keyword with new value: %s=%s",
+ pri_keyval_sal(kv),
+ kv->key->keyname, kv->val);
+ }
+
+ switch (kv->key->type) {
+ case kt_string:
+ {
+ /* all treated as strings for now */
+ update_setup_string(f, kv->val);
+ continue;
+ }
+
+ case kt_sparse_name:
+ {
+ uintmax_t number;
+ d = parse_kt_sparse_name(kv, value, &number,
+ ERROR_STREAM, logger);
+ if (d != NULL) {
+ llog_bad(logger, kv, d);
+ pfree_diag(&d);
+ return false;
+ }
+
+ update_setup_option(f, number);
+ continue;
+ }
+
+ case kt_unsigned:
+ {
+ uintmax_t number;
+ d = parse_kt_unsigned(kv, value, &number);
+ if (d != NULL) {
+ llog_bad(logger, kv, d);
+ pfree_diag(&d);
+ return false;
+ }
+
+ update_setup_option(f, number);
+ continue;
+ }
+
+ case kt_seconds:
+ {
+ deltatime_t deltatime;
+ d = parse_kt_deltatime(kv, value, &deltatime);
+ if (d != NULL) {
+ llog_bad(logger, kv, d);
+ pfree_diag(&d);
+ return false;
+ }
+
+ update_setup_deltatime(f, deltatime);
+ continue;
+ }
+
+ case kt_obsolete:
+ {
+ llog(WARNING_STREAM, logger,
+ PRI_KEYVAL_SAL": obsolete keyword ignored: %s=%s",
+ pri_keyval_sal(kv), kv->key->keyname, kv->val);
+ continue;
+ }
+
+ case kt_also:
+ case kt_appendstring:
+ case kt_appendlist:
+ case kt_nosup:
+ break;
+
+ }
+
+ bad_case(kv->key->type);
+ }
+
+ return true;
+}
+
+bool load_config_setup(const char *file,
+ struct logger *logger,
+ unsigned verbosity)
+{
+
+ /*
+ * Load file
+ */
+ struct ipsec_conf *ipsec_conf = alloc_ipsec_conf();
+ if (!ipsec_conf_add_file(ipsec_conf, file, logger, verbosity)) {
+ return false;
+ }
+
+ /**
+ * Load setup
+ */
+ if (!parse_ipsec_conf_config_setup(ipsec_conf, logger)) {
+ pfree_ipsec_conf(&ipsec_conf);
+ return false;
+ }
+
+ pfree_ipsec_conf(&ipsec_conf);
+ return true;
+}
+
+static const struct keyword_def config_setup_keyword[] = {
+#define K(KEYNAME, TYPE, FIELD, ...) [FIELD] = { .keyname = KEYNAME, .field = FIELD, .type = TYPE, ##__VA_ARGS__ }
+#define U(KEYNAME, TYPE, FIELD, ...) [FIELD] = { .keyname = KEYNAME, .field = FIELD, .type = kt_nosup, }
+
+ K("ikev1-policy", kt_sparse_name, KBF_IKEv1_POLICY, .sparse_names = &global_ikev1_policy_names),
+ K("curl-iface", kt_string, KSF_CURLIFACE),
+
+ K("myvendorid", kt_string, KSF_MYVENDORID),
+
+ K("plutodebug", kt_string, KSF_PLUTODEBUG),
+
+ K("logfile", kt_string, KSF_LOGFILE),
+ K("logtime", kt_sparse_name, KYN_LOGTIME, .sparse_names = &yn_option_names),
+ K("logappend", kt_sparse_name, KYN_LOGAPPEND, .sparse_names = &yn_option_names),
+ K("logip", kt_sparse_name, KYN_LOGIP, .sparse_names = &yn_option_names),
+ K("audit-log", kt_sparse_name, KYN_AUDIT_LOG, .sparse_names = &yn_option_names),
+
+#ifdef USE_DNSSEC
+# define S K
+#else
+# define S U
+#endif
+ S("dnssec-enable", kt_sparse_name, KYN_DNSSEC_ENABLE, .sparse_names = &yn_option_names),
+ S("dnssec-rootkey-file", kt_string, KSF_DNSSEC_ROOTKEY_FILE),
+ S("dnssec-anchors", kt_string, KSF_DNSSEC_ANCHORS),
+#undef S
+
+ K("dumpdir", kt_string, KSF_DUMPDIR),
+ K("ipsecdir", kt_string, KSF_IPSECDIR),
+ K("nssdir", kt_string, KSF_NSSDIR),
+
+ /* these are only allowed on the command line */
+ K("rundir", kt_string, KSF_RUNDIR, .validity = kv_optarg_only),
+ K("logstderr", kt_string, KYN_LOGSTDERR, .validity = kv_optarg_only),
+
+ K("secretsfile", kt_string, KSF_SECRETSFILE),
+ K("statsbin", kt_string, KSF_STATSBIN),
+ K("uniqueids", kt_sparse_name, KYN_UNIQUEIDS, .sparse_names = &yn_option_names),
+ K("shuntlifetime", kt_seconds, KBF_SHUNTLIFETIME),
+
+ K("global-redirect", kt_sparse_name, KBF_GLOBAL_REDIRECT, .sparse_names = &global_redirect_names),
+ K("global-redirect-to", kt_string, KSF_GLOBAL_REDIRECT_TO),
+
+ K("crl-strict", kt_sparse_name, KYN_CRL_STRICT, .sparse_names = &yn_option_names),
+ K("crlcheckinterval", kt_seconds, KBF_CRL_CHECKINTERVAL),
+ K("crl-timeout", kt_seconds, KBF_CRL_TIMEOUT_SECONDS),
+
+ K("ocsp-strict", kt_sparse_name, KYN_OCSP_STRICT, .sparse_names = &yn_option_names),
+ K("ocsp-enable", kt_sparse_name, KYN_OCSP_ENABLE, .sparse_names = &yn_option_names),
+ K("ocsp-uri", kt_string, KSF_OCSP_URI),
+ K("ocsp-timeout", kt_seconds, KBF_OCSP_TIMEOUT_SECONDS),
+ K("ocsp-trustname", kt_string, KSF_OCSP_TRUSTNAME),
+ K("ocsp-cache-size", kt_unsigned, KBF_OCSP_CACHE_SIZE),
+ K("ocsp-cache-min-age", kt_seconds, KBF_OCSP_CACHE_MIN_AGE_SECONDS),
+ K("ocsp-cache-max-age", kt_seconds, KBF_OCSP_CACHE_MAX_AGE_SECONDS),
+ K("ocsp-method", kt_sparse_name, KBF_OCSP_METHOD, .sparse_names = &ocsp_method_names),
+
+#ifdef USE_SECCOMP
+# define S K
+#else
+# define S U
+#endif
+ S("seccomp", kt_sparse_name, KBF_SECCOMP, .sparse_names = &seccomp_mode_names),
+#undef S
+
+ K("ddos-mode", kt_sparse_name, KBF_DDOS_MODE, .sparse_names = &ddos_mode_names),
+ K("ddos-ike-threshold", kt_unsigned, KBF_DDOS_IKE_THRESHOLD),
+ K("max-halfopen-ike", kt_unsigned, KBF_MAX_HALFOPEN_IKE),
+
+ K("ike-socket-bufsize", kt_unsigned, KBF_IKE_SOCKET_BUFSIZE),
+ K("ike-socket-errqueue", kt_sparse_name, KYN_IKE_SOCKET_ERRQUEUE, .sparse_names = &yn_option_names),
+
+#ifdef XFRM_LIFETIME_DEFAULT
+# define S K
+#else
+# define S U
+#endif
+ S("expire-lifetime", kt_seconds, KBF_EXPIRE_LIFETIME),
+#undef S
+
+ K("virtual-private", kt_string, KSF_VIRTUAL_PRIVATE),
+ K("seedbits", kt_unsigned, KBF_SEEDBITS),
+ K("keep-alive", kt_seconds, KBF_KEEP_ALIVE),
+
+ K("listen-tcp", kt_sparse_name, KYN_LISTEN_TCP, .sparse_names = &yn_option_names),
+ K("listen-udp", kt_sparse_name, KYN_LISTEN_UDP, .sparse_names = &yn_option_names),
+
+ K("listen", kt_string, KSF_LISTEN),
+ K("protostack", kt_string, KSF_PROTOSTACK),
+ K("nhelpers", kt_unsigned, KBF_NHELPERS),
+ K("drop-oppo-null", kt_sparse_name, KYN_DROP_OPPO_NULL, .sparse_names = &yn_option_names),
+ K("expire-shunt-interval", kt_seconds, KSF_EXPIRE_SHUNT_INTERVAL),
+
+ K("dns-resolver", kt_string, KSF_DNS_RESOLVER),
+
+ K("ipsec-interface-managed", kt_sparse_name, KYN_IPSEC_INTERFACE_MANAGED, .sparse_names = &yn_option_names),
+
+#ifdef USE_NFLOG
+# define S K
+#else
+# define S U
+#endif
+ S("nflog-all", kt_unsigned, KBF_NFLOG_ALL),
+#undef S
+
+ /*
+ * Force first alias/obsolete keyword into slot following all
+ * defined keywords. Else compiler tries to store it into above
+ * keyword's slot + 1, which is likely occupied by another keyword.
+ * The result is a nonsensical error.
+ */
+ [CONFIG_SETUP_KEYWORD_ROOF] =
+
+ /* alias for compatibility - undocumented on purpose */
+
+#define A(KEYNAME, TYPE, FIELD, ...) { .keyname = KEYNAME, .validity = kv_alias, .type = TYPE, .field = FIELD, ##__VA_ARGS__ }
+
+ A("curl-timeout", kt_seconds, KBF_CRL_TIMEOUT_SECONDS), /* legacy */
+#ifdef XFRM_LIFETIME_DEFAULT
+ A("xfrmlifetime", kt_seconds, KBF_EXPIRE_LIFETIME), /* legacy */
+#endif
+
+ /* obsolete config setup options */
+
+#define O(KEYNAME, ...) { .keyname = KEYNAME, .type = kt_obsolete, }
+
+ O("syslog"), /* never went anywhere! */
+ O("plutostderrlog"), /* obsolete name, but very common :/ */
+ O("virtual_private"), /* obsolete variant, very common */
+ O("interfaces"), /* obsoleted but often present keyword */
+ O("ikev1-secctx-attr-type"), /* obsolete: not a value, a type */
+ O("secctx-attr-type"),
+
+#undef U
+#undef O
+#undef A
+#undef K
+};
+
+const struct keywords_def config_setup_keywords = {
+ .len = elemsof(config_setup_keyword),
+ .item = config_setup_keyword,
+};
#include <keyhi.h>
#include <nss.h> /* for NSS_Initialize() */
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#include "lswnss.h"
#include "lswalloc.h"
#include "lswlog.h"
#include "import_crl.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#include "lswnss.h"
#include "lswtool.h"
#include "lswalloc.h"
#include "lswalloc.h"
#include "lswtool.h"
#include "whack.h"
-#include "ipsecconf/config_setup.h"
-#include "ipsecconf/config_conn.h"
+#include "ipsecconf/setup.h"
+#include "ipsecconf/conn.h"
#include "ipsecconf/keywords.h"
#include "ipsecconf/confread.h"
#include "ipsecconf/confwrite.h"
#include "lswtool.h"
#include "lswnss.h"
#include "ipsecconf/keywords.h" /* for KSF_NSSDIR */
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#ifndef DEVICE
# define DEVICE "/dev/random"
#include "lswtool.h"
#include "lswnss.h"
#include "ipsecconf/keywords.h" /* for KSF_NSSDIR */
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#ifndef DEVICE
# define DEVICE "/dev/random"
#ifdef USE_SECCOMP
#include "pluto_seccomp.h"
#endif
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
const char *pluto_stats_binary; /* see init_binlog() */
#include "whack_pubkey.h"
#include "binaryscale-iec-60027-2.h"
#include "defaultroute.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#include "extract.h"
static void discard_connection(struct connection **cp, bool connection_valid, where_t where);
#include "ddos.h"
#include "constants.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#include "defs.h"
#include "log.h"
#include "log_limiter.h"
#include "ikev1_notification.h"
#include "ikev2_notification.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
static enum global_ikev1_policy global_ikev1_policy; /* see init_demux() */
static callback_cb handle_md_event; /* type assertion */
#include "passert.h"
#include "ipsecconf/interfaces.h"
#include "nss_cert_load.h"
-#include "ipsecconf/config_conn.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/conn.h"
+#include "ipsecconf/setup.h"
#include "scale.h"
#include "deltatime.h"
#include "timescale.h"
#include "connections.h" /* needs id.h */
#include "foodgroups.h"
#include "kernel.h" /* needs connections.h */
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#include "lex.h"
#include "log.h"
#include "whack.h"
#endif
#include "lsw_socket.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#include "defs.h"
#include "ikev1_vendorid.h"
#include "demux.h"
#include "connections.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
/*
* Handle IKEv1 Known VendorID's. This function parses what the remote peer
#include "lswalloc.h"
#include "sysdep.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#include "constants.h"
#include "defs.h"
#include "ikev2_prf.h"
#include "crypt_symkey.h"
#include "ikev2_notification.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#include "ikev2_ke.h"
static ke_and_nonce_cb initiate_v2_IKE_SA_INIT_request_continue; /* type assertion */
#include "sysdep.h"
#include "constants.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#include "defs.h"
#include "rnd.h"
#include "lsw_socket.h"
#include "constants.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#include "defs.h"
#include "id.h"
#include <secerr.h>
#include <secport.h>
#include <time.h>
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#include "lswnss.h"
#include "secrets.h"
#include "ike_alg_hash.h"
#include "lock_file.h"
#include "lswalloc.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#include "defs.h" /* for so_serial_t */
#include "log.h"
#include "demux.h" /* for struct msg_digest */
#include "pending.h"
#include "show.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
static refcnt_discard_content_fn discard_logger_content;
static struct fd *logger_fd(const struct logger *logger);
#include <unistd.h>
#include "lswseccomp.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#include "defs.h"
#include "log.h"
#include "keys.h"
#include "secrets.h" /* for free_remembered_public_keys() */
#include "hourly.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#include "ipsecconf/confread.h"
#include "crypto.h"
#include "vendorid.h"
#include "pluto_stats.h" /* for whack_clear_stats() et.al. */
#include "server_fork.h" /* for show_process_status() */
#include "ddns.h" /* for connection_check_ddns() */
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#include "ddos.h"
#include "visit_connection.h"
#include "lsw_socket.h"
#include "constants.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#include "defs.h"
#include "state.h"
#include "id.h"
#include "ikev2_states.h"
#include "crypt_cipher.h" /* for cipher_context_destroy() */
#include "ddos.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
static void delete_state(struct state *st);
#include "spd_db.h" /* for check_spd_db() */
#include "server_fork.h" /* for check_server_fork() */
#include "ikev2_redirect.h" /* for free_global_redirect_dests() */
-#include "ipsecconf/config_setup.h" /* for free_config_setup() */
+#include "ipsecconf/setup.h" /* for free_config_setup() */
#include "ikev2_ipseckey.h" /* for shutdown_ikev2_ipseckey() */
#include "pending.h"
#include "connection_event.h"
#include "sysdep.h"
#include "constants.h"
#include "fips_mode.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#include "defs.h"
#include "log.h"
#include "timer.h"
#include "keys.h" /* for pluto_pubkeys; */
#include "server_fork.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
struct crl_distribution_point;
#include "lswtool.h"
#include "lswalloc.h"
#include "lswlog.h"
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#include "ipsecconf/confread.h"
#include "ipsecconf/confwrite.h"
#include "optarg.h"
#include "lswtool.h"
#include "lswnss.h"
#include "ipsecconf/keywords.h" /* for KSF_NSSDIR */
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
/*
* We allow 2192 as a minimum, but default to a random value between 3072 and
#include "optarg.h"
#include "ipsecconf/keywords.h" /* for KSF_NSSDIR */
-#include "ipsecconf/config_setup.h"
+#include "ipsecconf/setup.h"
#include <keyhi.h>
#include <prerror.h>