/* * Copyright (C) 2012-2019 Tobias Brunner * Copyright (C) 2005-2007 Martin Willi * Copyright (C) 2005 Jan Hutter * 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 . * * 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. */ /** * @defgroup ike_cfg ike_cfg * @{ @ingroup config */ #ifndef IKE_CFG_H_ #define IKE_CFG_H_ typedef enum ike_version_t ike_version_t; typedef enum fragmentation_t fragmentation_t; typedef enum childless_t childless_t; typedef struct ike_cfg_t ike_cfg_t; typedef struct ike_cfg_create_t ike_cfg_create_t; #include #include #include #include #include #include /** * IKE version. */ enum ike_version_t { /** any version */ IKE_ANY = 0, /** IKE version 1 */ IKEV1 = 1, /** IKE version 2 */ IKEV2 = 2, }; /** * Proprietary IKEv1 fragmentation and IKEv2 fragmentation */ enum fragmentation_t { /** disable fragmentation */ FRAGMENTATION_NO, /** announce support, but don't send any fragments */ FRAGMENTATION_ACCEPT, /** enable fragmentation, if supported by peer */ FRAGMENTATION_YES, /** force use of fragmentation (even for the first message for IKEv1) */ FRAGMENTATION_FORCE, }; /** * Childless IKE_SAs (RFC 6023) */ enum childless_t { /** Allow childless IKE_SAs as responder, but initiate regular IKE_SAs */ CHILDLESS_ALLOW, /** Don't accept childless IKE_SAs as responder, don't initiate them */ CHILDLESS_NEVER, /** Only accept the creation of childless IKE_SAs (also as responder) */ CHILDLESS_FORCE, }; /** * enum strings for ike_version_t */ extern enum_name_t *ike_version_names; /** * An ike_cfg_t defines the rules to set up an IKE_SA. * * @see peer_cfg_t to get an overview over the configurations. */ struct ike_cfg_t { /** * Get the IKE version to use with this configuration. * * @return IKE major version */ ike_version_t (*get_version)(ike_cfg_t *this); /** * Resolve the local address to use for initiation. * * @param family address family to prefer, or AF_UNSPEC * @return resolved host, NULL on error */ host_t* (*resolve_me)(ike_cfg_t *this, int family); /** * Resolve the remote address to use for initiation. * * @param family address family to prefer, or AF_UNSPEC * @return resolved host, NULL on error */ host_t* (*resolve_other)(ike_cfg_t *this, int family); /** * Check how good a host matches to the configured local address. * * @param host host to check match quality * @return quality of the match, 0 if not matching at all */ u_int (*match_me)(ike_cfg_t *this, host_t *host); /** * Check how good a host matches to the configured remote address. * * @param host host to check match quality * @return quality of the match, 0 if not matching at all */ u_int (*match_other)(ike_cfg_t *this, host_t *host); /** * Get own address. * * @return string of address/DNS name */ char* (*get_my_addr) (ike_cfg_t *this); /** * Get peer's address. * * @return string of address/DNS name */ char* (*get_other_addr) (ike_cfg_t *this); /** * Get the port to use as our source port. * * @return source address port, host order */ uint16_t (*get_my_port)(ike_cfg_t *this); /** * Get the port to use as destination port. * * @return destination address, host order */ uint16_t (*get_other_port)(ike_cfg_t *this); /** * Get the DSCP value to use for IKE packets send from connections. * * @return DSCP value */ uint8_t (*get_dscp)(ike_cfg_t *this); /** * Adds a proposal to the list. * * The first added proposal has the highest priority, the last * added the lowest. It is safe to add NULL as proposal, which has no * effect. * * @param proposal proposal to add, or NULL */ void (*add_proposal) (ike_cfg_t *this, proposal_t *proposal); /** * Returns a list of all supported proposals. * * Returned list and its proposals must be destroyed after use. * * @return list containing all the proposals */ linked_list_t* (*get_proposals) (ike_cfg_t *this); /** * Select a proposal from a list of supplied proposals. * * Returned proposal must be destroyed after use. * * @param proposals list of proposals to select from * @param flags flags to consider during proposal selection * @return selected proposal, or NULL if none matches. */ proposal_t *(*select_proposal) (ike_cfg_t *this, linked_list_t *proposals, proposal_selection_flag_t flags); /** * Check if the config has a matching proposal. * * @param match proposal to check * @param private accept algorithms from a private range * @return TRUE if a matching proposal is contained */ bool(*has_proposal)(ike_cfg_t *this, proposal_t *match, bool private); /** * Should we send a certificate request in IKE_SA_INIT? * * @return certificate request sending policy */ bool (*send_certreq) (ike_cfg_t *this); /** * Enforce UDP encapsulation by faking NATD notifies? * * @return TRUE to enforce UDP encapsulation */ bool (*force_encap) (ike_cfg_t *this); /** * Use IKE fragmentation * * @return TRUE to use fragmentation */ fragmentation_t (*fragmentation) (ike_cfg_t *this); /** * Whether to initiate/accept childless IKE_SAs * * @return initiate/accept childless IKE_SAs */ childless_t (*childless)(ike_cfg_t *this); /** * Get the DH group to use for IKE_SA setup. * * @return dh group to use for initialization */ diffie_hellman_group_t (*get_dh_group)(ike_cfg_t *this); /** * Check if two IKE configs are equal. * * @param other other to check for equality * @return TRUE if other equal to this */ bool (*equals)(ike_cfg_t *this, ike_cfg_t *other); /** * Increase reference count. * * @return reference to this */ ike_cfg_t* (*get_ref) (ike_cfg_t *this); /** * Destroys a ike_cfg_t object. * * Decrements the internal reference counter and * destroys the ike_cfg when it reaches zero. */ void (*destroy) (ike_cfg_t *this); }; /** * Data passed to the constructor of an ike_cfg_t object. * * local and remote are comma separated lists of IP addresses, DNS names, * IP ranges or subnets. When initiating, the first non-range/subnet address is * used as address. When responding, a match is performed against all items in * the list. */ struct ike_cfg_create_t { /** IKE major version to use for this config */ ike_version_t version; /** Address/DNS name of local peer (cloned) */ char *local; /** IKE port to use as source, 500 uses IKEv2 port floating */ uint16_t local_port; /** Address/DNS name of remote peer (cloned) */ char *remote; /** IKE port to use as dest, 500 uses IKEv2 port floating */ uint16_t remote_port; /** TRUE to not send any certificate requests */ bool no_certreq; /** Enforce UDP encapsulation by faking NATD notify */ bool force_encap; /** Use IKE fragmentation */ fragmentation_t fragmentation; /** Childless IKE_SA configuration */ childless_t childless; /** DSCP value to send IKE packets with */ uint8_t dscp; }; /** * Creates an ike_cfg_t object. * * @param data data for this ike_cfg * @return ike_cfg_t object. */ ike_cfg_t *ike_cfg_create(ike_cfg_create_t *data); /** * Determine the address family of the local or remote address(es). If multiple * families are configured AF_UNSPEC is returned. %any is ignored (%any4|6 are * not though). * * @param this ike config to check * @param local TRUE to check local addresses, FALSE for remote * @return address family of address(es) if distinct */ int ike_cfg_get_family(ike_cfg_t *this, bool local); /** * Determine if the given address was explicitly configured as local or remote * address. * * @param this ike config to check * @param addr address to check * @param local TRUE to check local addresses, FALSE for remote * @return TRUE if address was configured */ bool ike_cfg_has_address(ike_cfg_t *this, host_t *addr, bool local); #endif /** IKE_CFG_H_ @}*/