Merge branch 'ikev1-pushmode'
Implements Mode Config Push mode in IKEv1 using the existing modeconfig=push ipsec.conf option.
This commit is contained in:
+1
-2
@@ -931,8 +931,7 @@ Accepted values are
|
||||
and
|
||||
.B pull
|
||||
(the default).
|
||||
Push mode is currently not supported in charon, hence this parameter has no
|
||||
effect.
|
||||
Push mode is currently not supported with IKEv2.
|
||||
.TP
|
||||
.BR reauth " = " yes " | no"
|
||||
whether rekeying of an IKE_SA should also reauthenticate the peer. In IKEv1,
|
||||
|
||||
@@ -170,7 +170,7 @@ static peer_cfg_t* create_peer_cfg(private_cmd_connection_t *this)
|
||||
CERT_SEND_IF_ASKED, UNIQUE_REPLACE, 1, /* keyingtries */
|
||||
36000, 0, /* rekey 10h, reauth none */
|
||||
600, 600, /* jitter, over 10min */
|
||||
TRUE, aggressive, /* mobike, aggressive */
|
||||
TRUE, aggressive, TRUE, /* mobike, aggressive, pull */
|
||||
30, 0, /* DPD delay, timeout */
|
||||
FALSE, NULL, NULL); /* mediation */
|
||||
peer_cfg->add_virtual_ip(peer_cfg, host_create_from_string("0.0.0.0", 0));
|
||||
|
||||
@@ -536,7 +536,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
||||
CERT_SEND_IF_ASKED, UNIQUE_REPLACE, 1, /* keyingtries */
|
||||
36000, 0, /* rekey 10h, reauth none */
|
||||
600, 600, /* jitter, over 10min */
|
||||
TRUE, FALSE, /* mobike, aggressive */
|
||||
TRUE, FALSE, TRUE, /* mobike, aggressive, pull */
|
||||
0, 0, /* DPD delay, timeout */
|
||||
FALSE, NULL, NULL); /* mediation */
|
||||
if (virtual)
|
||||
|
||||
@@ -249,8 +249,8 @@ static peer_cfg_t *load_peer_config(private_config_t *this,
|
||||
|
||||
ike_cfg = load_ike_config(this, settings, config);
|
||||
peer_cfg = peer_cfg_create(config, ike_cfg, CERT_ALWAYS_SEND,
|
||||
UNIQUE_NO, 1, 0, 0, 0, 0, FALSE, FALSE, 0, 0,
|
||||
FALSE, NULL, NULL);
|
||||
UNIQUE_NO, 1, 0, 0, 0, 0, FALSE, FALSE, TRUE,
|
||||
0, 0, FALSE, NULL, NULL);
|
||||
|
||||
auth = auth_cfg_create();
|
||||
auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PUBKEY);
|
||||
|
||||
@@ -535,7 +535,7 @@ static job_requeue_t initiate(private_android_service_t *this)
|
||||
UNIQUE_REPLACE, 0, /* keyingtries */
|
||||
36000, 0, /* rekey 10h, reauth none */
|
||||
600, 600, /* jitter, over 10min */
|
||||
TRUE, FALSE, /* mobike, aggressive */
|
||||
TRUE, FALSE, TRUE, /* mobike, aggressive, pull */
|
||||
0, 0, /* DPD delay, timeout */
|
||||
FALSE, NULL, NULL); /* mediation */
|
||||
peer_cfg->add_virtual_ip(peer_cfg, host_create_any(AF_INET));
|
||||
|
||||
@@ -91,7 +91,7 @@ static peer_cfg_t* create_peer_cfg(char *name, char *host)
|
||||
CERT_SEND_IF_ASKED, UNIQUE_REPLACE, 1, /* keyingtries */
|
||||
36000, 0, /* rekey 10h, reauth none */
|
||||
600, 600, /* jitter, over 10min */
|
||||
TRUE, FALSE, /* mobike, aggressive */
|
||||
TRUE, FALSE, TRUE, /* mobike, aggressive, pull */
|
||||
30, 0, /* DPD delay, timeout */
|
||||
FALSE, NULL, NULL); /* mediation */
|
||||
peer_cfg->add_virtual_ip(peer_cfg, host_create_from_string("0.0.0.0", 0));
|
||||
|
||||
@@ -99,6 +99,11 @@ struct private_peer_cfg_t {
|
||||
*/
|
||||
bool aggressive;
|
||||
|
||||
/**
|
||||
* Use pull or push in mode config?
|
||||
*/
|
||||
bool pull_mode;
|
||||
|
||||
/**
|
||||
* Time before starting rekeying
|
||||
*/
|
||||
@@ -390,6 +395,12 @@ METHOD(peer_cfg_t, use_aggressive, bool,
|
||||
return this->aggressive;
|
||||
}
|
||||
|
||||
METHOD(peer_cfg_t, use_pull_mode, bool,
|
||||
private_peer_cfg_t *this)
|
||||
{
|
||||
return this->pull_mode;
|
||||
}
|
||||
|
||||
METHOD(peer_cfg_t, get_dpd, u_int32_t,
|
||||
private_peer_cfg_t *this)
|
||||
{
|
||||
@@ -588,6 +599,7 @@ METHOD(peer_cfg_t, equals, bool,
|
||||
this->over_time == other->over_time &&
|
||||
this->dpd == other->dpd &&
|
||||
this->aggressive == other->aggressive &&
|
||||
this->pull_mode == other->pull_mode &&
|
||||
auth_cfg_equal(this, other)
|
||||
#ifdef ME
|
||||
&& this->mediation == other->mediation &&
|
||||
@@ -638,8 +650,8 @@ peer_cfg_t *peer_cfg_create(char *name,
|
||||
unique_policy_t unique, u_int32_t keyingtries,
|
||||
u_int32_t rekey_time, u_int32_t reauth_time,
|
||||
u_int32_t jitter_time, u_int32_t over_time,
|
||||
bool mobike, bool aggressive, u_int32_t dpd,
|
||||
u_int32_t dpd_timeout,
|
||||
bool mobike, bool aggressive, bool pull_mode,
|
||||
u_int32_t dpd, u_int32_t dpd_timeout,
|
||||
bool mediation, peer_cfg_t *mediated_by,
|
||||
identification_t *peer_id)
|
||||
{
|
||||
@@ -671,6 +683,7 @@ peer_cfg_t *peer_cfg_create(char *name,
|
||||
.get_over_time = _get_over_time,
|
||||
.use_mobike = _use_mobike,
|
||||
.use_aggressive = _use_aggressive,
|
||||
.use_pull_mode = _use_pull_mode,
|
||||
.get_dpd = _get_dpd,
|
||||
.get_dpd_timeout = _get_dpd_timeout,
|
||||
.add_virtual_ip = _add_virtual_ip,
|
||||
@@ -701,6 +714,7 @@ peer_cfg_t *peer_cfg_create(char *name,
|
||||
.over_time = over_time,
|
||||
.use_mobike = mobike,
|
||||
.aggressive = aggressive,
|
||||
.pull_mode = pull_mode,
|
||||
.dpd = dpd,
|
||||
.dpd_timeout = dpd_timeout,
|
||||
.vips = linked_list_create(),
|
||||
|
||||
@@ -247,6 +247,13 @@ struct peer_cfg_t {
|
||||
*/
|
||||
bool (*use_aggressive)(peer_cfg_t *this);
|
||||
|
||||
/**
|
||||
* Use pull or push mode for mode config?
|
||||
*
|
||||
* @return TRUE to use pull, FALSE to use push mode
|
||||
*/
|
||||
bool (*use_pull_mode)(peer_cfg_t *this);
|
||||
|
||||
/**
|
||||
* Get the DPD check interval.
|
||||
*
|
||||
@@ -366,6 +373,7 @@ struct peer_cfg_t {
|
||||
* @param over_time maximum overtime before closing a rekeying/reauth SA
|
||||
* @param mobike use MOBIKE (RFC4555) if peer supports it
|
||||
* @param aggressive use/accept aggressive mode with IKEv1
|
||||
* @param pullmode TRUE to use modeconfig pull, FALSE for push
|
||||
* @param dpd DPD check interval, 0 to disable
|
||||
* @param dpd_timeout DPD timeout interval (IKEv1 only), if 0 default applies
|
||||
* @param mediation TRUE if this is a mediation connection
|
||||
@@ -378,8 +386,8 @@ peer_cfg_t *peer_cfg_create(char *name,
|
||||
unique_policy_t unique, u_int32_t keyingtries,
|
||||
u_int32_t rekey_time, u_int32_t reauth_time,
|
||||
u_int32_t jitter_time, u_int32_t over_time,
|
||||
bool mobike, bool aggressive, u_int32_t dpd,
|
||||
u_int32_t dpd_timeout,
|
||||
bool mobike, bool aggressive, bool pull_mode,
|
||||
u_int32_t dpd, u_int32_t dpd_timeout,
|
||||
bool mediation, peer_cfg_t *mediated_by,
|
||||
identification_t *peer_id);
|
||||
|
||||
|
||||
@@ -208,8 +208,8 @@ static void setup_tunnel(private_ha_tunnel_t *this,
|
||||
remote, FALSE, IKEV2_UDP_PORT, FRAGMENTATION_NO, 0);
|
||||
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
|
||||
peer_cfg = peer_cfg_create("ha", ike_cfg, CERT_NEVER_SEND,
|
||||
UNIQUE_KEEP, 0, 86400, 0, 7200, 3600, FALSE, FALSE, 30,
|
||||
0, FALSE, NULL, NULL);
|
||||
UNIQUE_KEEP, 0, 86400, 0, 7200, 3600, FALSE, FALSE,
|
||||
TRUE, 30, 0, FALSE, NULL, NULL);
|
||||
|
||||
auth_cfg = auth_cfg_create();
|
||||
auth_cfg->add(auth_cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
|
||||
|
||||
@@ -561,7 +561,7 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
|
||||
CERT_SEND_IF_ASKED, UNIQUE_NO, 1, /* keytries */
|
||||
this->ike_rekey, 0, /* rekey, reauth */
|
||||
0, this->ike_rekey, /* jitter, overtime */
|
||||
FALSE, FALSE, /* mobike, aggressive mode */
|
||||
FALSE, FALSE, TRUE, /* mobike, aggressive, pull */
|
||||
this->dpd_delay, /* dpd_delay */
|
||||
this->dpd_timeout, /* dpd_timeout */
|
||||
FALSE, NULL, NULL);
|
||||
|
||||
@@ -334,7 +334,7 @@ static gboolean initiate_connection(private_maemo_service_t *this,
|
||||
UNIQUE_REPLACE, 1, /* keyingtries */
|
||||
36000, 0, /* rekey 10h, reauth none */
|
||||
600, 600, /* jitter, over 10min */
|
||||
TRUE, FALSE, /* mobike, aggressive */
|
||||
TRUE, FALSE, TRUE, /* mobike, aggressive, pull */
|
||||
0, 0, /* DPD delay, timeout */
|
||||
FALSE, NULL, NULL); /* mediation */
|
||||
peer_cfg->add_virtual_ip(peer_cfg, host_create_from_string("0.0.0.0", 0));
|
||||
|
||||
@@ -112,7 +112,7 @@ METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
|
||||
CERT_NEVER_SEND, UNIQUE_REPLACE,
|
||||
1, this->rekey*60, 0, /* keytries, rekey, reauth */
|
||||
this->rekey*5, this->rekey*3, /* jitter, overtime */
|
||||
TRUE, FALSE, /* mobike, aggressive */
|
||||
TRUE, FALSE, TRUE, /* mobike, aggressive, pull */
|
||||
this->dpd, 0, /* DPD delay, timeout */
|
||||
TRUE, NULL, NULL); /* mediation, med by, peer id */
|
||||
e->destroy(e);
|
||||
@@ -149,7 +149,7 @@ METHOD(backend_t, get_peer_cfg_by_name, peer_cfg_t*,
|
||||
CERT_NEVER_SEND, UNIQUE_REPLACE,
|
||||
1, this->rekey*60, 0, /* keytries, rekey, reauth */
|
||||
this->rekey*5, this->rekey*3, /* jitter, overtime */
|
||||
TRUE, FALSE, /* mobike, aggressive */
|
||||
TRUE, FALSE, TRUE, /* mobike, aggressive, pull */
|
||||
this->dpd, 0, /* DPD delay, timeout */
|
||||
FALSE, med_cfg, /* mediation, med by */
|
||||
identification_create_from_encoding(ID_KEY_ID, other));
|
||||
@@ -224,7 +224,7 @@ METHOD(enumerator_t, peer_enumerator_enumerate, bool,
|
||||
CERT_NEVER_SEND, UNIQUE_REPLACE,
|
||||
1, this->rekey*60, 0, /* keytries, rekey, reauth */
|
||||
this->rekey*5, this->rekey*3, /* jitter, overtime */
|
||||
TRUE, FALSE, /* mobike, aggressive */
|
||||
TRUE, FALSE, TRUE, /* mobike, aggressive, pull */
|
||||
this->dpd, 0, /* DPD delay, timeout */
|
||||
FALSE, NULL, NULL); /* mediation, med by, peer id */
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ METHOD(backend_t, create_peer_cfg_enumerator, enumerator_t*,
|
||||
CERT_NEVER_SEND, UNIQUE_REPLACE,
|
||||
1, this->rekey*60, 0, /* keytries, rekey, reauth */
|
||||
this->rekey*5, this->rekey*3, /* jitter, overtime */
|
||||
TRUE, FALSE, /* mobike, aggressiv */
|
||||
TRUE, FALSE, TRUE, /* mobike, aggressive, pull */
|
||||
this->dpd, 0, /* DPD delay, timeout */
|
||||
TRUE, NULL, NULL); /* mediation, med by, peer id */
|
||||
e->destroy(e);
|
||||
|
||||
@@ -374,7 +374,7 @@ static peer_cfg_t *build_peer_cfg(private_sql_config_t *this, enumerator_t *e,
|
||||
peer_cfg = peer_cfg_create(
|
||||
name, ike, cert_policy, uniqueid,
|
||||
keyingtries, rekeytime, reauthtime, jitter, overtime,
|
||||
mobike, FALSE, dpd_delay, 0,
|
||||
mobike, FALSE, TRUE, dpd_delay, 0,
|
||||
mediation, mediated_cfg, peer_id);
|
||||
if (vip)
|
||||
{
|
||||
|
||||
@@ -731,6 +731,7 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
|
||||
msg->add_conn.me.sendcert, unique,
|
||||
msg->add_conn.rekey.tries, rekey, reauth, jitter, over,
|
||||
msg->add_conn.mobike, msg->add_conn.aggressive,
|
||||
msg->add_conn.pushmode == 0,
|
||||
msg->add_conn.dpd.delay, msg->add_conn.dpd.timeout,
|
||||
msg->add_conn.ikeme.mediation, mediated_by, peer_id);
|
||||
|
||||
@@ -780,7 +781,13 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
if (msg->add_conn.me.sourceip)
|
||||
if (msg->add_conn.me.sourceip && msg->add_conn.other.sourceip)
|
||||
{
|
||||
DBG1(DBG_CFG, "'%s' has both left- and rightsourceip, but IKE can "
|
||||
"negotiate one virtual IP only, ignoring local virtual IP",
|
||||
msg->add_conn.name);
|
||||
}
|
||||
else if (msg->add_conn.me.sourceip)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
char *token;
|
||||
|
||||
@@ -162,7 +162,7 @@ METHOD(enumerator_t, peer_enumerator_enumerate, bool,
|
||||
name, ike_cfg, CERT_SEND_IF_ASKED, UNIQUE_NO,
|
||||
1, create_rekey(ike_rekey), 0, /* keytries, rekey, reauth */
|
||||
1800, 900, /* jitter, overtime */
|
||||
TRUE, FALSE, /* mobike, aggressive */
|
||||
TRUE, FALSE, TRUE, /* mobike, aggressive, pull */
|
||||
60, 0, /* DPD delay, timeout */
|
||||
FALSE, NULL, NULL); /* mediation, med by, peer id */
|
||||
auth = auth_cfg_create();
|
||||
|
||||
@@ -539,23 +539,40 @@ static bool mode_config_expected(private_task_manager_t *this)
|
||||
enumerator_t *enumerator;
|
||||
peer_cfg_t *peer_cfg;
|
||||
char *pool;
|
||||
bool local;
|
||||
host_t *host;
|
||||
|
||||
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
if (peer_cfg)
|
||||
{
|
||||
enumerator = peer_cfg->create_pool_enumerator(peer_cfg);
|
||||
if (!enumerator->enumerate(enumerator, &pool))
|
||||
{ /* no pool configured */
|
||||
if (peer_cfg->use_pull_mode(peer_cfg))
|
||||
{
|
||||
enumerator = peer_cfg->create_pool_enumerator(peer_cfg);
|
||||
if (!enumerator->enumerate(enumerator, &pool))
|
||||
{ /* no pool configured */
|
||||
enumerator->destroy(enumerator);
|
||||
return FALSE;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
return FALSE;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
local = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
enumerator = peer_cfg->create_virtual_ip_enumerator(peer_cfg);
|
||||
if (!enumerator->enumerate(enumerator, &host))
|
||||
{ /* not requesting a vip */
|
||||
enumerator->destroy(enumerator);
|
||||
return FALSE;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
local = TRUE;
|
||||
}
|
||||
enumerator = this->ike_sa->create_virtual_ip_enumerator(this->ike_sa,
|
||||
FALSE);
|
||||
local);
|
||||
if (!enumerator->enumerate(enumerator, &host))
|
||||
{ /* have a pool, but no VIP assigned yet */
|
||||
{ /* expecting a VIP exchange, but no VIP assigned yet */
|
||||
enumerator->destroy(enumerator);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1087,7 +1104,8 @@ static status_t process_request(private_task_manager_t *this,
|
||||
case TRANSACTION:
|
||||
if (this->ike_sa->get_state(this->ike_sa) != IKE_CONNECTING)
|
||||
{
|
||||
task = (task_t *)mode_config_create(this->ike_sa, FALSE);
|
||||
task = (task_t *)mode_config_create(this->ike_sa,
|
||||
FALSE, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -196,6 +196,17 @@ static status_t send_delete(private_aggressive_mode_t *this)
|
||||
return ALREADY_DONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a timeout for the IKE_SA should it not establish
|
||||
*/
|
||||
static void schedule_timeout(ike_sa_t *ike_sa)
|
||||
{
|
||||
job_t *job;
|
||||
|
||||
job = (job_t*)delete_ike_sa_job_create(ike_sa->get_id(ike_sa), FALSE);
|
||||
lib->scheduler->schedule_job(lib->scheduler, job, HALF_OPEN_IKE_SA_TIMEOUT);
|
||||
}
|
||||
|
||||
METHOD(task_t, build_i, status_t,
|
||||
private_aggressive_mode_t *this, message_t *message)
|
||||
{
|
||||
@@ -300,20 +311,15 @@ METHOD(task_t, build_i, status_t,
|
||||
case AUTH_XAUTH_INIT_PSK:
|
||||
case AUTH_XAUTH_INIT_RSA:
|
||||
case AUTH_HYBRID_INIT_RSA:
|
||||
{ /* wait for XAUTH request, since this may never come,
|
||||
* we queue a timeout */
|
||||
job_t *job = (job_t*)delete_ike_sa_job_create(
|
||||
this->ike_sa->get_id(this->ike_sa), FALSE);
|
||||
lib->scheduler->schedule_job(lib->scheduler, job,
|
||||
HALF_OPEN_IKE_SA_TIMEOUT);
|
||||
/* wait for XAUTH request */
|
||||
schedule_timeout(this->ike_sa);
|
||||
break;
|
||||
}
|
||||
case AUTH_XAUTH_RESP_PSK:
|
||||
case AUTH_XAUTH_RESP_RSA:
|
||||
case AUTH_HYBRID_RESP_RSA:
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)xauth_create(this->ike_sa, TRUE));
|
||||
return SUCCESS;
|
||||
break;
|
||||
default:
|
||||
if (charon->ike_sa_manager->check_uniqueness(
|
||||
charon->ike_sa_manager, this->ike_sa, FALSE))
|
||||
@@ -328,10 +334,30 @@ METHOD(task_t, build_i, status_t,
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* check for and prepare mode config push/pull */
|
||||
if (this->ph1->has_virtual_ip(this->ph1, this->peer_cfg))
|
||||
{
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)mode_config_create(this->ike_sa, TRUE));
|
||||
if (this->peer_cfg->use_pull_mode(this->peer_cfg))
|
||||
{
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)mode_config_create(this->ike_sa, TRUE, TRUE));
|
||||
}
|
||||
else
|
||||
{
|
||||
schedule_timeout(this->ike_sa);
|
||||
}
|
||||
}
|
||||
else if (this->ph1->has_pool(this->ph1, this->peer_cfg))
|
||||
{
|
||||
if (this->peer_cfg->use_pull_mode(this->peer_cfg))
|
||||
{
|
||||
schedule_timeout(this->ike_sa);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)mode_config_create(this->ike_sa, TRUE, FALSE));
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -482,7 +508,7 @@ METHOD(task_t, process_r, status_t,
|
||||
case AUTH_HYBRID_INIT_RSA:
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)xauth_create(this->ike_sa, TRUE));
|
||||
return SUCCESS;
|
||||
break;
|
||||
case AUTH_XAUTH_RESP_PSK:
|
||||
case AUTH_XAUTH_RESP_RSA:
|
||||
case AUTH_HYBRID_RESP_RSA:
|
||||
@@ -505,11 +531,22 @@ METHOD(task_t, process_r, status_t,
|
||||
this->ike_sa->get_id(this->ike_sa)));
|
||||
break;
|
||||
}
|
||||
if (!this->ph1->has_pool(this->ph1, this->peer_cfg) &&
|
||||
this->ph1->has_virtual_ip(this->ph1, this->peer_cfg))
|
||||
/* check for and prepare mode config push/pull */
|
||||
if (this->ph1->has_virtual_ip(this->ph1, this->peer_cfg))
|
||||
{
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)mode_config_create(this->ike_sa, TRUE));
|
||||
if (this->peer_cfg->use_pull_mode(this->peer_cfg))
|
||||
{
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)mode_config_create(this->ike_sa, TRUE, TRUE));
|
||||
}
|
||||
}
|
||||
else if (this->ph1->has_pool(this->ph1, this->peer_cfg))
|
||||
{
|
||||
if (!this->peer_cfg->use_pull_mode(this->peer_cfg))
|
||||
{
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)mode_config_create(this->ike_sa, TRUE, FALSE));
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -504,7 +504,7 @@ METHOD(task_t, build_r, status_t,
|
||||
case AUTH_HYBRID_INIT_RSA:
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)xauth_create(this->ike_sa, TRUE));
|
||||
return SUCCESS;
|
||||
break;
|
||||
case AUTH_XAUTH_RESP_PSK:
|
||||
case AUTH_XAUTH_RESP_RSA:
|
||||
case AUTH_HYBRID_RESP_RSA:
|
||||
@@ -527,11 +527,21 @@ METHOD(task_t, build_r, status_t,
|
||||
this->ike_sa->get_id(this->ike_sa)));
|
||||
break;
|
||||
}
|
||||
if (!this->ph1->has_pool(this->ph1, this->peer_cfg) &&
|
||||
this->ph1->has_virtual_ip(this->ph1, this->peer_cfg))
|
||||
if (this->ph1->has_virtual_ip(this->ph1, this->peer_cfg))
|
||||
{
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)mode_config_create(this->ike_sa, TRUE));
|
||||
if (this->peer_cfg->use_pull_mode(this->peer_cfg))
|
||||
{
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)mode_config_create(this->ike_sa, TRUE, TRUE));
|
||||
}
|
||||
}
|
||||
else if (this->ph1->has_pool(this->ph1, this->peer_cfg))
|
||||
{
|
||||
if (!this->peer_cfg->use_pull_mode(this->peer_cfg))
|
||||
{
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)mode_config_create(this->ike_sa, TRUE, FALSE));
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -540,6 +550,17 @@ METHOD(task_t, build_r, status_t,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a timeout for the IKE_SA should it not establish
|
||||
*/
|
||||
static void schedule_timeout(ike_sa_t *ike_sa)
|
||||
{
|
||||
job_t *job;
|
||||
|
||||
job = (job_t*)delete_ike_sa_job_create(ike_sa->get_id(ike_sa), FALSE);
|
||||
lib->scheduler->schedule_job(lib->scheduler, job, HALF_OPEN_IKE_SA_TIMEOUT);
|
||||
}
|
||||
|
||||
METHOD(task_t, process_i, status_t,
|
||||
private_main_mode_t *this, message_t *message)
|
||||
{
|
||||
@@ -639,20 +660,15 @@ METHOD(task_t, process_i, status_t,
|
||||
case AUTH_XAUTH_INIT_PSK:
|
||||
case AUTH_XAUTH_INIT_RSA:
|
||||
case AUTH_HYBRID_INIT_RSA:
|
||||
{ /* wait for XAUTH request, since this may never come,
|
||||
* we queue a timeout */
|
||||
job_t *job = (job_t*)delete_ike_sa_job_create(
|
||||
this->ike_sa->get_id(this->ike_sa), FALSE);
|
||||
lib->scheduler->schedule_job(lib->scheduler, job,
|
||||
HALF_OPEN_IKE_SA_TIMEOUT);
|
||||
/* wait for XAUTH request */
|
||||
schedule_timeout(this->ike_sa);
|
||||
break;
|
||||
}
|
||||
case AUTH_XAUTH_RESP_PSK:
|
||||
case AUTH_XAUTH_RESP_RSA:
|
||||
case AUTH_HYBRID_RESP_RSA:
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)xauth_create(this->ike_sa, TRUE));
|
||||
return SUCCESS;
|
||||
break;
|
||||
default:
|
||||
if (charon->ike_sa_manager->check_uniqueness(
|
||||
charon->ike_sa_manager, this->ike_sa, FALSE))
|
||||
@@ -667,10 +683,30 @@ METHOD(task_t, process_i, status_t,
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* check for and prepare mode config push/pull */
|
||||
if (this->ph1->has_virtual_ip(this->ph1, this->peer_cfg))
|
||||
{
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)mode_config_create(this->ike_sa, TRUE));
|
||||
if (this->peer_cfg->use_pull_mode(this->peer_cfg))
|
||||
{
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)mode_config_create(this->ike_sa, TRUE, TRUE));
|
||||
}
|
||||
else
|
||||
{
|
||||
schedule_timeout(this->ike_sa);
|
||||
}
|
||||
}
|
||||
else if (this->ph1->has_pool(this->ph1, this->peer_cfg))
|
||||
{
|
||||
if (this->peer_cfg->use_pull_mode(this->peer_cfg))
|
||||
{
|
||||
schedule_timeout(this->ike_sa);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->ike_sa->queue_task(this->ike_sa,
|
||||
(task_t*)mode_config_create(this->ike_sa, TRUE, FALSE));
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -41,15 +41,20 @@ struct private_mode_config_t {
|
||||
*/
|
||||
bool initiator;
|
||||
|
||||
/**
|
||||
* Use pull (CFG_REQUEST/RESPONSE) or push (CFG_SET/ACK)?
|
||||
*/
|
||||
bool pull;
|
||||
|
||||
/**
|
||||
* Received list of virtual IPs, host_t*
|
||||
*/
|
||||
linked_list_t *vips;
|
||||
|
||||
/**
|
||||
* list of attributes requested and its handler, entry_t
|
||||
* Requested/received list of attributes, entry_t
|
||||
*/
|
||||
linked_list_t *requested;
|
||||
linked_list_t *attributes;
|
||||
|
||||
/**
|
||||
* Identifier to include in response
|
||||
@@ -58,12 +63,12 @@ struct private_mode_config_t {
|
||||
};
|
||||
|
||||
/**
|
||||
* Entry for a requested attribute and the requesting handler
|
||||
* Entry for a attribute and associated handler
|
||||
*/
|
||||
typedef struct {
|
||||
/** attribute requested */
|
||||
/** attribute type */
|
||||
configuration_attribute_type_t type;
|
||||
/** handler requesting this attribute */
|
||||
/** handler for this attribute */
|
||||
attribute_handler_t *handler;
|
||||
} entry_t;
|
||||
|
||||
@@ -117,13 +122,13 @@ static void handle_attribute(private_mode_config_t *this,
|
||||
entry_t *entry;
|
||||
|
||||
/* find the handler which requested this attribute */
|
||||
enumerator = this->requested->create_enumerator(this->requested);
|
||||
enumerator = this->attributes->create_enumerator(this->attributes);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->type == ca->get_type(ca))
|
||||
{
|
||||
handler = entry->handler;
|
||||
this->requested->remove_at(this->requested, enumerator);
|
||||
this->attributes->remove_at(this->attributes, enumerator);
|
||||
free(entry);
|
||||
break;
|
||||
}
|
||||
@@ -180,7 +185,7 @@ static void process_attribute(private_mode_config_t *this,
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (this->initiator)
|
||||
if (this->initiator == this->pull)
|
||||
{
|
||||
handle_attribute(this, ca);
|
||||
}
|
||||
@@ -188,6 +193,24 @@ static void process_attribute(private_mode_config_t *this,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if config allows push mode when acting as task responder
|
||||
*/
|
||||
static bool accept_push(private_mode_config_t *this)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
peer_cfg_t *config;
|
||||
bool vip;
|
||||
host_t *host;
|
||||
|
||||
config = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
enumerator = config->create_virtual_ip_enumerator(config);
|
||||
vip = enumerator->enumerate(enumerator, &host);
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return vip && !config->use_pull_mode(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan for configuration payloads and attributes
|
||||
*/
|
||||
@@ -206,6 +229,15 @@ static void process_payloads(private_mode_config_t *this, message_t *message)
|
||||
|
||||
switch (cp->get_type(cp))
|
||||
{
|
||||
case CFG_SET:
|
||||
/* when acting as a responder, we detect the mode using
|
||||
* the type of configuration payload. But we should double
|
||||
* check the peer is allowed to use push mode on us. */
|
||||
if (!this->initiator && accept_push(this))
|
||||
{
|
||||
this->pull = FALSE;
|
||||
}
|
||||
/* FALL */
|
||||
case CFG_REQUEST:
|
||||
this->identifier = cp->get_identifier(cp);
|
||||
/* FALL */
|
||||
@@ -219,6 +251,8 @@ static void process_payloads(private_mode_config_t *this, message_t *message)
|
||||
}
|
||||
attributes->destroy(attributes);
|
||||
break;
|
||||
case CFG_ACK:
|
||||
break;
|
||||
default:
|
||||
DBG1(DBG_IKE, "ignoring %N config payload",
|
||||
config_type_names, cp->get_type(cp));
|
||||
@@ -229,8 +263,29 @@ static void process_payloads(private_mode_config_t *this, message_t *message)
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
METHOD(task_t, build_i, status_t,
|
||||
private_mode_config_t *this, message_t *message)
|
||||
/**
|
||||
* Add an attribute to a configuration payload, and store it in task
|
||||
*/
|
||||
static void add_attribute(private_mode_config_t *this, cp_payload_t *cp,
|
||||
configuration_attribute_type_t type, chunk_t data,
|
||||
attribute_handler_t *handler)
|
||||
{
|
||||
entry_t *entry;
|
||||
|
||||
cp->add_attribute(cp,
|
||||
configuration_attribute_create_chunk(CONFIGURATION_ATTRIBUTE_V1,
|
||||
type, data));
|
||||
INIT(entry,
|
||||
.type = type,
|
||||
.handler = handler,
|
||||
);
|
||||
this->attributes->insert_last(this->attributes, entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a CFG_REQUEST as initiator
|
||||
*/
|
||||
static status_t build_request(private_mode_config_t *this, message_t *message)
|
||||
{
|
||||
cp_payload_t *cp;
|
||||
enumerator_t *enumerator;
|
||||
@@ -279,18 +334,7 @@ METHOD(task_t, build_i, status_t,
|
||||
this->ike_sa->get_other_id(this->ike_sa), vips);
|
||||
while (enumerator->enumerate(enumerator, &handler, &type, &data))
|
||||
{
|
||||
entry_t *entry;
|
||||
|
||||
DBG2(DBG_IKE, "building %N attribute",
|
||||
configuration_attribute_type_names, type);
|
||||
cp->add_attribute(cp,
|
||||
configuration_attribute_create_chunk(CONFIGURATION_ATTRIBUTE_V1,
|
||||
type, data));
|
||||
INIT(entry,
|
||||
.type = type,
|
||||
.handler = handler,
|
||||
);
|
||||
this->requested->insert_last(this->requested, entry);
|
||||
add_attribute(this, cp, type, data, handler);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
@@ -301,15 +345,121 @@ METHOD(task_t, build_i, status_t,
|
||||
return NEED_MORE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a CFG_SET as initiator
|
||||
*/
|
||||
static status_t build_set(private_mode_config_t *this, message_t *message)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
configuration_attribute_type_t type;
|
||||
chunk_t value;
|
||||
cp_payload_t *cp;
|
||||
peer_cfg_t *config;
|
||||
identification_t *id;
|
||||
linked_list_t *pools;
|
||||
host_t *any4, *any6, *found;
|
||||
char *name;
|
||||
|
||||
cp = cp_payload_create_type(CONFIGURATION_V1, CFG_SET);
|
||||
|
||||
id = this->ike_sa->get_other_eap_id(this->ike_sa);
|
||||
config = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
any4 = host_create_any(AF_INET);
|
||||
any6 = host_create_any(AF_INET6);
|
||||
|
||||
this->ike_sa->clear_virtual_ips(this->ike_sa, FALSE);
|
||||
|
||||
/* in push mode, we ask each configured pool for an address */
|
||||
enumerator = config->create_pool_enumerator(config);
|
||||
while (enumerator->enumerate(enumerator, &name))
|
||||
{
|
||||
pools = linked_list_create_with_items(name, NULL);
|
||||
/* try IPv4, then IPv6 */
|
||||
found = hydra->attributes->acquire_address(hydra->attributes,
|
||||
pools, id, any4);
|
||||
if (!found)
|
||||
{
|
||||
found = hydra->attributes->acquire_address(hydra->attributes,
|
||||
pools, id, any6);
|
||||
}
|
||||
pools->destroy(pools);
|
||||
if (found)
|
||||
{
|
||||
DBG1(DBG_IKE, "assigning virtual IP %H to peer '%Y'", found, id);
|
||||
this->ike_sa->add_virtual_ip(this->ike_sa, FALSE, found);
|
||||
cp->add_attribute(cp, build_vip(found));
|
||||
this->vips->insert_last(this->vips, found);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
any4->destroy(any4);
|
||||
any6->destroy(any6);
|
||||
|
||||
/* query registered providers for additional attributes to include */
|
||||
pools = linked_list_create_from_enumerator(
|
||||
config->create_pool_enumerator(config));
|
||||
enumerator = hydra->attributes->create_responder_enumerator(
|
||||
hydra->attributes, pools, id, this->vips);
|
||||
while (enumerator->enumerate(enumerator, &type, &value))
|
||||
{
|
||||
add_attribute(this, cp, type, value, NULL);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
pools->destroy(pools);
|
||||
|
||||
message->add_payload(message, (payload_t*)cp);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(task_t, build_i, status_t,
|
||||
private_mode_config_t *this, message_t *message)
|
||||
{
|
||||
if (this->pull)
|
||||
{
|
||||
return build_request(this, message);
|
||||
}
|
||||
return build_set(this, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store received virtual IPs to the IKE_SA, install them
|
||||
*/
|
||||
static void install_vips(private_mode_config_t *this)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
host_t *host;
|
||||
|
||||
this->ike_sa->clear_virtual_ips(this->ike_sa, TRUE);
|
||||
|
||||
enumerator = this->vips->create_enumerator(this->vips);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
if (!host->is_anyaddr(host))
|
||||
{
|
||||
this->ike_sa->add_virtual_ip(this->ike_sa, TRUE, host);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
METHOD(task_t, process_r, status_t,
|
||||
private_mode_config_t *this, message_t *message)
|
||||
{
|
||||
process_payloads(this, message);
|
||||
|
||||
if (!this->pull)
|
||||
{
|
||||
install_vips(this);
|
||||
}
|
||||
return NEED_MORE;
|
||||
}
|
||||
|
||||
METHOD(task_t, build_r, status_t,
|
||||
private_mode_config_t *this, message_t *message)
|
||||
/**
|
||||
* Build CFG_REPLY message after receiving CFG_REQUEST
|
||||
*/
|
||||
static status_t build_reply(private_mode_config_t *this, message_t *message)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
configuration_attribute_type_t type;
|
||||
@@ -360,8 +510,6 @@ METHOD(task_t, build_r, status_t,
|
||||
hydra->attributes, pools, id, vips);
|
||||
while (enumerator->enumerate(enumerator, &type, &value))
|
||||
{
|
||||
DBG2(DBG_IKE, "building %N attribute",
|
||||
configuration_attribute_type_names, type);
|
||||
cp->add_attribute(cp,
|
||||
configuration_attribute_create_chunk(CONFIGURATION_ATTRIBUTE_V1,
|
||||
type, value));
|
||||
@@ -376,26 +524,72 @@ METHOD(task_t, build_r, status_t,
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(task_t, process_i, status_t,
|
||||
private_mode_config_t *this, message_t *message)
|
||||
/**
|
||||
* Build CFG_ACK for a received CFG_SET
|
||||
*/
|
||||
static status_t build_ack(private_mode_config_t *this, message_t *message)
|
||||
{
|
||||
cp_payload_t *cp;
|
||||
enumerator_t *enumerator;
|
||||
host_t *host;
|
||||
configuration_attribute_type_t type;
|
||||
entry_t *entry;
|
||||
|
||||
process_payloads(this, message);
|
||||
cp = cp_payload_create_type(CONFIGURATION_V1, CFG_ACK);
|
||||
|
||||
this->ike_sa->clear_virtual_ips(this->ike_sa, TRUE);
|
||||
/* return empty attributes for installed IPs */
|
||||
|
||||
enumerator = this->vips->create_enumerator(this->vips);
|
||||
while (enumerator->enumerate(enumerator, &host))
|
||||
{
|
||||
if (!host->is_anyaddr(host))
|
||||
type = INTERNAL_IP6_ADDRESS;
|
||||
if (host->get_family(host) == AF_INET6)
|
||||
{
|
||||
this->ike_sa->add_virtual_ip(this->ike_sa, TRUE, host);
|
||||
type = INTERNAL_IP6_ADDRESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = INTERNAL_IP4_ADDRESS;
|
||||
}
|
||||
cp->add_attribute(cp, configuration_attribute_create_chunk(
|
||||
CONFIGURATION_ATTRIBUTE_V1, type, chunk_empty));
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
enumerator = this->attributes->create_enumerator(this->attributes);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
cp->add_attribute(cp,
|
||||
configuration_attribute_create_chunk(CONFIGURATION_ATTRIBUTE_V1,
|
||||
entry->type, chunk_empty));
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
cp->set_identifier(cp, this->identifier);
|
||||
message->add_payload(message, (payload_t*)cp);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(task_t, build_r, status_t,
|
||||
private_mode_config_t *this, message_t *message)
|
||||
{
|
||||
if (this->pull)
|
||||
{
|
||||
return build_reply(this, message);
|
||||
}
|
||||
return build_ack(this, message);
|
||||
}
|
||||
|
||||
METHOD(task_t, process_i, status_t,
|
||||
private_mode_config_t *this, message_t *message)
|
||||
{
|
||||
process_payloads(this, message);
|
||||
|
||||
if (this->pull)
|
||||
{
|
||||
install_vips(this);
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -411,22 +605,22 @@ METHOD(task_t, migrate, void,
|
||||
this->ike_sa = ike_sa;
|
||||
this->vips->destroy_offset(this->vips, offsetof(host_t, destroy));
|
||||
this->vips = linked_list_create();
|
||||
this->requested->destroy_function(this->requested, free);
|
||||
this->requested = linked_list_create();
|
||||
this->attributes->destroy_function(this->attributes, free);
|
||||
this->attributes = linked_list_create();
|
||||
}
|
||||
|
||||
METHOD(task_t, destroy, void,
|
||||
private_mode_config_t *this)
|
||||
{
|
||||
this->vips->destroy_offset(this->vips, offsetof(host_t, destroy));
|
||||
this->requested->destroy_function(this->requested, free);
|
||||
this->attributes->destroy_function(this->attributes, free);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
mode_config_t *mode_config_create(ike_sa_t *ike_sa, bool initiator)
|
||||
mode_config_t *mode_config_create(ike_sa_t *ike_sa, bool initiator, bool pull)
|
||||
{
|
||||
private_mode_config_t *this;
|
||||
|
||||
@@ -439,8 +633,9 @@ mode_config_t *mode_config_create(ike_sa_t *ike_sa, bool initiator)
|
||||
},
|
||||
},
|
||||
.initiator = initiator,
|
||||
.pull = initiator ? pull : TRUE,
|
||||
.ike_sa = ike_sa,
|
||||
.requested = linked_list_create(),
|
||||
.attributes = linked_list_create(),
|
||||
.vips = linked_list_create(),
|
||||
);
|
||||
|
||||
|
||||
@@ -43,8 +43,9 @@ struct mode_config_t {
|
||||
*
|
||||
* @param ike_sa IKE_SA this task works for
|
||||
* @param initiator TRUE for initiator
|
||||
* @param pull TRUE to pull, FALSE to push (applies if initiator only)
|
||||
* @return mode_config task to handle by the task_manager
|
||||
*/
|
||||
mode_config_t *mode_config_create(ike_sa_t *ike_sa, bool initiator);
|
||||
mode_config_t *mode_config_create(ike_sa_t *ike_sa, bool initiator, bool pull);
|
||||
|
||||
#endif /** MODE_CONFIG_H_ @}*/
|
||||
|
||||
@@ -186,6 +186,7 @@ int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn)
|
||||
msg.add_conn.ipcomp = conn->options & SA_OPTION_COMPRESS;
|
||||
msg.add_conn.install_policy = conn->install_policy;
|
||||
msg.add_conn.aggressive = conn->aggressive;
|
||||
msg.add_conn.pushmode = conn->options & SA_OPTION_MODECFG_PUSH;
|
||||
msg.add_conn.crl_policy = (crl_policy_t)cfg->setup.strictcrlpolicy;
|
||||
msg.add_conn.unique = cfg->setup.uniqueids;
|
||||
msg.add_conn.algorithms.ike = push_string(&msg, conn->ike);
|
||||
|
||||
@@ -258,6 +258,7 @@ struct stroke_msg_t {
|
||||
int mode;
|
||||
int mobike;
|
||||
int aggressive;
|
||||
int pushmode;
|
||||
int force_encap;
|
||||
int fragmentation;
|
||||
int ipcomp;
|
||||
|
||||
Reference in New Issue
Block a user