1330 lines
43 KiB
C
1330 lines
43 KiB
C
/* $OpenBSD: iked.h,v 1.229 2024/02/15 20:10:45 tobhe Exp $ */
|
|
|
|
/*
|
|
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
|
|
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
|
|
*
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/tree.h>
|
|
#include <sys/queue.h>
|
|
#include <arpa/inet.h>
|
|
#include <limits.h>
|
|
#include <imsg.h>
|
|
|
|
#include <openssl/evp.h>
|
|
|
|
#include "types.h"
|
|
#include "dh.h"
|
|
|
|
#define MAXIMUM(a,b) (((a)>(b))?(a):(b))
|
|
#define MINIMUM(a,b) (((a)<(b))?(a):(b))
|
|
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
|
|
|
|
#ifndef IKED_H
|
|
#define IKED_H
|
|
|
|
/*
|
|
* Common IKEv1/IKEv2 header
|
|
*/
|
|
|
|
struct ike_header {
|
|
uint64_t ike_ispi; /* Initiator cookie */
|
|
uint64_t ike_rspi; /* Responder cookie */
|
|
uint8_t ike_nextpayload; /* Next payload type */
|
|
uint8_t ike_version; /* Major/Minor version number */
|
|
uint8_t ike_exchange; /* Exchange type */
|
|
uint8_t ike_flags; /* Message options */
|
|
uint32_t ike_msgid; /* Message identifier */
|
|
uint32_t ike_length; /* Total message length */
|
|
} __packed;
|
|
|
|
/*
|
|
* Common daemon infrastructure, local imsg etc.
|
|
*/
|
|
|
|
struct imsgev {
|
|
struct imsgbuf ibuf;
|
|
void (*handler)(int, short, void *);
|
|
struct event ev;
|
|
struct privsep_proc *proc;
|
|
void *data;
|
|
short events;
|
|
const char *name;
|
|
};
|
|
|
|
#define IMSG_SIZE_CHECK(imsg, p) do { \
|
|
if (IMSG_DATA_SIZE(imsg) < sizeof(*p)) \
|
|
fatalx("bad length imsg received"); \
|
|
} while (0)
|
|
#define IMSG_DATA_SIZE(imsg) ((imsg)->hdr.len - IMSG_HEADER_SIZE)
|
|
|
|
#define IKED_ADDR_EQ(_a, _b) \
|
|
((_a)->addr_mask == (_b)->addr_mask && \
|
|
sockaddr_cmp((struct sockaddr *)&(_a)->addr, \
|
|
(struct sockaddr *)&(_b)->addr, (_a)->addr_mask) == 0)
|
|
|
|
#define IKED_ADDR_NEQ(_a, _b) \
|
|
((_a)->addr_mask != (_b)->addr_mask || \
|
|
sockaddr_cmp((struct sockaddr *)&(_a)->addr, \
|
|
(struct sockaddr *)&(_b)->addr, (_a)->addr_mask) != 0)
|
|
|
|
/* initially control.h */
|
|
struct control_sock {
|
|
const char *cs_name;
|
|
struct event cs_ev;
|
|
struct event cs_evt;
|
|
int cs_fd;
|
|
int cs_restricted;
|
|
void *cs_env;
|
|
};
|
|
|
|
struct ctl_conn {
|
|
TAILQ_ENTRY(ctl_conn) entry;
|
|
uint8_t flags;
|
|
#define CTL_CONN_NOTIFY 0x01
|
|
struct imsgev iev;
|
|
uint32_t peerid;
|
|
};
|
|
TAILQ_HEAD(ctl_connlist, ctl_conn);
|
|
|
|
extern enum privsep_procid privsep_process;
|
|
|
|
/*
|
|
* Runtime structures
|
|
*/
|
|
|
|
struct iked_timer {
|
|
struct event tmr_ev;
|
|
struct iked *tmr_env;
|
|
void (*tmr_cb)(struct iked *, void *);
|
|
void *tmr_cbarg;
|
|
};
|
|
|
|
struct iked_spi {
|
|
uint64_t spi;
|
|
uint8_t spi_size;
|
|
uint8_t spi_protoid;
|
|
};
|
|
|
|
struct iked_proposal {
|
|
uint8_t prop_id;
|
|
uint8_t prop_protoid;
|
|
|
|
struct iked_spi prop_localspi;
|
|
struct iked_spi prop_peerspi;
|
|
|
|
struct iked_transform *prop_xforms;
|
|
unsigned int prop_nxforms;
|
|
|
|
TAILQ_ENTRY(iked_proposal) prop_entry;
|
|
};
|
|
TAILQ_HEAD(iked_proposals, iked_proposal);
|
|
|
|
struct iked_addr {
|
|
int addr_af;
|
|
struct sockaddr_storage addr;
|
|
uint8_t addr_mask;
|
|
int addr_net;
|
|
in_port_t addr_port;
|
|
};
|
|
|
|
struct iked_ts {
|
|
struct iked_addr ts_addr;
|
|
uint8_t ts_ipproto;
|
|
TAILQ_ENTRY(iked_ts) ts_entry;
|
|
};
|
|
TAILQ_HEAD(iked_tss, iked_ts);
|
|
|
|
struct iked_flow {
|
|
struct iked_addr flow_src;
|
|
struct iked_addr flow_dst;
|
|
unsigned int flow_dir; /* in/out */
|
|
int flow_rdomain;
|
|
struct iked_addr flow_prenat;
|
|
int flow_fixed;
|
|
|
|
unsigned int flow_loaded; /* pfkey done */
|
|
|
|
uint8_t flow_saproto;
|
|
uint8_t flow_ipproto;
|
|
|
|
struct iked_addr *flow_local; /* outer source */
|
|
struct iked_addr *flow_peer; /* outer dest */
|
|
struct iked_sa *flow_ikesa; /* parent SA */
|
|
|
|
RB_ENTRY(iked_flow) flow_node;
|
|
TAILQ_ENTRY(iked_flow) flow_entry;
|
|
};
|
|
RB_HEAD(iked_flows, iked_flow);
|
|
TAILQ_HEAD(iked_saflows, iked_flow);
|
|
|
|
struct iked_childsa {
|
|
uint8_t csa_saproto; /* IPsec protocol */
|
|
unsigned int csa_dir; /* in/out */
|
|
|
|
uint64_t csa_peerspi; /* peer relation */
|
|
uint8_t csa_loaded; /* pfkey done */
|
|
uint8_t csa_rekey; /* will be deleted */
|
|
uint8_t csa_allocated; /* from the kernel */
|
|
uint8_t csa_persistent;/* do not rekey */
|
|
uint8_t csa_esn; /* use ESN */
|
|
uint8_t csa_transport; /* transport mode */
|
|
|
|
struct iked_spi csa_spi;
|
|
|
|
struct ibuf *csa_encrkey; /* encryption key */
|
|
uint16_t csa_encrid; /* encryption xform id */
|
|
|
|
struct ibuf *csa_integrkey; /* auth key */
|
|
uint16_t csa_integrid; /* auth xform id */
|
|
|
|
struct iked_addr *csa_local; /* outer source */
|
|
struct iked_addr *csa_peer; /* outer dest */
|
|
struct iked_sa *csa_ikesa; /* parent SA */
|
|
|
|
struct iked_childsa *csa_peersa; /* peer */
|
|
|
|
struct iked_childsa *csa_bundled; /* IPCOMP */
|
|
|
|
uint16_t csa_pfsgrpid; /* pfs group id */
|
|
|
|
RB_ENTRY(iked_childsa) csa_node;
|
|
TAILQ_ENTRY(iked_childsa) csa_entry;
|
|
};
|
|
RB_HEAD(iked_activesas, iked_childsa);
|
|
TAILQ_HEAD(iked_childsas, iked_childsa);
|
|
|
|
|
|
struct iked_static_id {
|
|
uint8_t id_type;
|
|
uint8_t id_length;
|
|
uint8_t id_offset;
|
|
uint8_t id_data[IKED_ID_SIZE];
|
|
};
|
|
|
|
struct iked_auth {
|
|
uint8_t auth_method;
|
|
uint8_t auth_eap; /* optional EAP */
|
|
uint8_t auth_length; /* zero if EAP */
|
|
uint8_t auth_data[IKED_PSK_SIZE];
|
|
};
|
|
|
|
struct iked_cfg {
|
|
uint8_t cfg_action;
|
|
uint16_t cfg_type;
|
|
union {
|
|
struct iked_addr address;
|
|
} cfg;
|
|
};
|
|
|
|
TAILQ_HEAD(iked_sapeers, iked_sa);
|
|
|
|
struct iked_lifetime {
|
|
uint64_t lt_bytes;
|
|
uint64_t lt_seconds;
|
|
};
|
|
|
|
struct iked_policy {
|
|
unsigned int pol_id;
|
|
char pol_name[IKED_ID_SIZE];
|
|
unsigned int pol_iface;
|
|
|
|
#define IKED_SKIP_FLAGS 0
|
|
#define IKED_SKIP_AF 1
|
|
#define IKED_SKIP_SRC_ADDR 2
|
|
#define IKED_SKIP_DST_ADDR 3
|
|
#define IKED_SKIP_COUNT 4
|
|
struct iked_policy *pol_skip[IKED_SKIP_COUNT];
|
|
|
|
uint8_t pol_flags;
|
|
#define IKED_POLICY_PASSIVE 0x00
|
|
#define IKED_POLICY_DEFAULT 0x01
|
|
#define IKED_POLICY_ACTIVE 0x02
|
|
#define IKED_POLICY_REFCNT 0x04
|
|
#define IKED_POLICY_QUICK 0x08
|
|
#define IKED_POLICY_SKIP 0x10
|
|
#define IKED_POLICY_IPCOMP 0x20
|
|
#define IKED_POLICY_TRANSPORT 0x40
|
|
#define IKED_POLICY_ROUTING 0x80
|
|
|
|
int pol_refcnt;
|
|
|
|
uint8_t pol_certreqtype;
|
|
|
|
int pol_af;
|
|
int pol_rdomain;
|
|
uint8_t pol_saproto;
|
|
unsigned int pol_ipproto[IKED_IPPROTO_MAX];
|
|
unsigned int pol_nipproto;
|
|
|
|
struct iked_addr pol_peer;
|
|
struct iked_static_id pol_peerid;
|
|
uint32_t pol_peerdh;
|
|
|
|
struct iked_addr pol_local;
|
|
struct iked_static_id pol_localid;
|
|
|
|
struct iked_auth pol_auth;
|
|
|
|
char pol_tag[IKED_TAG_SIZE];
|
|
unsigned int pol_tap;
|
|
|
|
struct iked_proposals pol_proposals;
|
|
size_t pol_nproposals;
|
|
|
|
struct iked_flows pol_flows;
|
|
size_t pol_nflows;
|
|
struct iked_tss pol_tssrc; /* Traffic Selectors Initiator*/
|
|
size_t pol_tssrc_count;
|
|
struct iked_tss pol_tsdst; /* Traffic Selectors Responder*/
|
|
size_t pol_tsdst_count;
|
|
|
|
struct iked_cfg pol_cfg[IKED_CFG_MAX];
|
|
unsigned int pol_ncfg;
|
|
|
|
uint32_t pol_rekey; /* ike SA lifetime */
|
|
struct iked_lifetime pol_lifetime; /* child SA lifetime */
|
|
|
|
struct iked_sapeers pol_sapeers;
|
|
|
|
TAILQ_ENTRY(iked_policy) pol_entry;
|
|
};
|
|
TAILQ_HEAD(iked_policies, iked_policy);
|
|
|
|
struct iked_hash {
|
|
uint8_t hash_type; /* PRF or INTEGR */
|
|
uint16_t hash_id; /* IKE PRF/INTEGR hash id */
|
|
const void *hash_priv; /* Identifying the hash alg */
|
|
void *hash_ctx; /* Context of the current invocation */
|
|
int hash_fixedkey; /* Requires fixed key length */
|
|
struct ibuf *hash_key; /* MAC key derived from key seed */
|
|
size_t hash_length; /* Output length */
|
|
size_t hash_trunc; /* Truncate the output length */
|
|
struct iked_hash *hash_prf; /* PRF pointer */
|
|
int hash_isaead;
|
|
};
|
|
|
|
struct iked_cipher {
|
|
uint8_t encr_type; /* ENCR */
|
|
uint16_t encr_id; /* IKE ENCR hash id */
|
|
const void *encr_priv; /* Identifying the hash alg */
|
|
void *encr_ctx; /* Context of the current invocation */
|
|
int encr_fixedkey; /* Requires fixed key length */
|
|
struct ibuf *encr_key; /* MAC key derived from key seed */
|
|
struct ibuf *encr_iv; /* Initialization Vector */
|
|
uint64_t encr_civ; /* Counter IV for GCM */
|
|
size_t encr_ivlength; /* IV length */
|
|
size_t encr_length; /* Block length */
|
|
size_t encr_saltlength; /* IV salt length */
|
|
uint16_t encr_authid; /* ID of associated authentication */
|
|
};
|
|
|
|
struct iked_dsa {
|
|
uint8_t dsa_method; /* AUTH method */
|
|
const void *dsa_priv; /* PRF or signature hash function */
|
|
void *dsa_ctx; /* PRF or signature hash ctx */
|
|
struct ibuf *dsa_keydata; /* public, private or shared key */
|
|
void *dsa_key; /* parsed public or private key */
|
|
int dsa_hmac; /* HMAC or public/private key */
|
|
int dsa_sign; /* Sign or verify operation */
|
|
uint32_t dsa_flags; /* State flags */
|
|
};
|
|
|
|
struct iked_id {
|
|
uint8_t id_type;
|
|
uint8_t id_offset;
|
|
struct ibuf *id_buf;
|
|
};
|
|
|
|
#define IKED_REQ_CERT 0x0001 /* get local certificate (if required) */
|
|
#define IKED_REQ_CERTVALID 0x0002 /* validated the peer cert */
|
|
#define IKED_REQ_CERTREQ 0x0004 /* CERTREQ has been received */
|
|
#define IKED_REQ_AUTH 0x0008 /* AUTH payload */
|
|
#define IKED_REQ_AUTHVALID 0x0010 /* AUTH payload has been verified */
|
|
#define IKED_REQ_SA 0x0020 /* SA available */
|
|
#define IKED_REQ_EAPVALID 0x0040 /* EAP payload has been verified */
|
|
#define IKED_REQ_CHILDSA 0x0080 /* Child SA initiated */
|
|
#define IKED_REQ_INF 0x0100 /* Informational exchange initiated */
|
|
|
|
#define IKED_REQ_BITS \
|
|
"\20\01CERT\02CERTVALID\03CERTREQ\04AUTH\05AUTHVALID\06SA\07EAPVALID" \
|
|
"\10CHILDSA\11INF"
|
|
|
|
TAILQ_HEAD(iked_msgqueue, iked_msg_retransmit);
|
|
TAILQ_HEAD(iked_msg_fragqueue, iked_message);
|
|
|
|
struct iked_sahdr {
|
|
uint64_t sh_ispi; /* Initiator SPI */
|
|
uint64_t sh_rspi; /* Responder SPI */
|
|
unsigned int sh_initiator; /* Is initiator? */
|
|
} __packed;
|
|
|
|
struct iked_kex {
|
|
struct ibuf *kex_inonce; /* Ni */
|
|
struct ibuf *kex_rnonce; /* Nr */
|
|
|
|
struct dh_group *kex_dhgroup; /* DH group */
|
|
struct ibuf *kex_dhiexchange;
|
|
struct ibuf *kex_dhrexchange;
|
|
struct ibuf *kex_dhpeer; /* pointer to i or r */
|
|
};
|
|
|
|
struct iked_frag_entry {
|
|
uint8_t *frag_data;
|
|
size_t frag_size;
|
|
};
|
|
|
|
struct iked_frag {
|
|
struct iked_frag_entry **frag_arr; /* list of fragment buffers */
|
|
size_t frag_count; /* number of fragments received */
|
|
#define IKED_FRAG_TOTAL_MAX 111 /* upper limit (64kB / 576B) */
|
|
size_t frag_total; /* total numbe of fragments */
|
|
size_t frag_total_size;
|
|
uint8_t frag_nextpayload;
|
|
|
|
};
|
|
|
|
struct iked_ipcomp {
|
|
uint16_t ic_cpi_out; /* outgoing CPI */
|
|
uint16_t ic_cpi_in; /* incoming CPI */
|
|
uint8_t ic_transform; /* transform */
|
|
};
|
|
|
|
struct iked_sa {
|
|
struct iked_sahdr sa_hdr;
|
|
uint32_t sa_msgid; /* Last request rcvd */
|
|
int sa_msgid_set; /* msgid initialized */
|
|
uint32_t sa_msgid_current; /* Current requested rcvd */
|
|
uint32_t sa_reqid; /* Next request sent */
|
|
|
|
int sa_type;
|
|
#define IKED_SATYPE_LOOKUP 0 /* Used for lookup */
|
|
#define IKED_SATYPE_LOCAL 1 /* Local SA */
|
|
|
|
struct iked_addr sa_peer;
|
|
struct iked_addr sa_peer_loaded;/* MOBIKE */
|
|
struct iked_addr sa_local;
|
|
int sa_fd;
|
|
|
|
struct iked_frag sa_fragments;
|
|
|
|
int sa_natt; /* for IKE messages */
|
|
int sa_udpencap; /* for pfkey */
|
|
int sa_usekeepalive;/* NAT-T keepalive */
|
|
|
|
int sa_state;
|
|
unsigned int sa_stateflags;
|
|
unsigned int sa_stateinit; /* SA_INIT */
|
|
unsigned int sa_statevalid; /* IKE_AUTH */
|
|
|
|
int sa_cp; /* XXX */
|
|
struct iked_addr *sa_cp_addr; /* requested address */
|
|
struct iked_addr *sa_cp_addr6; /* requested address */
|
|
struct iked_addr *sa_cp_dns; /* requested dns */
|
|
|
|
struct iked_policy *sa_policy;
|
|
struct timeval sa_timecreated;
|
|
struct timeval sa_timeused;
|
|
|
|
char *sa_tag;
|
|
const char *sa_reason; /* reason for close */
|
|
|
|
struct iked_kex sa_kex;
|
|
/* XXX compat defines until everything is converted */
|
|
#define sa_inonce sa_kex.kex_inonce
|
|
#define sa_rnonce sa_kex.kex_rnonce
|
|
#define sa_dhgroup sa_kex.kex_dhgroup
|
|
#define sa_dhiexchange sa_kex.kex_dhiexchange
|
|
#define sa_dhrexchange sa_kex.kex_dhrexchange
|
|
#define sa_dhpeer sa_kex.kex_dhpeer
|
|
|
|
struct iked_hash *sa_prf; /* PRF alg */
|
|
struct iked_hash *sa_integr; /* integrity alg */
|
|
struct iked_cipher *sa_encr; /* encryption alg */
|
|
|
|
struct ibuf *sa_key_d; /* SK_d */
|
|
struct ibuf *sa_key_iauth; /* SK_ai */
|
|
struct ibuf *sa_key_rauth; /* SK_ar */
|
|
struct ibuf *sa_key_iencr; /* SK_ei */
|
|
struct ibuf *sa_key_rencr; /* SK_er */
|
|
struct ibuf *sa_key_iprf; /* SK_pi */
|
|
struct ibuf *sa_key_rprf; /* SK_pr */
|
|
|
|
struct ibuf *sa_1stmsg; /* for initiator AUTH */
|
|
struct ibuf *sa_2ndmsg; /* for responder AUTH */
|
|
struct iked_id sa_localauth; /* local AUTH message */
|
|
struct iked_id sa_peerauth; /* peer AUTH message */
|
|
int sa_sigsha2; /* use SHA2 for signatures */
|
|
#define IKED_SCERT_MAX 3 /* max # of supplemental cert payloads */
|
|
|
|
struct iked_id sa_iid; /* initiator id */
|
|
struct iked_id sa_rid; /* responder id */
|
|
struct iked_id sa_icert; /* initiator cert */
|
|
struct iked_id sa_rcert; /* responder cert */
|
|
struct iked_id sa_scert[IKED_SCERT_MAX]; /* supplemental certs */
|
|
#define IKESA_SRCID(x) ((x)->sa_hdr.sh_initiator ? &(x)->sa_iid : &(x)->sa_rid)
|
|
#define IKESA_DSTID(x) ((x)->sa_hdr.sh_initiator ? &(x)->sa_rid : &(x)->sa_iid)
|
|
|
|
char *sa_eapid; /* EAP identity */
|
|
struct iked_id sa_eap; /* EAP challenge */
|
|
struct ibuf *sa_eapmsk; /* EAK session key */
|
|
|
|
struct iked_proposals sa_proposals; /* SA proposals */
|
|
struct iked_childsas sa_childsas; /* IPsec Child SAs */
|
|
struct iked_saflows sa_flows; /* IPsec flows */
|
|
|
|
struct iked_sa *sa_nexti; /* initiated IKE SA */
|
|
struct iked_sa *sa_previ; /* matching back pointer */
|
|
struct iked_sa *sa_nextr; /* simultaneous rekey */
|
|
struct iked_sa *sa_prevr; /* matching back pointer */
|
|
uint64_t sa_rekeyspi; /* peerspi CSA rekey */
|
|
struct ibuf *sa_simult; /* simultaneous rekey */
|
|
|
|
struct iked_ipcomp sa_ipcompi; /* IPcomp initator */
|
|
struct iked_ipcomp sa_ipcompr; /* IPcomp responder */
|
|
|
|
int sa_mobike; /* MOBIKE */
|
|
int sa_frag; /* fragmentation */
|
|
|
|
int sa_use_transport_mode; /* peer requested */
|
|
int sa_used_transport_mode; /* we enabled */
|
|
|
|
struct iked_timer sa_timer; /* SA timeouts */
|
|
#define IKED_IKE_SA_EXCHANGE_TIMEOUT 300 /* 5 minutes */
|
|
#define IKED_IKE_SA_REKEY_TIMEOUT 120 /* 2 minutes */
|
|
#define IKED_IKE_SA_DELETE_TIMEOUT 120 /* 2 minutes */
|
|
#define IKED_IKE_SA_ALIVE_TIMEOUT 60 /* 1 minute */
|
|
|
|
struct iked_timer sa_keepalive; /* keepalive timer */
|
|
#define IKED_IKE_SA_KEEPALIVE_TIMEOUT 20
|
|
|
|
struct iked_timer sa_rekey; /* rekey timeout */
|
|
int sa_tmpfail;
|
|
|
|
struct iked_msgqueue sa_requests; /* request queue */
|
|
#define IKED_RETRANSMIT_TIMEOUT 2 /* 2 seconds */
|
|
|
|
struct iked_msgqueue sa_responses; /* response queue */
|
|
#define IKED_RESPONSE_TIMEOUT 120 /* 2 minutes */
|
|
|
|
TAILQ_ENTRY(iked_sa) sa_peer_entry;
|
|
RB_ENTRY(iked_sa) sa_entry; /* all SAs */
|
|
|
|
RB_ENTRY(iked_sa) sa_dstid_entry; /* SAs by DSTID */
|
|
int sa_dstid_entry_valid; /* sa_dstid_entry valid */
|
|
|
|
struct iked_addr *sa_addrpool; /* address from pool */
|
|
RB_ENTRY(iked_sa) sa_addrpool_entry; /* pool entries */
|
|
|
|
struct iked_addr *sa_addrpool6; /* address from pool */
|
|
RB_ENTRY(iked_sa) sa_addrpool6_entry; /* pool entries */
|
|
time_t sa_last_recvd;
|
|
#define IKED_IKE_SA_LAST_RECVD_TIMEOUT 300 /* 5 minutes */
|
|
};
|
|
RB_HEAD(iked_sas, iked_sa);
|
|
RB_HEAD(iked_dstid_sas, iked_sa);
|
|
RB_HEAD(iked_addrpool, iked_sa);
|
|
RB_HEAD(iked_addrpool6, iked_sa);
|
|
|
|
/* stats */
|
|
|
|
struct iked_stats {
|
|
uint64_t ikes_sa_created;
|
|
uint64_t ikes_sa_established_total;
|
|
uint64_t ikes_sa_established_current; /* gauge */
|
|
uint64_t ikes_sa_established_failures;
|
|
uint64_t ikes_sa_proposals_negotiate_failures;
|
|
uint64_t ikes_sa_rekeyed;
|
|
uint64_t ikes_sa_removed;
|
|
uint64_t ikes_csa_created;
|
|
uint64_t ikes_csa_removed;
|
|
uint64_t ikes_msg_sent;
|
|
uint64_t ikes_msg_send_failures;
|
|
uint64_t ikes_msg_rcvd;
|
|
uint64_t ikes_msg_rcvd_busy;
|
|
uint64_t ikes_msg_rcvd_dropped;
|
|
uint64_t ikes_retransmit_request;
|
|
uint64_t ikes_retransmit_response;
|
|
uint64_t ikes_retransmit_limit;
|
|
uint64_t ikes_frag_sent;
|
|
uint64_t ikes_frag_send_failures;
|
|
uint64_t ikes_frag_rcvd;
|
|
uint64_t ikes_frag_rcvd_drop;
|
|
uint64_t ikes_frag_reass_ok;
|
|
uint64_t ikes_frag_reass_drop;
|
|
uint64_t ikes_update_addresses_sent;
|
|
uint64_t ikes_dpd_sent;
|
|
uint64_t ikes_keepalive_sent;
|
|
};
|
|
|
|
#define ikestat_add(env, c, n) do { env->sc_stats.c += (n); } while(0)
|
|
#define ikestat_inc(env, c) ikestat_add(env, c, 1)
|
|
#define ikestat_dec(env, c) ikestat_add(env, c, -1)
|
|
|
|
struct iked_certreq {
|
|
struct ibuf *cr_data;
|
|
uint8_t cr_type;
|
|
SIMPLEQ_ENTRY(iked_certreq) cr_entry;
|
|
};
|
|
SIMPLEQ_HEAD(iked_certreqs, iked_certreq);
|
|
|
|
#define EAP_STATE_IDENTITY (1)
|
|
#define EAP_STATE_MSCHAPV2_CHALLENGE (2)
|
|
#define EAP_STATE_MSCHAPV2_SUCCESS (3)
|
|
#define EAP_STATE_SUCCESS (4)
|
|
|
|
struct eap_msg {
|
|
char *eam_identity;
|
|
char *eam_user;
|
|
int eam_type;
|
|
uint8_t eam_id;
|
|
uint8_t eam_msrid;
|
|
int eam_success;
|
|
int eam_found;
|
|
int eam_response;
|
|
uint8_t eam_challenge[16];
|
|
uint8_t eam_ntresponse[24];
|
|
uint32_t eam_state;
|
|
};
|
|
|
|
struct iked_message {
|
|
struct ibuf *msg_data;
|
|
size_t msg_offset;
|
|
|
|
struct sockaddr_storage msg_local;
|
|
socklen_t msg_locallen;
|
|
|
|
struct sockaddr_storage msg_peer;
|
|
socklen_t msg_peerlen;
|
|
|
|
struct iked_socket *msg_sock;
|
|
|
|
int msg_fd;
|
|
int msg_response;
|
|
int msg_responded;
|
|
int msg_valid;
|
|
int msg_natt;
|
|
int msg_natt_rcvd;
|
|
int msg_nat_detected;
|
|
int msg_error;
|
|
int msg_e;
|
|
struct iked_message *msg_parent;
|
|
|
|
/* Associated policy and SA */
|
|
struct iked_policy *msg_policy;
|
|
struct iked_sa *msg_sa;
|
|
|
|
uint32_t msg_msgid;
|
|
uint8_t msg_exchange;
|
|
|
|
/* Parsed information */
|
|
struct iked_proposals msg_proposals;
|
|
struct iked_certreqs msg_certreqs;
|
|
struct iked_spi msg_rekey;
|
|
struct ibuf *msg_nonce; /* dh NONCE */
|
|
uint16_t msg_dhgroup; /* dh group */
|
|
struct ibuf *msg_ke; /* dh key exchange */
|
|
struct iked_id msg_auth; /* AUTH payload */
|
|
struct iked_id msg_peerid;
|
|
struct iked_id msg_localid;
|
|
struct iked_id msg_cert;
|
|
struct iked_id msg_scert[IKED_SCERT_MAX]; /* supplemental certs */
|
|
struct ibuf *msg_cookie;
|
|
uint16_t msg_group;
|
|
uint16_t msg_cpi;
|
|
uint8_t msg_transform;
|
|
uint16_t msg_flags;
|
|
struct eap_msg msg_eap;
|
|
size_t msg_del_spisize;
|
|
size_t msg_del_cnt;
|
|
struct ibuf *msg_del_buf;
|
|
int msg_del_protoid;
|
|
int msg_cp;
|
|
struct iked_addr *msg_cp_addr; /* requested address */
|
|
struct iked_addr *msg_cp_addr6; /* requested address */
|
|
struct iked_addr *msg_cp_dns; /* requested dns */
|
|
|
|
/* MOBIKE */
|
|
int msg_update_sa_addresses;
|
|
struct ibuf *msg_cookie2;
|
|
|
|
/* Parse stack */
|
|
struct iked_proposal *msg_prop;
|
|
uint16_t msg_attrlength;
|
|
|
|
/* Retransmit queue */
|
|
TAILQ_ENTRY(iked_message)
|
|
msg_entry;
|
|
};
|
|
|
|
struct iked_msg_retransmit {
|
|
struct iked_msg_fragqueue mrt_frags;
|
|
TAILQ_ENTRY(iked_msg_retransmit) mrt_entry;
|
|
struct iked_timer mrt_timer;
|
|
int mrt_tries;
|
|
#define IKED_RETRANSMIT_TRIES 5 /* try 5 times */
|
|
};
|
|
|
|
#define IKED_MSG_NAT_SRC_IP 0x01
|
|
#define IKED_MSG_NAT_DST_IP 0x02
|
|
|
|
#define IKED_MSG_FLAGS_FRAGMENTATION 0x0001
|
|
#define IKED_MSG_FLAGS_MOBIKE 0x0002
|
|
#define IKED_MSG_FLAGS_SIGSHA2 0x0004
|
|
#define IKED_MSG_FLAGS_CHILD_SA_NOT_FOUND 0x0008
|
|
#define IKED_MSG_FLAGS_NO_ADDITIONAL_SAS 0x0010
|
|
#define IKED_MSG_FLAGS_AUTHENTICATION_FAILED 0x0020
|
|
#define IKED_MSG_FLAGS_INVALID_KE 0x0040
|
|
#define IKED_MSG_FLAGS_IPCOMP_SUPPORTED 0x0080
|
|
#define IKED_MSG_FLAGS_USE_TRANSPORT 0x0100
|
|
#define IKED_MSG_FLAGS_TEMPORARY_FAILURE 0x0200
|
|
#define IKED_MSG_FLAGS_NO_PROPOSAL_CHOSEN 0x0400
|
|
|
|
|
|
struct iked_user {
|
|
char usr_name[LOGIN_NAME_MAX];
|
|
char usr_pass[IKED_PASSWORD_SIZE];
|
|
RB_ENTRY(iked_user) usr_entry;
|
|
};
|
|
RB_HEAD(iked_users, iked_user);
|
|
|
|
struct privsep_pipes {
|
|
int *pp_pipes[PROC_MAX];
|
|
};
|
|
|
|
struct privsep {
|
|
struct privsep_pipes *ps_pipes[PROC_MAX];
|
|
struct privsep_pipes *ps_pp;
|
|
|
|
struct imsgev *ps_ievs[PROC_MAX];
|
|
const char *ps_title[PROC_MAX];
|
|
pid_t ps_pid[PROC_MAX];
|
|
struct passwd *ps_pw;
|
|
int ps_noaction;
|
|
|
|
struct control_sock ps_csock;
|
|
|
|
unsigned int ps_instances[PROC_MAX];
|
|
unsigned int ps_ninstances;
|
|
unsigned int ps_instance;
|
|
|
|
/* Event and signal handlers */
|
|
struct event ps_evsigint;
|
|
struct event ps_evsigterm;
|
|
struct event ps_evsigchld;
|
|
struct event ps_evsighup;
|
|
struct event ps_evsigpipe;
|
|
struct event ps_evsigusr1;
|
|
|
|
struct iked *ps_env;
|
|
unsigned int ps_connecting;
|
|
void (*ps_connected)(struct privsep *);
|
|
};
|
|
|
|
struct privsep_proc {
|
|
const char *p_title;
|
|
enum privsep_procid p_id;
|
|
int (*p_cb)(int, struct privsep_proc *,
|
|
struct imsg *);
|
|
void (*p_init)(struct privsep *,
|
|
struct privsep_proc *);
|
|
const char *p_chroot;
|
|
struct passwd *p_pw;
|
|
struct privsep *p_ps;
|
|
void (*p_shutdown)(void);
|
|
};
|
|
|
|
struct privsep_fd {
|
|
enum privsep_procid pf_procid;
|
|
unsigned int pf_instance;
|
|
};
|
|
|
|
#define PROC_PARENT_SOCK_FILENO 3
|
|
#define PROC_MAX_INSTANCES 32
|
|
|
|
struct iked_ocsp_entry {
|
|
TAILQ_ENTRY(iked_ocsp_entry) ioe_entry; /* next request */
|
|
void *ioe_ocsp; /* private ocsp request data */
|
|
};
|
|
TAILQ_HEAD(iked_ocsp_requests, iked_ocsp_entry);
|
|
|
|
/*
|
|
* Daemon configuration
|
|
*/
|
|
|
|
enum natt_mode {
|
|
NATT_DEFAULT, /* send/recv with both :500 and NAT-T port */
|
|
NATT_DISABLE, /* send/recv with only :500 */
|
|
NATT_FORCE, /* send/recv with only NAT-T port */
|
|
};
|
|
|
|
struct iked_static {
|
|
uint64_t st_alive_timeout;
|
|
int st_cert_partial_chain;
|
|
int st_enforcesingleikesa;
|
|
uint8_t st_frag; /* fragmentation */
|
|
uint8_t st_mobike; /* MOBIKE */
|
|
in_port_t st_nattport;
|
|
int st_stickyaddress; /* addr per DSTID */
|
|
int st_vendorid;
|
|
};
|
|
|
|
struct iked {
|
|
char sc_conffile[PATH_MAX];
|
|
|
|
uint32_t sc_opts;
|
|
enum natt_mode sc_nattmode;
|
|
uint8_t sc_passive;
|
|
uint8_t sc_decoupled;
|
|
|
|
struct iked_static sc_static;
|
|
|
|
#define sc_alive_timeout sc_static.st_alive_timeout
|
|
#define sc_cert_partial_chain sc_static.st_cert_partial_chain
|
|
#define sc_enforcesingleikesa sc_static.st_enforcesingleikesa
|
|
#define sc_frag sc_static.st_frag
|
|
#define sc_mobike sc_static.st_mobike
|
|
#define sc_nattport sc_static.st_nattport
|
|
#define sc_stickyaddress sc_static.st_stickyaddress
|
|
#define sc_vendorid sc_static.st_vendorid
|
|
|
|
struct iked_policies sc_policies;
|
|
struct iked_policy *sc_defaultcon;
|
|
|
|
struct iked_sas sc_sas;
|
|
struct iked_dstid_sas sc_dstid_sas;
|
|
struct iked_activesas sc_activesas;
|
|
struct iked_flows sc_activeflows;
|
|
struct iked_users sc_users;
|
|
|
|
struct iked_stats sc_stats;
|
|
|
|
void *sc_priv; /* per-process */
|
|
|
|
int sc_pfkey; /* ike process */
|
|
struct event sc_pfkeyev;
|
|
struct event sc_routeev;
|
|
uint8_t sc_certreqtype;
|
|
struct ibuf *sc_certreq;
|
|
void *sc_vroute;
|
|
|
|
struct iked_socket *sc_sock4[2];
|
|
struct iked_socket *sc_sock6[2];
|
|
|
|
struct iked_timer sc_inittmr;
|
|
#define IKED_INITIATOR_INITIAL 2
|
|
#define IKED_INITIATOR_INTERVAL 60
|
|
|
|
struct privsep sc_ps;
|
|
|
|
struct iked_ocsp_requests sc_ocsp;
|
|
char *sc_ocsp_url;
|
|
long sc_ocsp_tolerate;
|
|
long sc_ocsp_maxage;
|
|
|
|
struct iked_addrpool sc_addrpool;
|
|
struct iked_addrpool6 sc_addrpool6;
|
|
};
|
|
|
|
struct iked_socket {
|
|
int sock_fd;
|
|
struct event sock_ev;
|
|
struct iked *sock_env;
|
|
struct sockaddr_storage sock_addr;
|
|
};
|
|
|
|
struct ipsec_xf {
|
|
const char *name;
|
|
unsigned int id;
|
|
unsigned int length;
|
|
unsigned int keylength;
|
|
unsigned int nonce;
|
|
unsigned int noauth;
|
|
};
|
|
|
|
struct ipsec_transforms {
|
|
const struct ipsec_xf **authxf;
|
|
unsigned int nauthxf;
|
|
const struct ipsec_xf **prfxf;
|
|
unsigned int nprfxf;
|
|
const struct ipsec_xf **encxf;
|
|
unsigned int nencxf;
|
|
const struct ipsec_xf **groupxf;
|
|
unsigned int ngroupxf;
|
|
const struct ipsec_xf **esnxf;
|
|
unsigned int nesnxf;
|
|
};
|
|
|
|
struct ipsec_mode {
|
|
struct ipsec_transforms **xfs;
|
|
unsigned int nxfs;
|
|
};
|
|
|
|
/* iked.c */
|
|
void parent_reload(struct iked *, int, const char *);
|
|
|
|
extern struct iked *iked_env;
|
|
|
|
/* control.c */
|
|
void control(struct privsep *, struct privsep_proc *);
|
|
int control_init(struct privsep *, struct control_sock *);
|
|
int control_listen(struct control_sock *);
|
|
|
|
/* config.c */
|
|
struct iked_policy *
|
|
config_new_policy(struct iked *);
|
|
void config_free_kex(struct iked_kex *);
|
|
void config_free_fragments(struct iked_frag *);
|
|
void config_free_sa(struct iked *, struct iked_sa *);
|
|
struct iked_sa *
|
|
config_new_sa(struct iked *, int);
|
|
struct iked_user *
|
|
config_new_user(struct iked *, struct iked_user *);
|
|
uint64_t
|
|
config_getspi(void);
|
|
struct iked_transform *
|
|
config_findtransform(struct iked_proposals *, uint8_t, unsigned int);
|
|
struct iked_transform *
|
|
config_findtransform_ext(struct iked_proposals *, uint8_t,int, unsigned int);
|
|
void config_free_policy(struct iked *, struct iked_policy *);
|
|
struct iked_proposal *
|
|
config_add_proposal(struct iked_proposals *, unsigned int,
|
|
unsigned int);
|
|
void config_free_proposal(struct iked_proposals *, struct iked_proposal *);
|
|
void config_free_proposals(struct iked_proposals *, unsigned int);
|
|
void config_free_flows(struct iked *, struct iked_flows *);
|
|
void config_free_childsas(struct iked *, struct iked_childsas *,
|
|
struct iked_spi *, struct iked_spi *);
|
|
int config_add_transform(struct iked_proposal *,
|
|
unsigned int, unsigned int, unsigned int, unsigned int);
|
|
int config_setcoupled(struct iked *, unsigned int);
|
|
int config_getcoupled(struct iked *, unsigned int);
|
|
int config_setmode(struct iked *, unsigned int);
|
|
int config_getmode(struct iked *, unsigned int);
|
|
int config_setreset(struct iked *, unsigned int, enum privsep_procid);
|
|
int config_getreset(struct iked *, struct imsg *);
|
|
int config_doreset(struct iked *, unsigned int);
|
|
int config_setpolicy(struct iked *, struct iked_policy *,
|
|
enum privsep_procid);
|
|
int config_getpolicy(struct iked *, struct imsg *);
|
|
int config_setflow(struct iked *, struct iked_policy *,
|
|
enum privsep_procid);
|
|
int config_getflow(struct iked *, struct imsg *);
|
|
int config_setsocket(struct iked *, struct sockaddr_storage *, in_port_t,
|
|
enum privsep_procid);
|
|
int config_getsocket(struct iked *env, struct imsg *,
|
|
void (*cb)(int, short, void *));
|
|
void config_enablesocket(struct iked *env);
|
|
int config_setpfkey(struct iked *);
|
|
int config_getpfkey(struct iked *, struct imsg *);
|
|
int config_setuser(struct iked *, struct iked_user *, enum privsep_procid);
|
|
int config_getuser(struct iked *, struct imsg *);
|
|
int config_setcompile(struct iked *, enum privsep_procid);
|
|
int config_getcompile(struct iked *);
|
|
int config_setocsp(struct iked *);
|
|
int config_getocsp(struct iked *, struct imsg *);
|
|
int config_setkeys(struct iked *);
|
|
int config_getkey(struct iked *, struct imsg *);
|
|
int config_setstatic(struct iked *);
|
|
int config_getstatic(struct iked *, struct imsg *);
|
|
|
|
/* policy.c */
|
|
void policy_init(struct iked *);
|
|
int policy_lookup(struct iked *, struct iked_message *,
|
|
struct iked_proposals *, struct iked_flows *, int);
|
|
int policy_lookup_sa(struct iked *, struct iked_sa *);
|
|
struct iked_policy *
|
|
policy_test(struct iked *, struct iked_policy *);
|
|
int policy_generate_ts(struct iked_policy *);
|
|
void policy_calc_skip_steps(struct iked_policies *);
|
|
void policy_ref(struct iked *, struct iked_policy *);
|
|
void policy_unref(struct iked *, struct iked_policy *);
|
|
void sa_state(struct iked *, struct iked_sa *, int);
|
|
void sa_stateflags(struct iked_sa *, unsigned int);
|
|
int sa_stateok(const struct iked_sa *, int);
|
|
struct iked_sa *
|
|
sa_new(struct iked *, uint64_t, uint64_t, unsigned int,
|
|
struct iked_policy *);
|
|
void sa_free(struct iked *, struct iked_sa *);
|
|
void sa_free_flows(struct iked *, struct iked_saflows *);
|
|
int sa_configure_iface(struct iked *, struct iked_sa *, int);
|
|
int sa_address(struct iked_sa *, struct iked_addr *, struct sockaddr *);
|
|
void childsa_free(struct iked_childsa *);
|
|
struct iked_childsa *
|
|
childsa_lookup(struct iked_sa *, uint64_t, uint8_t);
|
|
void flow_free(struct iked_flow *);
|
|
int flow_equal(struct iked_flow *, struct iked_flow *);
|
|
struct iked_sa *
|
|
sa_lookup(struct iked *, uint64_t, uint64_t, unsigned int);
|
|
struct iked_user *
|
|
user_lookup(struct iked *, const char *);
|
|
struct iked_sa *
|
|
sa_dstid_lookup(struct iked *, struct iked_sa *);
|
|
struct iked_sa *
|
|
sa_dstid_insert(struct iked *, struct iked_sa *);
|
|
void sa_dstid_remove(struct iked *, struct iked_sa *);
|
|
int proposals_negotiate(struct iked_proposals *, struct iked_proposals *,
|
|
struct iked_proposals *, int, int);
|
|
RB_PROTOTYPE(iked_sas, iked_sa, sa_entry, sa_cmp);
|
|
RB_PROTOTYPE(iked_dstid_sas, iked_sa, sa_dstid_entry, sa_dstid_cmp);
|
|
RB_PROTOTYPE(iked_addrpool, iked_sa, sa_addrpool_entry, sa_addrpool_cmp);
|
|
RB_PROTOTYPE(iked_addrpool6, iked_sa, sa_addrpool6_entry, sa_addrpool6_cmp);
|
|
RB_PROTOTYPE(iked_users, iked_user, user_entry, user_cmp);
|
|
RB_PROTOTYPE(iked_activesas, iked_childsa, csa_node, childsa_cmp);
|
|
RB_PROTOTYPE(iked_flows, iked_flow, flow_node, flow_cmp);
|
|
|
|
/* crypto.c */
|
|
struct iked_hash *
|
|
hash_new(uint8_t, uint16_t);
|
|
struct ibuf *
|
|
hash_setkey(struct iked_hash *, void *, size_t);
|
|
void hash_free(struct iked_hash *);
|
|
void hash_init(struct iked_hash *);
|
|
void hash_update(struct iked_hash *, void *, size_t);
|
|
void hash_final(struct iked_hash *, void *, size_t *);
|
|
size_t hash_keylength(struct iked_hash *);
|
|
size_t hash_length(struct iked_hash *);
|
|
|
|
struct iked_cipher *
|
|
cipher_new(uint8_t, uint16_t, uint16_t);
|
|
struct ibuf *
|
|
cipher_setkey(struct iked_cipher *, const void *, size_t);
|
|
struct ibuf *
|
|
cipher_setiv(struct iked_cipher *, const void *, size_t);
|
|
int cipher_settag(struct iked_cipher *, uint8_t *, size_t);
|
|
int cipher_gettag(struct iked_cipher *, uint8_t *, size_t);
|
|
void cipher_free(struct iked_cipher *);
|
|
int cipher_init(struct iked_cipher *, int);
|
|
int cipher_init_encrypt(struct iked_cipher *);
|
|
int cipher_init_decrypt(struct iked_cipher *);
|
|
void cipher_aad(struct iked_cipher *, const void *, size_t, size_t *);
|
|
int cipher_update(struct iked_cipher *, const void *, size_t, void *, size_t *);
|
|
int cipher_final(struct iked_cipher *);
|
|
size_t cipher_length(struct iked_cipher *);
|
|
size_t cipher_keylength(struct iked_cipher *);
|
|
size_t cipher_ivlength(struct iked_cipher *);
|
|
size_t cipher_outlength(struct iked_cipher *, size_t);
|
|
|
|
struct iked_dsa *
|
|
dsa_new(uint8_t, struct iked_hash *, int);
|
|
struct iked_dsa *
|
|
dsa_sign_new(uint8_t, struct iked_hash *);
|
|
struct iked_dsa *
|
|
dsa_verify_new(uint8_t, struct iked_hash *);
|
|
struct ibuf *
|
|
dsa_setkey(struct iked_dsa *, void *, size_t, uint8_t);
|
|
void dsa_free(struct iked_dsa *);
|
|
int dsa_init(struct iked_dsa *, const void *, size_t);
|
|
size_t dsa_prefix(struct iked_dsa *);
|
|
size_t dsa_length(struct iked_dsa *);
|
|
int dsa_update(struct iked_dsa *, const void *, size_t);
|
|
ssize_t dsa_sign_final(struct iked_dsa *, void *, size_t);
|
|
ssize_t dsa_verify_final(struct iked_dsa *, void *, size_t);
|
|
|
|
/* vroute.c */
|
|
void vroute_init(struct iked *);
|
|
int vroute_setaddr(struct iked *, int, struct sockaddr *, int, unsigned int);
|
|
void vroute_cleanup(struct iked *);
|
|
int vroute_getaddr(struct iked *, struct imsg *);
|
|
int vroute_setdns(struct iked *, int, struct sockaddr *, unsigned int);
|
|
int vroute_getdns(struct iked *, struct imsg *);
|
|
int vroute_setaddroute(struct iked *, uint8_t, struct sockaddr *,
|
|
uint8_t, struct sockaddr *);
|
|
int vroute_setcloneroute(struct iked *, uint8_t, struct sockaddr *,
|
|
uint8_t, struct sockaddr *);
|
|
int vroute_setdelroute(struct iked *, uint8_t, struct sockaddr *,
|
|
uint8_t, struct sockaddr *);
|
|
int vroute_getroute(struct iked *, struct imsg *);
|
|
int vroute_getcloneroute(struct iked *, struct imsg *);
|
|
|
|
/* ikev2.c */
|
|
void ikev2(struct privsep *, struct privsep_proc *);
|
|
void ikev2_recv(struct iked *, struct iked_message *);
|
|
void ikev2_init_ike_sa(struct iked *, void *);
|
|
int ikev2_policy2id(struct iked_static_id *, struct iked_id *, int);
|
|
int ikev2_childsa_enable(struct iked *, struct iked_sa *);
|
|
int ikev2_childsa_delete(struct iked *, struct iked_sa *,
|
|
uint8_t, uint64_t, uint64_t *, int);
|
|
void ikev2_ikesa_recv_delete(struct iked *, struct iked_sa *);
|
|
void ikev2_ike_sa_timeout(struct iked *env, void *);
|
|
void ikev2_ike_sa_setreason(struct iked_sa *, char *);
|
|
void ikev2_reset_alive_timer(struct iked *);
|
|
int ikev2_ike_sa_delete(struct iked *, struct iked_sa *);
|
|
|
|
struct ibuf *
|
|
ikev2_prfplus(struct iked_hash *, struct ibuf *, struct ibuf *,
|
|
size_t);
|
|
ssize_t ikev2_psk(struct iked_sa *, uint8_t *, size_t, uint8_t **);
|
|
ssize_t ikev2_nat_detection(struct iked *, struct iked_message *,
|
|
void *, size_t, unsigned int, int);
|
|
void ikev2_enable_natt(struct iked *, struct iked_sa *,
|
|
struct iked_message *, int);
|
|
int ikev2_send_informational(struct iked *, struct iked_message *);
|
|
int ikev2_send_ike_e(struct iked *, struct iked_sa *, struct ibuf *,
|
|
uint8_t, uint8_t, int);
|
|
struct ike_header *
|
|
ikev2_add_header(struct ibuf *, struct iked_sa *,
|
|
uint32_t, uint8_t, uint8_t, uint8_t);
|
|
int ikev2_set_header(struct ike_header *, size_t);
|
|
struct ikev2_payload *
|
|
ikev2_add_payload(struct ibuf *);
|
|
int ikev2_next_payload(struct ikev2_payload *, size_t,
|
|
uint8_t);
|
|
int ikev2_child_sa_acquire(struct iked *, struct iked_flow *);
|
|
int ikev2_child_sa_drop(struct iked *, struct iked_spi *);
|
|
int ikev2_child_sa_rekey(struct iked *, struct iked_spi *);
|
|
void ikev2_disable_rekeying(struct iked *, struct iked_sa *);
|
|
int ikev2_print_id(struct iked_id *, char *, size_t);
|
|
int ikev2_print_static_id(struct iked_static_id *, char *, size_t);
|
|
|
|
const char *ikev2_ikesa_info(uint64_t, const char *msg);
|
|
#define SPI_IH(hdr) ikev2_ikesa_info(betoh64((hdr)->ike_ispi), NULL)
|
|
#define SPI_SH(sh, f) ikev2_ikesa_info((sh)->sh_ispi, (f))
|
|
#define SPI_SA(sa, f) SPI_SH(&(sa)->sa_hdr, (f))
|
|
|
|
/* ikev2_msg.c */
|
|
void ikev2_msg_cb(int, short, void *);
|
|
struct ibuf *
|
|
ikev2_msg_init(struct iked *, struct iked_message *,
|
|
struct sockaddr_storage *, socklen_t,
|
|
struct sockaddr_storage *, socklen_t, int);
|
|
struct iked_message *
|
|
ikev2_msg_copy(struct iked *, struct iked_message *);
|
|
void ikev2_msg_cleanup(struct iked *, struct iked_message *);
|
|
uint32_t
|
|
ikev2_msg_id(struct iked *, struct iked_sa *);
|
|
struct ibuf
|
|
*ikev2_msg_auth(struct iked *, struct iked_sa *, int);
|
|
int ikev2_msg_authsign(struct iked *, struct iked_sa *,
|
|
struct iked_auth *, struct ibuf *);
|
|
int ikev2_msg_authverify(struct iked *, struct iked_sa *,
|
|
struct iked_auth *, uint8_t *, size_t, struct ibuf *);
|
|
int ikev2_msg_valid_ike_sa(struct iked *, struct ike_header *,
|
|
struct iked_message *);
|
|
int ikev2_msg_send(struct iked *, struct iked_message *);
|
|
int ikev2_msg_send_encrypt(struct iked *, struct iked_sa *,
|
|
struct ibuf **, uint8_t, uint8_t, int);
|
|
struct ibuf
|
|
*ikev2_msg_encrypt(struct iked *, struct iked_sa *, struct ibuf *,
|
|
struct ibuf *);
|
|
struct ibuf *
|
|
ikev2_msg_decrypt(struct iked *, struct iked_sa *,
|
|
struct ibuf *, struct ibuf *);
|
|
int ikev2_msg_integr(struct iked *, struct iked_sa *, struct ibuf *);
|
|
int ikev2_msg_frompeer(struct iked_message *);
|
|
struct iked_socket *
|
|
ikev2_msg_getsocket(struct iked *, int, int);
|
|
int ikev2_msg_enqueue(struct iked *, struct iked_msgqueue *,
|
|
struct iked_message *, int);
|
|
int ikev2_msg_retransmit_response(struct iked *, struct iked_sa *,
|
|
struct iked_message *, uint8_t);
|
|
void ikev2_msg_prevail(struct iked *, struct iked_msgqueue *,
|
|
struct iked_message *);
|
|
void ikev2_msg_dispose(struct iked *, struct iked_msgqueue *,
|
|
struct iked_msg_retransmit *);
|
|
void ikev2_msg_flushqueue(struct iked *, struct iked_msgqueue *);
|
|
struct iked_msg_retransmit *
|
|
ikev2_msg_lookup(struct iked *, struct iked_msgqueue *,
|
|
struct iked_message *, uint8_t);
|
|
|
|
/* ikev2_pld.c */
|
|
int ikev2_pld_parse(struct iked *, struct ike_header *,
|
|
struct iked_message *, size_t);
|
|
|
|
/* eap.c */
|
|
int eap_parse(struct iked *, const struct iked_sa *, struct iked_message*,
|
|
void *, int);
|
|
int eap_success(struct iked *, struct iked_sa *, int);
|
|
int eap_identity_request(struct iked *, struct iked_sa *);
|
|
int eap_mschap_challenge(struct iked *, struct iked_sa *, int, int,
|
|
uint8_t *, size_t);
|
|
int eap_mschap_success(struct iked *, struct iked_sa *, int);
|
|
int eap_challenge_request(struct iked *, struct iked_sa *, int);
|
|
|
|
/* pfkey.c */
|
|
int pfkey_couple(struct iked *, struct iked_sas *, int);
|
|
int pfkey_flow_add(struct iked *, struct iked_flow *);
|
|
int pfkey_flow_delete(struct iked *, struct iked_flow *);
|
|
int pfkey_sa_init(struct iked *, struct iked_childsa *, uint32_t *);
|
|
int pfkey_sa_add(struct iked *, struct iked_childsa *, struct iked_childsa *);
|
|
int pfkey_sa_update_addresses(struct iked *, struct iked_childsa *);
|
|
int pfkey_sa_delete(struct iked *, struct iked_childsa *);
|
|
int pfkey_sa_last_used(struct iked *, struct iked_childsa *, uint64_t *);
|
|
int pfkey_flush(struct iked *);
|
|
int pfkey_socket(struct iked *);
|
|
void pfkey_init(struct iked *, int fd);
|
|
|
|
/* ca.c */
|
|
void caproc(struct privsep *, struct privsep_proc *);
|
|
int ca_setreq(struct iked *, struct iked_sa *, struct iked_static_id *,
|
|
uint8_t, uint8_t, uint8_t *, size_t, enum privsep_procid);
|
|
int ca_setcert(struct iked *, struct iked_sahdr *, struct iked_id *,
|
|
uint8_t, uint8_t *, size_t, enum privsep_procid);
|
|
int ca_setauth(struct iked *, struct iked_sa *,
|
|
struct ibuf *, enum privsep_procid);
|
|
void ca_getkey(struct privsep *, struct iked_id *, enum imsg_type);
|
|
int ca_certbundle_add(struct ibuf *, struct iked_id *);
|
|
int ca_privkey_serialize(EVP_PKEY *, struct iked_id *);
|
|
int ca_pubkey_serialize(EVP_PKEY *, struct iked_id *);
|
|
void ca_sslerror(const char *);
|
|
char *ca_asn1_name(uint8_t *, size_t);
|
|
void *ca_x509_name_parse(char *);
|
|
void ca_cert_info(const char *, X509 *);
|
|
|
|
/* timer.c */
|
|
void timer_set(struct iked *, struct iked_timer *,
|
|
void (*)(struct iked *, void *), void *);
|
|
void timer_add(struct iked *, struct iked_timer *, int);
|
|
void timer_del(struct iked *, struct iked_timer *);
|
|
|
|
/* proc.c */
|
|
void proc_init(struct privsep *, struct privsep_proc *, unsigned int, int,
|
|
int, char **, enum privsep_procid);
|
|
void proc_kill(struct privsep *);
|
|
void proc_connect(struct privsep *, void (*)(struct privsep *));
|
|
void proc_dispatch(int, short event, void *);
|
|
void proc_run(struct privsep *, struct privsep_proc *,
|
|
struct privsep_proc *, unsigned int,
|
|
void (*)(struct privsep *, struct privsep_proc *, void *), void *);
|
|
void imsg_event_add(struct imsgev *);
|
|
int imsg_compose_event(struct imsgev *, uint16_t, uint32_t,
|
|
pid_t, int, void *, uint16_t);
|
|
int imsg_composev_event(struct imsgev *, uint16_t, uint32_t,
|
|
pid_t, int, const struct iovec *, int);
|
|
int proc_compose_imsg(struct privsep *, enum privsep_procid, int,
|
|
uint16_t, uint32_t, int, void *, uint16_t);
|
|
int proc_compose(struct privsep *, enum privsep_procid,
|
|
uint16_t, void *, uint16_t);
|
|
int proc_composev_imsg(struct privsep *, enum privsep_procid, int,
|
|
uint16_t, uint32_t, int, const struct iovec *, int);
|
|
int proc_composev(struct privsep *, enum privsep_procid,
|
|
uint16_t, const struct iovec *, int);
|
|
int proc_forward_imsg(struct privsep *, struct imsg *,
|
|
enum privsep_procid, int);
|
|
struct imsgbuf *
|
|
proc_ibuf(struct privsep *, enum privsep_procid, int);
|
|
struct imsgev *
|
|
proc_iev(struct privsep *, enum privsep_procid, int);
|
|
enum privsep_procid
|
|
proc_getid(struct privsep_proc *, unsigned int, const char *);
|
|
int proc_flush_imsg(struct privsep *, enum privsep_procid, int);
|
|
|
|
/* util.c */
|
|
int socket_af(struct sockaddr *, in_port_t);
|
|
in_port_t
|
|
socket_getport(struct sockaddr *);
|
|
int socket_setport(struct sockaddr *, in_port_t);
|
|
int socket_getaddr(int, struct sockaddr_storage *);
|
|
int socket_bypass(int, struct sockaddr *);
|
|
int udp_bind(struct sockaddr *, in_port_t);
|
|
ssize_t sendtofrom(int, void *, size_t, int, struct sockaddr *,
|
|
socklen_t, struct sockaddr *, socklen_t);
|
|
ssize_t recvfromto(int, void *, size_t, int, struct sockaddr *,
|
|
socklen_t *, struct sockaddr *, socklen_t *);
|
|
const char *
|
|
print_spi(uint64_t, int);
|
|
const char *
|
|
print_map(unsigned int, struct iked_constmap *);
|
|
void lc_idtype(char *);
|
|
void print_hex(const uint8_t *, off_t, size_t);
|
|
void print_hexval(const uint8_t *, off_t, size_t);
|
|
void print_hexbuf(struct ibuf *);
|
|
const char *
|
|
print_bits(unsigned short, unsigned char *);
|
|
int sockaddr_cmp(struct sockaddr *, struct sockaddr *, int);
|
|
uint8_t mask2prefixlen(struct sockaddr *);
|
|
uint8_t mask2prefixlen6(struct sockaddr *);
|
|
struct in6_addr *
|
|
prefixlen2mask6(uint8_t, uint32_t *);
|
|
uint32_t
|
|
prefixlen2mask(uint8_t);
|
|
const char *
|
|
print_addr(void *);
|
|
char *get_string(uint8_t *, size_t);
|
|
const char *
|
|
print_proto(uint8_t);
|
|
int expand_string(char *, size_t, const char *, const char *);
|
|
uint8_t *string2unicode(const char *, size_t *);
|
|
void print_debug(const char *, ...)
|
|
__attribute__((format(printf, 1, 2)));
|
|
void print_verbose(const char *, ...)
|
|
__attribute__((format(printf, 1, 2)));
|
|
|
|
/* imsg_util.c */
|
|
struct ibuf *
|
|
ibuf_new(const void *, size_t);
|
|
struct ibuf *
|
|
ibuf_static(void);
|
|
size_t ibuf_length(struct ibuf *);
|
|
int ibuf_setsize(struct ibuf *, size_t);
|
|
struct ibuf *
|
|
ibuf_getdata(struct ibuf *, size_t);
|
|
struct ibuf *
|
|
ibuf_dup(struct ibuf *);
|
|
struct ibuf *
|
|
ibuf_random(size_t);
|
|
|
|
/* log.c */
|
|
void log_init(int, int);
|
|
void log_procinit(const char *);
|
|
void log_setverbose(int);
|
|
int log_getverbose(void);
|
|
void log_warn(const char *, ...)
|
|
__attribute__((__format__ (printf, 1, 2)));
|
|
void log_warnx(const char *, ...)
|
|
__attribute__((__format__ (printf, 1, 2)));
|
|
void log_info(const char *, ...)
|
|
__attribute__((__format__ (printf, 1, 2)));
|
|
void log_debug(const char *, ...)
|
|
__attribute__((__format__ (printf, 1, 2)));
|
|
void logit(int, const char *, ...)
|
|
__attribute__((__format__ (printf, 2, 3)));
|
|
void vlog(int, const char *, va_list)
|
|
__attribute__((__format__ (printf, 2, 0)));
|
|
__dead void fatal(const char *, ...)
|
|
__attribute__((__format__ (printf, 1, 2)));
|
|
__dead void fatalx(const char *, ...)
|
|
__attribute__((__format__ (printf, 1, 2)));
|
|
|
|
/* ocsp.c */
|
|
int ocsp_connect(struct iked *, struct imsg *);
|
|
int ocsp_receive_fd(struct iked *, struct imsg *);
|
|
int ocsp_validate_cert(struct iked *, void *, size_t, struct iked_sahdr,
|
|
uint8_t, X509 *);
|
|
|
|
/* parse.y */
|
|
int parse_config(const char *, struct iked *);
|
|
int cmdline_symset(char *);
|
|
extern const struct ipsec_xf authxfs[];
|
|
extern const struct ipsec_xf prfxfs[];
|
|
extern const struct ipsec_xf *encxfs;
|
|
extern const struct ipsec_xf ikeencxfs[];
|
|
extern const struct ipsec_xf ipsecencxfs[];
|
|
extern const struct ipsec_xf groupxfs[];
|
|
extern const struct ipsec_xf esnxfs[];
|
|
extern const struct ipsec_xf methodxfs[];
|
|
extern const struct ipsec_xf saxfs[];
|
|
extern const struct ipsec_xf cpxfs[];
|
|
size_t keylength_xf(unsigned int, unsigned int, unsigned int);
|
|
size_t noncelength_xf(unsigned int, unsigned int);
|
|
int encxf_noauth(unsigned int);
|
|
|
|
/* print.c */
|
|
void print_user(struct iked_user *);
|
|
void print_policy(struct iked_policy *);
|
|
const char *print_xf(unsigned int, unsigned int, const struct ipsec_xf *);
|
|
|
|
#endif /* IKED_H */
|