added support for transport mode and (experimental!) BEET mode

support for the type=transport/tunnel parameter in charon
This commit is contained in:
Martin Willi 2006-12-21 14:35:17 +00:00
parent 38ab8048f5
commit 7652be891c
17 changed files with 436 additions and 103 deletions

View File

@ -130,6 +130,11 @@ struct private_policy_t {
* What to do with an SA when other peer seams to be dead? * What to do with an SA when other peer seams to be dead?
*/ */
bool dpd_action; bool dpd_action;
/**
* Mode to propose for a initiated CHILD: tunnel/transport
*/
mode_t mode;
}; };
/** /**
@ -378,7 +383,6 @@ static dpd_action_t get_dpd_action(private_policy_t *this)
return this->dpd_action; return this->dpd_action;
} }
/** /**
* Implementation of policy_t.add_my_traffic_selector * Implementation of policy_t.add_my_traffic_selector
*/ */
@ -423,6 +427,14 @@ static u_int32_t get_hard_lifetime(private_policy_t *this)
return this->hard_lifetime; return this->hard_lifetime;
} }
/**
* Implementation of policy_t.get_mode.
*/
static mode_t get_mode(private_policy_t *this)
{
return this->mode;
}
/** /**
* Implements policy_t.get_ref. * Implements policy_t.get_ref.
*/ */
@ -475,7 +487,7 @@ policy_t *policy_create(char *name, identification_t *my_id, identification_t *o
auth_method_t auth_method, auth_method_t auth_method,
u_int32_t hard_lifetime, u_int32_t soft_lifetime, u_int32_t hard_lifetime, u_int32_t soft_lifetime,
u_int32_t jitter, char *updown, bool hostaccess, u_int32_t jitter, char *updown, bool hostaccess,
dpd_action_t dpd_action) mode_t mode, dpd_action_t dpd_action)
{ {
private_policy_t *this = malloc_thing(private_policy_t); private_policy_t *this = malloc_thing(private_policy_t);
@ -501,6 +513,7 @@ policy_t *policy_create(char *name, identification_t *my_id, identification_t *o
this->public.get_dpd_action = (dpd_action_t (*) (policy_t*))get_dpd_action; this->public.get_dpd_action = (dpd_action_t (*) (policy_t*))get_dpd_action;
this->public.get_soft_lifetime = (u_int32_t (*) (policy_t *))get_soft_lifetime; this->public.get_soft_lifetime = (u_int32_t (*) (policy_t *))get_soft_lifetime;
this->public.get_hard_lifetime = (u_int32_t (*) (policy_t *))get_hard_lifetime; this->public.get_hard_lifetime = (u_int32_t (*) (policy_t *))get_hard_lifetime;
this->public.get_mode = (mode_t (*) (policy_t *))get_mode;
this->public.get_ref = (void (*) (policy_t*))get_ref; this->public.get_ref = (void (*) (policy_t*))get_ref;
this->public.destroy = (void (*) (policy_t*))destroy; this->public.destroy = (void (*) (policy_t*))destroy;
@ -515,6 +528,7 @@ policy_t *policy_create(char *name, identification_t *my_id, identification_t *o
this->updown = (updown == NULL) ? NULL : strdup(updown); this->updown = (updown == NULL) ? NULL : strdup(updown);
this->hostaccess = hostaccess; this->hostaccess = hostaccess;
this->dpd_action = dpd_action; this->dpd_action = dpd_action;
this->mode = mode;
/* initialize private members*/ /* initialize private members*/
this->refcount = 1; this->refcount = 1;

View File

@ -52,6 +52,22 @@ enum dpd_action_t {
DPD_RESTART, DPD_RESTART,
}; };
/**
* @brief Mode of an IPsec SA.
*
* These are equal to those defined in XFRM, so don't change.
*
* @ingroup config
*/
enum mode_t {
/** transport mode, no inner address */
MODE_TRANSPORT = 0,
/** tunnel mode, inner and outer addresses */
MODE_TUNNEL = 1,
/** BEET mode, tunnel mode but fixed, bound inner addresses */
MODE_BEET = 4,
};
/** /**
* enum names for dpd_action_t. * enum names for dpd_action_t.
*/ */
@ -290,6 +306,14 @@ struct policy_t {
*/ */
u_int32_t (*get_hard_lifetime) (policy_t *this); u_int32_t (*get_hard_lifetime) (policy_t *this);
/**
* @brief Get the mode to use for the CHILD_SA, tunnel, transport or BEET.
*
* @param this policy
* @return lifetime in seconds
*/
mode_t (*get_mode) (policy_t *this);
/** /**
* @brief Get a new reference. * @brief Get a new reference.
* *
@ -334,6 +358,7 @@ struct policy_t {
* @param jitter range of randomization time * @param jitter range of randomization time
* @param updown updown script to execute on up/down event * @param updown updown script to execute on up/down event
* @param hostaccess allow access to the host itself (used by the updown script) * @param hostaccess allow access to the host itself (used by the updown script)
* @param mode mode to propose for CHILD_SA, transport, tunnel or BEET
* @param dpd_action what to to with a CHILD_SA when other peer does not respond * @param dpd_action what to to with a CHILD_SA when other peer does not respond
* @return policy_t object * @return policy_t object
* *
@ -343,8 +368,7 @@ policy_t *policy_create(char *name,
identification_t *my_id, identification_t *other_id, identification_t *my_id, identification_t *other_id,
auth_method_t auth_method, auth_method_t auth_method,
u_int32_t hard_lifetime, u_int32_t soft_lifetime, u_int32_t hard_lifetime, u_int32_t soft_lifetime,
u_int32_t jitter, u_int32_t jitter, char *updown, bool hostaccess,
char *updown, bool hostaccess, mode_t mode, dpd_action_t dpd_action);
dpd_action_t dpd_action);
#endif /* POLICY_H_ */ #endif /* POLICY_H_ */

View File

@ -447,15 +447,27 @@ static u_int8_t get_protocol(private_traffic_selector_t *this)
*/ */
static bool is_host(private_traffic_selector_t *this, host_t *host) static bool is_host(private_traffic_selector_t *this, host_t *host)
{ {
chunk_t addr; if (host)
int family = host->get_family(host);
if ((family == AF_INET && this->type == TS_IPV4_ADDR_RANGE) ||
(family == AF_INET6 && this->type == TS_IPV6_ADDR_RANGE))
{ {
addr = host->get_address(host); chunk_t addr;
if (memeq(addr.ptr, this->from, addr.len) && int family = host->get_family(host);
memeq(addr.ptr, this->to, addr.len))
if ((family == AF_INET && this->type == TS_IPV4_ADDR_RANGE) ||
(family == AF_INET6 && this->type == TS_IPV6_ADDR_RANGE))
{
addr = host->get_address(host);
if (memeq(addr.ptr, this->from, addr.len) &&
memeq(addr.ptr, this->to, addr.len))
{
return TRUE;
}
}
}
else
{
size_t length = (this->type == TS_IPV4_ADDR_RANGE) ? 4 : 16;
if (memeq(this->from, this->to, length))
{ {
return TRUE; return TRUE;
} }

View File

@ -164,6 +164,8 @@ struct traffic_selector_t {
* Traffic selector may describe the end of *-to-host tunnel. In this * Traffic selector may describe the end of *-to-host tunnel. In this
* case, the address range is a single address equal to the hosts * case, the address range is a single address equal to the hosts
* peer address. * peer address.
* If host is NULL, the traffic selector is checked if it is a single host,
* but not a specific one.
* *
* @param this calling obect * @param this calling obect
* @param host host_t specifying the address range * @param host host_t specifying the address range

View File

@ -88,6 +88,8 @@ enum notify_type_t {
NO_NATS_ALLOWED = 16402, NO_NATS_ALLOWED = 16402,
/* repeated authentication extension, RFC4478 */ /* repeated authentication extension, RFC4478 */
AUTH_LIFETIME = 16403, AUTH_LIFETIME = 16403,
/* BEET mode, not even a draft yet. private use */
USE_BEET_MODE = 40960,
}; };
/** /**
@ -97,7 +99,6 @@ enum notify_type_t {
*/ */
extern enum_name_t *notify_type_names; extern enum_name_t *notify_type_names;
/** /**
* @brief Class representing an IKEv2-Notify Payload. * @brief Class representing an IKEv2-Notify Payload.
* *

View File

@ -167,6 +167,11 @@ struct private_child_sa_t {
* Specifies if NAT traversal is used * Specifies if NAT traversal is used
*/ */
bool use_natt; bool use_natt;
/**
* mode this SA uses, tunnel/transport
*/
mode_t mode;
}; };
/** /**
@ -439,7 +444,8 @@ static status_t alloc(private_child_sa_t *this, linked_list_t *proposals)
return SUCCESS; return SUCCESS;
} }
static status_t install(private_child_sa_t *this, proposal_t *proposal, prf_plus_t *prf_plus, bool mine) static status_t install(private_child_sa_t *this, proposal_t *proposal,
mode_t mode, prf_plus_t *prf_plus, bool mine)
{ {
u_int32_t spi; u_int32_t spi;
algorithm_t *enc_algo, *int_algo; algorithm_t *enc_algo, *int_algo;
@ -536,7 +542,7 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal, prf_plus
mine ? this->soft_lifetime : 0, mine ? this->soft_lifetime : 0,
this->hard_lifetime, this->hard_lifetime,
enc_algo, int_algo, enc_algo, int_algo,
prf_plus, natt, mine); prf_plus, natt, mode, mine);
this->encryption = *enc_algo; this->encryption = *enc_algo;
this->integrity = *int_algo; this->integrity = *int_algo;
@ -545,7 +551,8 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal, prf_plus
return status; return status;
} }
static status_t add(private_child_sa_t *this, proposal_t *proposal, prf_plus_t *prf_plus) static status_t add(private_child_sa_t *this, proposal_t *proposal,
mode_t mode, prf_plus_t *prf_plus)
{ {
u_int32_t outbound_spi, inbound_spi; u_int32_t outbound_spi, inbound_spi;
@ -560,14 +567,14 @@ static status_t add(private_child_sa_t *this, proposal_t *proposal, prf_plus_t *
inbound_spi = proposal->get_spi(proposal); inbound_spi = proposal->get_spi(proposal);
/* install inbound SAs */ /* install inbound SAs */
if (install(this, proposal, prf_plus, TRUE) != SUCCESS) if (install(this, proposal, mode, prf_plus, TRUE) != SUCCESS)
{ {
return FAILED; return FAILED;
} }
/* install outbound SAs, restore spi*/ /* install outbound SAs, restore spi*/
proposal->set_spi(proposal, outbound_spi); proposal->set_spi(proposal, outbound_spi);
if (install(this, proposal, prf_plus, FALSE) != SUCCESS) if (install(this, proposal, mode, prf_plus, FALSE) != SUCCESS)
{ {
return FAILED; return FAILED;
} }
@ -576,7 +583,8 @@ static status_t add(private_child_sa_t *this, proposal_t *proposal, prf_plus_t *
return SUCCESS; return SUCCESS;
} }
static status_t update(private_child_sa_t *this, proposal_t *proposal, prf_plus_t *prf_plus) static status_t update(private_child_sa_t *this, proposal_t *proposal,
mode_t mode, prf_plus_t *prf_plus)
{ {
u_int32_t inbound_spi; u_int32_t inbound_spi;
@ -584,7 +592,7 @@ static status_t update(private_child_sa_t *this, proposal_t *proposal, prf_plus_
inbound_spi = proposal->get_spi(proposal); inbound_spi = proposal->get_spi(proposal);
/* install outbound SAs */ /* install outbound SAs */
if (install(this, proposal, prf_plus, FALSE) != SUCCESS) if (install(this, proposal, mode, prf_plus, FALSE) != SUCCESS)
{ {
return FAILED; return FAILED;
} }
@ -592,7 +600,7 @@ static status_t update(private_child_sa_t *this, proposal_t *proposal, prf_plus_
/* restore spi */ /* restore spi */
proposal->set_spi(proposal, inbound_spi); proposal->set_spi(proposal, inbound_spi);
/* install inbound SAs */ /* install inbound SAs */
if (install(this, proposal, prf_plus, TRUE) != SUCCESS) if (install(this, proposal, mode, prf_plus, TRUE) != SUCCESS)
{ {
return FAILED; return FAILED;
} }
@ -600,7 +608,9 @@ static status_t update(private_child_sa_t *this, proposal_t *proposal, prf_plus_
return SUCCESS; return SUCCESS;
} }
static status_t add_policies(private_child_sa_t *this, linked_list_t *my_ts_list, linked_list_t *other_ts_list) static status_t add_policies(private_child_sa_t *this,
linked_list_t *my_ts_list,
linked_list_t *other_ts_list, mode_t mode)
{ {
iterator_t *my_iter, *other_iter; iterator_t *my_iter, *other_iter;
traffic_selector_t *my_ts, *other_ts; traffic_selector_t *my_ts, *other_ts;
@ -637,16 +647,16 @@ static status_t add_policies(private_child_sa_t *this, linked_list_t *my_ts_list
/* install 3 policies: out, in and forward */ /* install 3 policies: out, in and forward */
status = charon->kernel_interface->add_policy(charon->kernel_interface, status = charon->kernel_interface->add_policy(charon->kernel_interface,
this->me.addr, this->other.addr, my_ts, other_ts, this->me.addr, this->other.addr, my_ts, other_ts, POLICY_OUT,
POLICY_OUT, this->protocol, this->reqid, high_prio, FALSE); this->protocol, this->reqid, high_prio, mode, FALSE);
status |= charon->kernel_interface->add_policy(charon->kernel_interface, status |= charon->kernel_interface->add_policy(charon->kernel_interface,
this->other.addr, this->me.addr, other_ts, my_ts, this->other.addr, this->me.addr, other_ts, my_ts, POLICY_IN,
POLICY_IN, this->protocol, this->reqid, high_prio, FALSE); this->protocol, this->reqid, high_prio, mode, FALSE);
status |= charon->kernel_interface->add_policy(charon->kernel_interface, status |= charon->kernel_interface->add_policy(charon->kernel_interface,
this->other.addr, this->me.addr, other_ts, my_ts, this->other.addr, this->me.addr, other_ts, my_ts, POLICY_FWD,
POLICY_FWD, this->protocol, this->reqid, high_prio, FALSE); this->protocol, this->reqid, high_prio, mode, FALSE);
if (status != SUCCESS) if (status != SUCCESS)
{ {
@ -673,7 +683,8 @@ static status_t add_policies(private_child_sa_t *this, linked_list_t *my_ts_list
{ {
this->state = CHILD_ROUTED; this->state = CHILD_ROUTED;
} }
/* needed to update hosts */
this->mode = mode;
return SUCCESS; return SUCCESS;
} }
@ -928,19 +939,19 @@ static status_t update_policy_hosts(private_child_sa_t *this, host_t *new_me, ho
charon->kernel_interface, charon->kernel_interface,
new_me, new_other, new_me, new_other,
policy->my_ts, policy->other_ts, policy->my_ts, policy->other_ts,
POLICY_OUT, this->protocol, this->reqid, TRUE, TRUE); POLICY_OUT, this->protocol, this->reqid, TRUE, this->mode, TRUE);
status |= charon->kernel_interface->add_policy( status |= charon->kernel_interface->add_policy(
charon->kernel_interface, charon->kernel_interface,
new_other, new_me, new_other, new_me,
policy->other_ts, policy->my_ts, policy->other_ts, policy->my_ts,
POLICY_IN, this->protocol, this->reqid, TRUE, TRUE); POLICY_IN, this->protocol, this->reqid, TRUE, this->mode, TRUE);
status |= charon->kernel_interface->add_policy( status |= charon->kernel_interface->add_policy(
charon->kernel_interface, charon->kernel_interface,
new_other, new_me, new_other, new_me,
policy->other_ts, policy->my_ts, policy->other_ts, policy->my_ts,
POLICY_FWD, this->protocol, this->reqid, TRUE, TRUE); POLICY_FWD, this->protocol, this->reqid, TRUE, this->mode, TRUE);
if (status != SUCCESS) if (status != SUCCESS)
{ {
@ -1085,10 +1096,10 @@ child_sa_t * child_sa_create(u_int32_t rekey, host_t *me, host_t* other,
this->public.get_spi = (u_int32_t(*)(child_sa_t*, bool))get_spi; this->public.get_spi = (u_int32_t(*)(child_sa_t*, bool))get_spi;
this->public.get_protocol = (protocol_id_t(*)(child_sa_t*))get_protocol; this->public.get_protocol = (protocol_id_t(*)(child_sa_t*))get_protocol;
this->public.alloc = (status_t(*)(child_sa_t*,linked_list_t*))alloc; this->public.alloc = (status_t(*)(child_sa_t*,linked_list_t*))alloc;
this->public.add = (status_t(*)(child_sa_t*,proposal_t*,prf_plus_t*))add; this->public.add = (status_t(*)(child_sa_t*,proposal_t*,mode_t,prf_plus_t*))add;
this->public.update = (status_t(*)(child_sa_t*,proposal_t*,prf_plus_t*))update; this->public.update = (status_t(*)(child_sa_t*,proposal_t*,mode_t,prf_plus_t*))update;
this->public.update_hosts = (status_t (*)(child_sa_t*,host_t*,host_t*,host_diff_t,host_diff_t))update_hosts; this->public.update_hosts = (status_t (*)(child_sa_t*,host_t*,host_t*,host_diff_t,host_diff_t))update_hosts;
this->public.add_policies = (status_t (*)(child_sa_t*, linked_list_t*,linked_list_t*))add_policies; this->public.add_policies = (status_t (*)(child_sa_t*, linked_list_t*,linked_list_t*,mode_t))add_policies;
this->public.get_my_traffic_selectors = (linked_list_t*(*)(child_sa_t*))get_my_traffic_selectors; this->public.get_my_traffic_selectors = (linked_list_t*(*)(child_sa_t*))get_my_traffic_selectors;
this->public.get_other_traffic_selectors = (linked_list_t*(*)(child_sa_t*))get_other_traffic_selectors; this->public.get_other_traffic_selectors = (linked_list_t*(*)(child_sa_t*))get_other_traffic_selectors;
this->public.get_use_time = (status_t (*)(child_sa_t*,bool,time_t*))get_use_time; this->public.get_use_time = (status_t (*)(child_sa_t*,bool,time_t*))get_use_time;
@ -1124,6 +1135,7 @@ child_sa_t * child_sa_create(u_int32_t rekey, host_t *me, host_t* other,
this->my_ts = linked_list_create(); this->my_ts = linked_list_create();
this->other_ts = linked_list_create(); this->other_ts = linked_list_create();
this->protocol = PROTO_NONE; this->protocol = PROTO_NONE;
this->mode = MODE_TUNNEL;
this->rekeying_transaction = NULL; this->rekeying_transaction = NULL;
return &this->public; return &this->public;

View File

@ -167,10 +167,12 @@ struct child_sa_t {
* *
* @param this calling object * @param this calling object
* @param proposal proposal for which SPIs are allocated * @param proposal proposal for which SPIs are allocated
* @param mode mode for the CHILD_SA
* @param prf_plus key material to use for key derivation * @param prf_plus key material to use for key derivation
* @return SUCCESS or FAILED * @return SUCCESS or FAILED
*/ */
status_t (*add)(child_sa_t *this, proposal_t *proposal, prf_plus_t *prf_plus); status_t (*add)(child_sa_t *this, proposal_t *proposal, mode_t mode,
prf_plus_t *prf_plus);
/** /**
* @brief Install the kernel SAs for a proposal, after SPIs have been allocated. * @brief Install the kernel SAs for a proposal, after SPIs have been allocated.
@ -179,10 +181,12 @@ struct child_sa_t {
* *
* @param this calling object * @param this calling object
* @param proposal proposal for which SPIs are allocated * @param proposal proposal for which SPIs are allocated
* @param mode mode for the CHILD_SA
* @param prf_plus key material to use for key derivation * @param prf_plus key material to use for key derivation
* @return SUCCESS or FAILED * @return SUCCESS or FAILED
*/ */
status_t (*update)(child_sa_t *this, proposal_t *proposal, prf_plus_t *prf_plus); status_t (*update)(child_sa_t *this, proposal_t *proposal, mode_t mode,
prf_plus_t *prf_plus);
/** /**
* @brief Update the hosts in the kernel SAs and policies * @brief Update the hosts in the kernel SAs and policies
@ -208,11 +212,11 @@ struct child_sa_t {
* @param this calling object * @param this calling object
* @param my_ts traffic selectors for local site * @param my_ts traffic selectors for local site
* @param other_ts traffic selectors for remote site * @param other_ts traffic selectors for remote site
* @param mode mode for the SA: tunnel/transport
* @return SUCCESS or FAILED * @return SUCCESS or FAILED
*/ */
status_t (*add_policies)(child_sa_t *this, status_t (*add_policies)(child_sa_t *this, linked_list_t *my_ts_list,
linked_list_t *my_ts_list, linked_list_t *other_ts_list, mode_t mode);
linked_list_t *other_ts_list);
/** /**
* @brief Get the traffic selectors of added policies of local host. * @brief Get the traffic selectors of added policies of local host.

View File

@ -1173,7 +1173,8 @@ static status_t route(private_ike_sa_t *this, connection_t *connection, policy_t
child_sa->set_name(child_sa, policy->get_name(policy)); child_sa->set_name(child_sa, policy->get_name(policy));
my_ts = policy->get_my_traffic_selectors(policy, this->my_host); my_ts = policy->get_my_traffic_selectors(policy, this->my_host);
other_ts = policy->get_other_traffic_selectors(policy, this->other_host); other_ts = policy->get_other_traffic_selectors(policy, this->other_host);
status = child_sa->add_policies(child_sa, my_ts, other_ts); status = child_sa->add_policies(child_sa, my_ts, other_ts,
policy->get_mode(policy));
my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy)); my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy));
other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy)); other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy));
this->child_sas->insert_last(this->child_sas, child_sa); this->child_sas->insert_last(this->child_sas, child_sa);

View File

@ -119,6 +119,11 @@ struct private_create_child_sa_t {
*/ */
child_sa_t *rekeyed_sa; child_sa_t *rekeyed_sa;
/**
* mode of the CHILD_SA to create: transport/tunnel
*/
mode_t mode;
/** /**
* Have we lost the simultaneous rekeying nonce compare? * Have we lost the simultaneous rekeying nonce compare?
*/ */
@ -186,6 +191,31 @@ static void cancel(private_create_child_sa_t *this)
this->lost = TRUE; this->lost = TRUE;
} }
/**
* Build a notify message.
*/
static void build_notify(notify_type_t type, chunk_t data, message_t *message, bool flush_message)
{
notify_payload_t *notify;
if (flush_message)
{
payload_t *payload;
iterator_t *iterator = message->get_payload_iterator(message);
while (iterator->iterate(iterator, (void**)&payload))
{
payload->destroy(payload);
iterator->remove(iterator);
}
iterator->destroy(iterator);
}
notify = notify_payload_create();
notify->set_notify_type(notify, type);
notify->set_notification_data(notify, data);
message->add_payload(message, (payload_t*)notify);
}
/** /**
* Implementation of transaction_t.get_request. * Implementation of transaction_t.get_request.
*/ */
@ -293,6 +323,28 @@ static status_t get_request(private_create_child_sa_t *this, message_t **result)
request->add_payload(request, (payload_t*)sa_payload); request->add_payload(request, (payload_t*)sa_payload);
} }
/* notify for transport/BEET mode, we propose it
* independent of the traffic selectors */
switch (this->policy->get_mode(this->policy))
{
case MODE_TUNNEL:
/* is the default */
break;
case MODE_TRANSPORT:
if (this->ike_sa->is_natt_enabled(this->ike_sa))
{
DBG1(DBG_IKE, "not using tranport mode, as connection NATed");
}
else
{
build_notify(USE_TRANSPORT_MODE, chunk_empty, request, FALSE);
}
break;
case MODE_BEET:
build_notify(USE_BEET_MODE, chunk_empty, request, FALSE);
break;
}
{ /* build the NONCE payload for us (initiator) */ { /* build the NONCE payload for us (initiator) */
nonce_payload_t *nonce_payload; nonce_payload_t *nonce_payload;
@ -374,6 +426,16 @@ static status_t process_notifys(private_create_child_sa_t *this, notify_payload_
SIG(this->failsig, "received NO_PROPOSAL_CHOSEN notify"); SIG(this->failsig, "received NO_PROPOSAL_CHOSEN notify");
return FAILED; return FAILED;
} }
case USE_TRANSPORT_MODE:
{
this->mode = MODE_TRANSPORT;
return SUCCESS;
}
case USE_BEET_MODE:
{
this->mode = MODE_BEET;
return SUCCESS;
}
case REKEY_SA: case REKEY_SA:
{ {
u_int32_t spi; u_int32_t spi;
@ -414,28 +476,20 @@ static status_t process_notifys(private_create_child_sa_t *this, notify_payload_
} }
/** /**
* Build a notify message. * Check a list of traffic selectors if any selector belongs to host
*/ */
static void build_notify(notify_type_t type, chunk_t data, message_t *message, bool flush_message) static bool ts_list_is_host(linked_list_t *list, host_t *host)
{ {
notify_payload_t *notify; traffic_selector_t *ts;
bool is_host = TRUE;
iterator_t *iterator = list->create_iterator(list, TRUE);
if (flush_message) while (is_host && iterator->iterate(iterator, (void**)&ts))
{ {
payload_t *payload; is_host = is_host && ts->is_host(ts, host);
iterator_t *iterator = message->get_payload_iterator(message);
while (iterator->iterate(iterator, (void**)&payload))
{
payload->destroy(payload);
iterator->remove(iterator);
}
iterator->destroy(iterator);
} }
iterator->destroy(iterator);
notify = notify_payload_create(); return is_host;
notify->set_notify_type(notify, type);
notify->set_notification_data(notify, data);
message->add_payload(message, (payload_t*)notify);
} }
/** /**
@ -455,11 +509,11 @@ static status_t install_child_sa(private_create_child_sa_t *this, bool initiator
if (initiator) if (initiator)
{ {
status = this->child_sa->update(this->child_sa, this->proposal, prf_plus); status = this->child_sa->update(this->child_sa, this->proposal, 1, prf_plus);
} }
else else
{ {
status = this->child_sa->add(this->child_sa, this->proposal, prf_plus); status = this->child_sa->add(this->child_sa, this->proposal, 1, prf_plus);
} }
prf_plus->destroy(prf_plus); prf_plus->destroy(prf_plus);
if (status != SUCCESS) if (status != SUCCESS)
@ -468,11 +522,11 @@ static status_t install_child_sa(private_create_child_sa_t *this, bool initiator
} }
if (initiator) if (initiator)
{ {
status = this->child_sa->add_policies(this->child_sa, this->tsi, this->tsr); status = this->child_sa->add_policies(this->child_sa, this->tsi, this->tsr, 1);
} }
else else
{ {
status = this->child_sa->add_policies(this->child_sa, this->tsr, this->tsi); status = this->child_sa->add_policies(this->child_sa, this->tsr, this->tsi, 1);
} }
if (status != SUCCESS) if (status != SUCCESS)
{ {
@ -697,6 +751,44 @@ static status_t get_response(private_create_child_sa_t *this, message_t *request
this->policy->get_hostaccess(this->policy), this->policy->get_hostaccess(this->policy),
use_natt); use_natt);
this->child_sa->set_name(this->child_sa, this->policy->get_name(this->policy)); this->child_sa->set_name(this->child_sa, this->policy->get_name(this->policy));
/* check mode, and include notify into reply */
switch (this->mode)
{
case MODE_TUNNEL:
/* is the default */
break;
case MODE_TRANSPORT:
if (!ts_list_is_host(this->tsi, other) ||
!ts_list_is_host(this->tsr, me))
{
this->mode = MODE_TUNNEL;
DBG1(DBG_IKE, "not using tranport mode, not host-to-host");
}
else if (this->ike_sa->is_natt_enabled(this->ike_sa))
{
this->mode = MODE_TUNNEL;
DBG1(DBG_IKE, "not using tranport mode, as connection NATed");
}
else
{
build_notify(USE_TRANSPORT_MODE, chunk_empty, response, FALSE);
}
break;
case MODE_BEET:
if (!ts_list_is_host(this->tsi, NULL) ||
!ts_list_is_host(this->tsr, NULL))
{
this->mode = MODE_TUNNEL;
DBG1(DBG_IKE, "not using BEET mode, not host-to-host");
}
else
{
build_notify(USE_BEET_MODE, chunk_empty, response, FALSE);
}
break;
}
if (install_child_sa(this, FALSE) != SUCCESS) if (install_child_sa(this, FALSE) != SUCCESS)
{ {
SIG(this->failsig, "installing CHILD_SA failed, sending NO_PROPOSAL_CHOSEN notify"); SIG(this->failsig, "installing CHILD_SA failed, sending NO_PROPOSAL_CHOSEN notify");
@ -855,6 +947,38 @@ static status_t conclude(private_create_child_sa_t *this, message_t *response,
SIG(this->failsig, "CHILD_SA negotiation failed, no CHILD_SA built"); SIG(this->failsig, "CHILD_SA negotiation failed, no CHILD_SA built");
return FAILED; return FAILED;
} }
/* check mode if it is acceptable */
switch (this->mode)
{
case MODE_TUNNEL:
/* is the default */
break;
case MODE_TRANSPORT:
/* TODO: we should close the CHILD_SA if negotiated
* mode is not acceptable for us */
if (!ts_list_is_host(this->tsi, me) ||
!ts_list_is_host(this->tsr, other))
{
this->mode = MODE_TUNNEL;
DBG1(DBG_IKE, "not using tranport mode, not host-to-host");
}
else if (this->ike_sa->is_natt_enabled(this->ike_sa))
{
this->mode = MODE_TUNNEL;
DBG1(DBG_IKE, "not using tranport mode, as connection NATed");
}
break;
case MODE_BEET:
if (!ts_list_is_host(this->tsi, NULL) ||
!ts_list_is_host(this->tsr, NULL))
{
this->mode = MODE_TUNNEL;
DBG1(DBG_IKE, "not using BEET mode, not host-to-host");
}
break;
}
new_child = this->child_sa; new_child = this->child_sa;
if (install_child_sa(this, TRUE) != SUCCESS) if (install_child_sa(this, TRUE) != SUCCESS)
{ {
@ -985,6 +1109,7 @@ create_child_sa_t *create_child_sa_create(ike_sa_t *ike_sa)
this->policy = NULL; this->policy = NULL;
this->tsi = NULL; this->tsi = NULL;
this->tsr = NULL; this->tsr = NULL;
this->mode = MODE_TUNNEL;
this->randomizer = randomizer_create(); this->randomizer = randomizer_create();
this->failsig = CHILD_UP_FAILED; this->failsig = CHILD_UP_FAILED;

View File

@ -128,6 +128,11 @@ struct private_ike_auth_t {
* reqid to use for CHILD_SA setup * reqid to use for CHILD_SA setup
*/ */
u_int32_t reqid; u_int32_t reqid;
/**
* mode the CHILD_SA uses: tranport, tunnel, BEET
*/
mode_t mode;
}; };
/** /**
@ -182,6 +187,30 @@ static void set_init_messages(private_ike_auth_t *this, chunk_t init_request, ch
this->init_response = init_response; this->init_response = init_response;
} }
/**
* Build a notify message.
*/
static void build_notify(notify_type_t type, message_t *message, bool flush_message)
{
notify_payload_t *notify;
if (flush_message)
{
payload_t *payload;
iterator_t *iterator = message->get_payload_iterator(message);
while (iterator->iterate(iterator, (void**)&payload))
{
payload->destroy(payload);
iterator->remove(iterator);
}
iterator->destroy(iterator);
}
notify = notify_payload_create();
notify->set_notify_type(notify, type);
message->add_payload(message, (payload_t*)notify);
}
/** /**
* Implementation of transaction_t.get_request. * Implementation of transaction_t.get_request.
*/ */
@ -319,6 +348,28 @@ static status_t get_request(private_ike_auth_t *this, message_t **result)
request->add_payload(request, (payload_t*)sa_payload); request->add_payload(request, (payload_t*)sa_payload);
} }
/* notify for transport/BEET mode, we propose it
* independent of the traffic selectors */
switch (this->policy->get_mode(this->policy))
{
case MODE_TUNNEL:
/* is the default */
break;
case MODE_TRANSPORT:
if (this->ike_sa->is_natt_enabled(this->ike_sa))
{
DBG1(DBG_IKE, "not using tranport mode, as connection NATed");
}
else
{
build_notify(USE_TRANSPORT_MODE, request, FALSE);
}
break;
case MODE_BEET:
build_notify(USE_BEET_MODE, request, FALSE);
break;
}
{ /* build TSi payload */ { /* build TSi payload */
linked_list_t *ts_list; linked_list_t *ts_list;
ts_payload_t *ts_payload; ts_payload_t *ts_payload;
@ -376,6 +427,16 @@ static status_t process_notifies(private_ike_auth_t *this, notify_payload_t *not
this->build_child = FALSE; this->build_child = FALSE;
return SUCCESS; return SUCCESS;
} }
case USE_TRANSPORT_MODE:
{
this->mode = MODE_TRANSPORT;
return SUCCESS;
}
case USE_BEET_MODE:
{
this->mode = MODE_BEET;
return SUCCESS;
}
default: default:
{ {
if (notify_type < 16383) if (notify_type < 16383)
@ -394,30 +455,6 @@ static status_t process_notifies(private_ike_auth_t *this, notify_payload_t *not
} }
} }
/**
* Build a notify message.
*/
static void build_notify(notify_type_t type, message_t *message, bool flush_message)
{
notify_payload_t *notify;
if (flush_message)
{
payload_t *payload;
iterator_t *iterator = message->get_payload_iterator(message);
while (iterator->iterate(iterator, (void**)&payload))
{
payload->destroy(payload);
iterator->remove(iterator);
}
iterator->destroy(iterator);
}
notify = notify_payload_create();
notify->set_notify_type(notify, type);
message->add_payload(message, (payload_t*)notify);
}
/** /**
* Import certificate requests from a certreq payload * Import certificate requests from a certreq payload
*/ */
@ -501,6 +538,23 @@ static void import_certificate(cert_payload_t *cert_payload)
} }
} }
/**
* Check a list of traffic selectors if any selector belongs to host
*/
static bool ts_list_is_host(linked_list_t *list, host_t *host)
{
traffic_selector_t *ts;
bool is_host = TRUE;
iterator_t *iterator = list->create_iterator(list, TRUE);
while (is_host && iterator->iterate(iterator, (void**)&ts))
{
is_host = is_host && ts->is_host(ts, host);
}
iterator->destroy(iterator);
return is_host;
}
/** /**
* Install a CHILD_SA for usage * Install a CHILD_SA for usage
*/ */
@ -518,11 +572,13 @@ static status_t install_child_sa(private_ike_auth_t *this, bool initiator)
if (initiator) if (initiator)
{ {
status = this->child_sa->update(this->child_sa, this->proposal, prf_plus); status = this->child_sa->update(this->child_sa, this->proposal,
this->mode, prf_plus);
} }
else else
{ {
status = this->child_sa->add(this->child_sa, this->proposal, prf_plus); status = this->child_sa->add(this->child_sa, this->proposal,
this->mode, prf_plus);
} }
prf_plus->destroy(prf_plus); prf_plus->destroy(prf_plus);
if (status != SUCCESS) if (status != SUCCESS)
@ -531,11 +587,13 @@ static status_t install_child_sa(private_ike_auth_t *this, bool initiator)
} }
if (initiator) if (initiator)
{ {
status = this->child_sa->add_policies(this->child_sa, this->tsi, this->tsr); status = this->child_sa->add_policies(this->child_sa, this->tsi,
this->tsr, this->mode);
} }
else else
{ {
status = this->child_sa->add_policies(this->child_sa, this->tsr, this->tsi); status = this->child_sa->add_policies(this->child_sa, this->tsr,
this->tsi, this->mode);
} }
if (status != SUCCESS) if (status != SUCCESS)
{ {
@ -850,6 +908,44 @@ static status_t get_response(private_ike_auth_t *this, message_t *request,
this->policy->get_hostaccess(this->policy), this->policy->get_hostaccess(this->policy),
use_natt); use_natt);
this->child_sa->set_name(this->child_sa, this->policy->get_name(this->policy)); this->child_sa->set_name(this->child_sa, this->policy->get_name(this->policy));
/* check mode, and include notify into reply */
switch (this->mode)
{
case MODE_TUNNEL:
/* is the default */
break;
case MODE_TRANSPORT:
if (!ts_list_is_host(this->tsi, other) ||
!ts_list_is_host(this->tsr, me))
{
this->mode = MODE_TUNNEL;
DBG1(DBG_IKE, "not using tranport mode, not host-to-host");
}
else if (this->ike_sa->is_natt_enabled(this->ike_sa))
{
this->mode = MODE_TUNNEL;
DBG1(DBG_IKE, "not using tranport mode, as connection NATed");
}
else
{
build_notify(USE_TRANSPORT_MODE, response, FALSE);
}
break;
case MODE_BEET:
if (!ts_list_is_host(this->tsi, NULL) ||
!ts_list_is_host(this->tsr, NULL))
{
this->mode = MODE_TUNNEL;
DBG1(DBG_IKE, "not using BEET mode, not host-to-host");
}
else
{
build_notify(USE_BEET_MODE, response, FALSE);
}
break;
}
if (install_child_sa(this, FALSE) != SUCCESS) if (install_child_sa(this, FALSE) != SUCCESS)
{ {
SIG(CHILD_UP_FAILED, "installing CHILD_SA failed, no CHILD_SA created"); SIG(CHILD_UP_FAILED, "installing CHILD_SA failed, no CHILD_SA created");
@ -1048,6 +1144,37 @@ static status_t conclude(private_ike_auth_t *this, message_t *response,
} }
else else
{ {
/* check mode if it is acceptable */
switch (this->mode)
{
case MODE_TUNNEL:
/* is the default */
break;
case MODE_TRANSPORT:
/* TODO: we should close the CHILD_SA if negotiated
* mode is not acceptable for us */
if (!ts_list_is_host(this->tsi, me) ||
!ts_list_is_host(this->tsr, other))
{
this->mode = MODE_TUNNEL;
DBG1(DBG_IKE, "not using tranport mode, not host-to-host");
}
else if (this->ike_sa->is_natt_enabled(this->ike_sa))
{
this->mode = MODE_TUNNEL;
DBG1(DBG_IKE, "not using tranport mode, as connection NATed");
}
break;
case MODE_BEET:
if (!ts_list_is_host(this->tsi, NULL) ||
!ts_list_is_host(this->tsr, NULL))
{
this->mode = MODE_TUNNEL;
DBG1(DBG_IKE, "not using BEET mode, not host-to-host");
}
break;
}
if (install_child_sa(this, TRUE) != SUCCESS) if (install_child_sa(this, TRUE) != SUCCESS)
{ {
SIG(CHILD_UP_FAILED, "installing CHILD_SA failed, no CHILD_SA built"); SIG(CHILD_UP_FAILED, "installing CHILD_SA failed, no CHILD_SA built");
@ -1126,6 +1253,7 @@ ike_auth_t *ike_auth_create(ike_sa_t *ike_sa)
this->tsr = NULL; this->tsr = NULL;
this->build_child = TRUE; this->build_child = TRUE;
this->reqid = 0; this->reqid = 0;
this->mode = MODE_TUNNEL;
return &this->public; return &this->public;
} }

View File

@ -503,7 +503,7 @@ static status_t add_sa(private_kernel_interface_t *this,
protocol_id_t protocol, u_int32_t reqid, protocol_id_t protocol, u_int32_t reqid,
u_int64_t expire_soft, u_int64_t expire_hard, u_int64_t expire_soft, u_int64_t expire_hard,
algorithm_t *enc_alg, algorithm_t *int_alg, algorithm_t *enc_alg, algorithm_t *int_alg,
prf_plus_t *prf_plus, natt_conf_t *natt, prf_plus_t *prf_plus, natt_conf_t *natt, mode_t mode,
bool replace) bool replace)
{ {
unsigned char request[BUFFER_SIZE]; unsigned char request[BUFFER_SIZE];
@ -529,7 +529,7 @@ static status_t add_sa(private_kernel_interface_t *this,
sa->id.spi = spi; sa->id.spi = spi;
sa->id.proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH; sa->id.proto = (protocol == PROTO_ESP) ? KERNEL_ESP : KERNEL_AH;
sa->family = src->get_family(src); sa->family = src->get_family(src);
sa->mode = TRUE; /* tunnel mode */ sa->mode = mode;
sa->replay_window = 32; sa->replay_window = 32;
sa->reqid = reqid; sa->reqid = reqid;
/* we currently do not expire SAs by volume/packet count */ /* we currently do not expire SAs by volume/packet count */
@ -970,7 +970,8 @@ static status_t add_policy(private_kernel_interface_t *this,
traffic_selector_t *src_ts, traffic_selector_t *src_ts,
traffic_selector_t *dst_ts, traffic_selector_t *dst_ts,
policy_dir_t direction, protocol_id_t protocol, policy_dir_t direction, protocol_id_t protocol,
u_int32_t reqid, bool high_prio, bool update) u_int32_t reqid, bool high_prio, mode_t mode,
bool update)
{ {
iterator_t *iterator; iterator_t *iterator;
kernel_policy_t *current, *policy; kernel_policy_t *current, *policy;
@ -992,7 +993,7 @@ static status_t add_policy(private_kernel_interface_t *this,
iterator = this->policies->create_iterator(this->policies, TRUE); iterator = this->policies->create_iterator(this->policies, TRUE);
while (iterator->iterate(iterator, (void**)&current)) while (iterator->iterate(iterator, (void**)&current))
{ {
if (memcmp(current, policy, sizeof(struct xfrm_selector)) == 0 && if (memcmp(&current->sel, &policy->sel, sizeof(struct xfrm_selector)) == 0 &&
policy->direction == current->direction) policy->direction == current->direction)
{ {
free(policy); free(policy);
@ -1068,7 +1069,7 @@ static status_t add_policy(private_kernel_interface_t *this,
tmpl->reqid = reqid; tmpl->reqid = reqid;
tmpl->id.proto = (protocol == PROTO_AH) ? KERNEL_AH : KERNEL_ESP; tmpl->id.proto = (protocol == PROTO_AH) ? KERNEL_AH : KERNEL_ESP;
tmpl->aalgos = tmpl->ealgos = tmpl->calgos = ~0; tmpl->aalgos = tmpl->ealgos = tmpl->calgos = ~0;
tmpl->mode = TRUE; tmpl->mode = mode;
tmpl->family = src->get_family(src); tmpl->family = src->get_family(src);
host2xfrm(src, &tmpl->saddr); host2xfrm(src, &tmpl->saddr);
@ -1266,11 +1267,11 @@ kernel_interface_t *kernel_interface_create()
/* public functions */ /* public functions */
this->public.get_spi = (status_t(*)(kernel_interface_t*,host_t*,host_t*,protocol_id_t,u_int32_t,u_int32_t*))get_spi; this->public.get_spi = (status_t(*)(kernel_interface_t*,host_t*,host_t*,protocol_id_t,u_int32_t,u_int32_t*))get_spi;
this->public.add_sa = (status_t(*)(kernel_interface_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,algorithm_t*,algorithm_t*,prf_plus_t*,natt_conf_t*,bool))add_sa; this->public.add_sa = (status_t(*)(kernel_interface_t *,host_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t,u_int64_t,u_int64_t,algorithm_t*,algorithm_t*,prf_plus_t*,natt_conf_t*,mode_t,bool))add_sa;
this->public.update_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t,host_t*,host_t*,host_diff_t,host_diff_t))update_sa; this->public.update_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t,host_t*,host_t*,host_diff_t,host_diff_t))update_sa;
this->public.query_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t*))query_sa; this->public.query_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t,u_int32_t*))query_sa;
this->public.del_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t))del_sa; this->public.del_sa = (status_t(*)(kernel_interface_t*,host_t*,u_int32_t,protocol_id_t))del_sa;
this->public.add_policy = (status_t(*)(kernel_interface_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,protocol_id_t,u_int32_t,bool,bool))add_policy; this->public.add_policy = (status_t(*)(kernel_interface_t*,host_t*,host_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,protocol_id_t,u_int32_t,bool,mode_t,bool))add_policy;
this->public.query_policy = (status_t(*)(kernel_interface_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy; this->public.query_policy = (status_t(*)(kernel_interface_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t,u_int32_t*))query_policy;
this->public.del_policy = (status_t(*)(kernel_interface_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t))del_policy; this->public.del_policy = (status_t(*)(kernel_interface_t*,traffic_selector_t*,traffic_selector_t*,policy_dir_t))del_policy;
this->public.destroy = (void(*)(kernel_interface_t*)) destroy; this->public.destroy = (void(*)(kernel_interface_t*)) destroy;

View File

@ -118,6 +118,7 @@ struct kernel_interface_t {
* @param int_alg Algorithm to use for integrity protection * @param int_alg Algorithm to use for integrity protection
* @param prf_plus PRF to derive keys from * @param prf_plus PRF to derive keys from
* @param natt NAT-T Configuration, or NULL of no NAT-T used * @param natt NAT-T Configuration, or NULL of no NAT-T used
* @param mode mode of the SA (tunnel, transport)
* @param replace Should an already installed SA be updated? * @param replace Should an already installed SA be updated?
* @return * @return
* - SUCCESS * - SUCCESS
@ -128,7 +129,8 @@ struct kernel_interface_t {
protocol_id_t protocol, u_int32_t reqid, protocol_id_t protocol, u_int32_t reqid,
u_int64_t expire_soft, u_int64_t expire_hard, u_int64_t expire_soft, u_int64_t expire_hard,
algorithm_t *enc_alg, algorithm_t *int_alg, algorithm_t *enc_alg, algorithm_t *int_alg,
prf_plus_t *prf_plus, natt_conf_t *natt, bool update); prf_plus_t *prf_plus, natt_conf_t *natt,
mode_t mode, bool update);
/** /**
* @brief Update the hosts on an installed SA. * @brief Update the hosts on an installed SA.
@ -206,6 +208,7 @@ struct kernel_interface_t {
* @param protocol protocol to use to protect traffic (AH/ESP) * @param protocol protocol to use to protect traffic (AH/ESP)
* @param reqid uniqe ID of an SA to use to enforce policy * @param reqid uniqe ID of an SA to use to enforce policy
* @param high_prio if TRUE, uses a higher priority than any with FALSE * @param high_prio if TRUE, uses a higher priority than any with FALSE
* @param mode mode of SA (tunnel, transport)
* @param update update an existing policy, if TRUE * @param update update an existing policy, if TRUE
* @return * @return
* - SUCCESS * - SUCCESS
@ -216,7 +219,8 @@ struct kernel_interface_t {
traffic_selector_t *src_ts, traffic_selector_t *src_ts,
traffic_selector_t *dst_ts, traffic_selector_t *dst_ts,
policy_dir_t direction, protocol_id_t protocol, policy_dir_t direction, protocol_id_t protocol,
u_int32_t reqid, bool high_prio, bool update); u_int32_t reqid, bool high_prio,
mode_t mode, bool update);
/** /**
* @brief Query the use time of a policy. * @brief Query the use time of a policy.

View File

@ -398,7 +398,7 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
msg->add_conn.rekey.ipsec_lifetime - msg->add_conn.rekey.margin, msg->add_conn.rekey.ipsec_lifetime - msg->add_conn.rekey.margin,
msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100, msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100,
msg->add_conn.me.updown, msg->add_conn.me.hostaccess, msg->add_conn.me.updown, msg->add_conn.me.hostaccess,
msg->add_conn.dpd.action); msg->add_conn.mode, msg->add_conn.dpd.action);
policy->add_my_traffic_selector(policy, my_ts); policy->add_my_traffic_selector(policy, my_ts);
policy->add_other_traffic_selector(policy, other_ts); policy->add_other_traffic_selector(policy, other_ts);
policy->add_authorities(policy, my_ca, other_ca); policy->add_authorities(policy, my_ca, other_ca);

View File

@ -234,9 +234,11 @@ signifying that no IPsec processing should be done at all;
signifying that packets should be discarded; and signifying that packets should be discarded; and
.BR reject , .BR reject ,
signifying that packets should be discarded and a diagnostic ICMP returned. signifying that packets should be discarded and a diagnostic ICMP returned.
Charon currently supports only the Charon currently supports only
.BR tunnel .BR tunnel
connection type. and
.BR transport
connection types.
.TP .TP
.B left .B left
(required) (required)

View File

@ -194,6 +194,7 @@ int starter_stroke_add_conn(starter_conn_t *conn)
msg.add_conn.name = push_string(&msg, connection_name(conn)); msg.add_conn.name = push_string(&msg, connection_name(conn));
msg.add_conn.auth_method = (conn->policy & POLICY_PSK)? msg.add_conn.auth_method = (conn->policy & POLICY_PSK)?
SHARED_KEY_MESSAGE_INTEGRITY_CODE : RSA_DIGITAL_SIGNATURE; SHARED_KEY_MESSAGE_INTEGRITY_CODE : RSA_DIGITAL_SIGNATURE;
msg.add_conn.mode = (conn->policy & POLICY_TUNNEL) ? 1 : 0;
if (conn->policy & POLICY_DONT_REKEY) if (conn->policy & POLICY_DONT_REKEY)
{ {

View File

@ -106,6 +106,7 @@ static int add_connection(char *name,
msg.add_conn.name = push_string(&msg, name); msg.add_conn.name = push_string(&msg, name);
msg.add_conn.ikev2 = 1; msg.add_conn.ikev2 = 1;
msg.add_conn.mode = 1;
msg.add_conn.rekey.reauth = 0; msg.add_conn.rekey.reauth = 0;
msg.add_conn.rekey.ipsec_lifetime = 0; msg.add_conn.rekey.ipsec_lifetime = 0;

View File

@ -137,6 +137,7 @@ struct stroke_msg_t {
char *name; char *name;
int ikev2; int ikev2;
int auth_method; int auth_method;
int mode;
struct { struct {
char *ike; char *ike;
char *esp; char *esp;