DNS resolving of ike_cfg hosts dynamically on demand
This commit is contained in:
@@ -138,9 +138,13 @@ static ike_cfg_t *get_ike_cfg(private_backend_manager_t *this,
|
|||||||
while (enumerator->enumerate(enumerator, (void**)¤t))
|
while (enumerator->enumerate(enumerator, (void**)¤t))
|
||||||
{
|
{
|
||||||
prio = MATCH_NONE;
|
prio = MATCH_NONE;
|
||||||
my_candidate = current->get_my_host(current);
|
|
||||||
other_candidate = current->get_other_host(current);
|
|
||||||
|
|
||||||
|
my_candidate = host_create_from_dns(current->get_my_addr(current),
|
||||||
|
me->get_family(me), 0);
|
||||||
|
if (!my_candidate)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (my_candidate->ip_equals(my_candidate, me))
|
if (my_candidate->ip_equals(my_candidate, me))
|
||||||
{
|
{
|
||||||
prio += MATCH_ME;
|
prio += MATCH_ME;
|
||||||
@@ -149,6 +153,14 @@ static ike_cfg_t *get_ike_cfg(private_backend_manager_t *this,
|
|||||||
{
|
{
|
||||||
prio += MATCH_ANY;
|
prio += MATCH_ANY;
|
||||||
}
|
}
|
||||||
|
my_candidate->destroy(my_candidate);
|
||||||
|
|
||||||
|
other_candidate = host_create_from_dns(current->get_other_addr(current),
|
||||||
|
other->get_family(other), 0);
|
||||||
|
if (!other_candidate)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (other_candidate->ip_equals(other_candidate, other))
|
if (other_candidate->ip_equals(other_candidate, other))
|
||||||
{
|
{
|
||||||
prio += MATCH_OTHER;
|
prio += MATCH_OTHER;
|
||||||
@@ -157,9 +169,11 @@ static ike_cfg_t *get_ike_cfg(private_backend_manager_t *this,
|
|||||||
{
|
{
|
||||||
prio += MATCH_ANY;
|
prio += MATCH_ANY;
|
||||||
}
|
}
|
||||||
|
other_candidate->destroy(other_candidate);
|
||||||
|
|
||||||
DBG2(DBG_CFG, " candidate: %H...%H, prio %d",
|
DBG2(DBG_CFG, " candidate: %s...%s, prio %d",
|
||||||
my_candidate, other_candidate, prio);
|
current->get_my_addr(current), current->get_other_addr(current),
|
||||||
|
prio);
|
||||||
|
|
||||||
/* we require at least two MATCH_ANY */
|
/* we require at least two MATCH_ANY */
|
||||||
if (prio > best)
|
if (prio > best)
|
||||||
|
|||||||
+17
-18
@@ -41,12 +41,12 @@ struct private_ike_cfg_t {
|
|||||||
/**
|
/**
|
||||||
* Address of local host
|
* Address of local host
|
||||||
*/
|
*/
|
||||||
host_t *my_host;
|
char *me;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Address of remote host
|
* Address of remote host
|
||||||
*/
|
*/
|
||||||
host_t *other_host;
|
char *other;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* should we send a certificate request?
|
* should we send a certificate request?
|
||||||
@@ -81,19 +81,19 @@ static bool force_encap_meth(private_ike_cfg_t *this)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of ike_cfg_t.get_my_host.
|
* Implementation of ike_cfg_t.get_my_addr.
|
||||||
*/
|
*/
|
||||||
static host_t *get_my_host (private_ike_cfg_t *this)
|
static char *get_my_addr(private_ike_cfg_t *this)
|
||||||
{
|
{
|
||||||
return this->my_host;
|
return this->me;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of ike_cfg_t.get_other_host.
|
* Implementation of ike_cfg_t.get_other_addr.
|
||||||
*/
|
*/
|
||||||
static host_t *get_other_host (private_ike_cfg_t *this)
|
static char *get_other_addr(private_ike_cfg_t *this)
|
||||||
{
|
{
|
||||||
return this->other_host;
|
return this->other;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -219,8 +219,8 @@ static bool equals(private_ike_cfg_t *this, private_ike_cfg_t *other)
|
|||||||
return (eq &&
|
return (eq &&
|
||||||
this->certreq == other->certreq &&
|
this->certreq == other->certreq &&
|
||||||
this->force_encap == other->force_encap &&
|
this->force_encap == other->force_encap &&
|
||||||
this->my_host->equals(this->my_host, other->my_host) &&
|
streq(this->me, other->me) &&
|
||||||
this->other_host->equals(this->other_host, other->other_host));
|
streq(this->other, other->other));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -241,8 +241,8 @@ static void destroy(private_ike_cfg_t *this)
|
|||||||
{
|
{
|
||||||
this->proposals->destroy_offset(this->proposals,
|
this->proposals->destroy_offset(this->proposals,
|
||||||
offsetof(proposal_t, destroy));
|
offsetof(proposal_t, destroy));
|
||||||
this->my_host->destroy(this->my_host);
|
free(this->me);
|
||||||
this->other_host->destroy(this->other_host);
|
free(this->other);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -251,15 +251,15 @@ static void destroy(private_ike_cfg_t *this)
|
|||||||
* Described in header.
|
* Described in header.
|
||||||
*/
|
*/
|
||||||
ike_cfg_t *ike_cfg_create(bool certreq, bool force_encap,
|
ike_cfg_t *ike_cfg_create(bool certreq, bool force_encap,
|
||||||
host_t *my_host, host_t *other_host)
|
char *me, char *other)
|
||||||
{
|
{
|
||||||
private_ike_cfg_t *this = malloc_thing(private_ike_cfg_t);
|
private_ike_cfg_t *this = malloc_thing(private_ike_cfg_t);
|
||||||
|
|
||||||
/* public functions */
|
/* public functions */
|
||||||
this->public.send_certreq = (bool(*)(ike_cfg_t*))send_certreq;
|
this->public.send_certreq = (bool(*)(ike_cfg_t*))send_certreq;
|
||||||
this->public.force_encap = (bool (*) (ike_cfg_t *))force_encap_meth;
|
this->public.force_encap = (bool (*) (ike_cfg_t *))force_encap_meth;
|
||||||
this->public.get_my_host = (host_t*(*)(ike_cfg_t*))get_my_host;
|
this->public.get_my_addr = (char*(*)(ike_cfg_t*))get_my_addr;
|
||||||
this->public.get_other_host = (host_t*(*)(ike_cfg_t*))get_other_host;
|
this->public.get_other_addr = (char*(*)(ike_cfg_t*))get_other_addr;
|
||||||
this->public.add_proposal = (void(*)(ike_cfg_t*, proposal_t*)) add_proposal;
|
this->public.add_proposal = (void(*)(ike_cfg_t*, proposal_t*)) add_proposal;
|
||||||
this->public.get_proposals = (linked_list_t*(*)(ike_cfg_t*))get_proposals;
|
this->public.get_proposals = (linked_list_t*(*)(ike_cfg_t*))get_proposals;
|
||||||
this->public.select_proposal = (proposal_t*(*)(ike_cfg_t*,linked_list_t*))select_proposal;
|
this->public.select_proposal = (proposal_t*(*)(ike_cfg_t*,linked_list_t*))select_proposal;
|
||||||
@@ -272,9 +272,8 @@ ike_cfg_t *ike_cfg_create(bool certreq, bool force_encap,
|
|||||||
this->refcount = 1;
|
this->refcount = 1;
|
||||||
this->certreq = certreq;
|
this->certreq = certreq;
|
||||||
this->force_encap = force_encap;
|
this->force_encap = force_encap;
|
||||||
this->my_host = my_host;
|
this->me = strdup(me);
|
||||||
this->other_host = other_host;
|
this->other = strdup(other);
|
||||||
|
|
||||||
this->proposals = linked_list_create();
|
this->proposals = linked_list_create();
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
|
|||||||
@@ -43,16 +43,16 @@ struct ike_cfg_t {
|
|||||||
/**
|
/**
|
||||||
* Get own address.
|
* Get own address.
|
||||||
*
|
*
|
||||||
* @return host information as host_t object
|
* @return string of address/DNS name
|
||||||
*/
|
*/
|
||||||
host_t* (*get_my_host) (ike_cfg_t *this);
|
char* (*get_my_addr) (ike_cfg_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get peers address.
|
* Get peers address.
|
||||||
*
|
*
|
||||||
* @return host information as host_t object
|
* @return string of address/DNS name
|
||||||
*/
|
*/
|
||||||
host_t* (*get_other_host) (ike_cfg_t *this);
|
char* (*get_other_addr) (ike_cfg_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a proposal to the list.
|
* Adds a proposal to the list.
|
||||||
@@ -136,11 +136,11 @@ struct ike_cfg_t {
|
|||||||
* @param name ike_cfg identifier
|
* @param name ike_cfg identifier
|
||||||
* @param certreq TRUE to send a certificate request
|
* @param certreq TRUE to send a certificate request
|
||||||
* @param force_encap enforce UDP encapsulation by faking NATD notify
|
* @param force_encap enforce UDP encapsulation by faking NATD notify
|
||||||
* @param my_host host_t representing local address
|
* @param me address/DNS name of local peer
|
||||||
* @param other_host host_t representing remote address
|
* @param other address/DNS name of remote peer
|
||||||
* @return ike_cfg_t object.
|
* @return ike_cfg_t object.
|
||||||
*/
|
*/
|
||||||
ike_cfg_t *ike_cfg_create(bool certreq, bool force_encap,
|
ike_cfg_t *ike_cfg_create(bool certreq, bool force_encap,
|
||||||
host_t *my_host, host_t *other_host);
|
char *me, char *other);
|
||||||
|
|
||||||
#endif /* IKE_CFG_H_ @} */
|
#endif /* IKE_CFG_H_ @} */
|
||||||
|
|||||||
@@ -100,7 +100,6 @@ static peer_cfg_t *get_peer_cfg_by_name(private_medcli_config_t *this, char *nam
|
|||||||
child_cfg_t *child_cfg;
|
child_cfg_t *child_cfg;
|
||||||
chunk_t me, other;
|
chunk_t me, other;
|
||||||
char *address, *local_net, *remote_net;
|
char *address, *local_net, *remote_net;
|
||||||
host_t *med;
|
|
||||||
|
|
||||||
/* query mediation server config:
|
/* query mediation server config:
|
||||||
* - build ike_cfg/peer_cfg for mediation connection on-the-fly
|
* - build ike_cfg/peer_cfg for mediation connection on-the-fly
|
||||||
@@ -114,14 +113,7 @@ static peer_cfg_t *get_peer_cfg_by_name(private_medcli_config_t *this, char *nam
|
|||||||
DESTROY_IF(e);
|
DESTROY_IF(e);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
med = host_create_from_string(address, 500);
|
ike_cfg = ike_cfg_create(FALSE, FALSE, "0.0.0.0", address);
|
||||||
if (!med)
|
|
||||||
{
|
|
||||||
e->destroy(e);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
ike_cfg = ike_cfg_create(FALSE, FALSE,
|
|
||||||
host_create_from_string("0.0.0.0", 500), med);
|
|
||||||
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
|
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
|
||||||
DBG1(DBG_CFG, "mediation server id: %B", &other);
|
DBG1(DBG_CFG, "mediation server id: %B", &other);
|
||||||
med_cfg = peer_cfg_create(
|
med_cfg = peer_cfg_create(
|
||||||
@@ -313,8 +305,7 @@ medcli_config_t *medcli_config_create(database_t *db)
|
|||||||
this->rekey = lib->settings->get_int(lib->settings,
|
this->rekey = lib->settings->get_int(lib->settings,
|
||||||
"medclient.rekey", 20) * 60;
|
"medclient.rekey", 20) * 60;
|
||||||
this->dpd = lib->settings->get_int(lib->settings, "medclient.dpd", 300);
|
this->dpd = lib->settings->get_int(lib->settings, "medclient.dpd", 300);
|
||||||
this->ike = ike_cfg_create(FALSE, FALSE, host_create_any(AF_INET),
|
this->ike = ike_cfg_create(FALSE, FALSE, "0.0.0.0", "0.0.0.0");
|
||||||
host_create_any(AF_INET));
|
|
||||||
this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE));
|
this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE));
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
|
|||||||
@@ -139,8 +139,7 @@ medsrv_config_t *medsrv_config_create(database_t *db)
|
|||||||
this->rekey = lib->settings->get_int(lib->settings,
|
this->rekey = lib->settings->get_int(lib->settings,
|
||||||
"medmanager.rekey", 20) * 60;
|
"medmanager.rekey", 20) * 60;
|
||||||
this->dpd = lib->settings->get_int(lib->settings, "medmanager.dpd", 300);
|
this->dpd = lib->settings->get_int(lib->settings, "medmanager.dpd", 300);
|
||||||
this->ike = ike_cfg_create(FALSE, FALSE, host_create_any(AF_INET),
|
this->ike = ike_cfg_create(FALSE, FALSE, "0.0.0.0", "0.0.0.0");
|
||||||
host_create_any(AF_INET));
|
|
||||||
this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE));
|
this->ike->add_proposal(this->ike, proposal_create_default(PROTO_IKE));
|
||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
|
|||||||
@@ -179,34 +179,9 @@ static ike_cfg_t *build_ike_cfg(private_sql_config_t *this, enumerator_t *e,
|
|||||||
|
|
||||||
while (e->enumerate(e, &certreq, &force_encap, &local, &remote))
|
while (e->enumerate(e, &certreq, &force_encap, &local, &remote))
|
||||||
{
|
{
|
||||||
host_t *me, *other;
|
|
||||||
ike_cfg_t *ike_cfg;
|
ike_cfg_t *ike_cfg;
|
||||||
|
|
||||||
me = host_create_from_string(local, 500);
|
ike_cfg = ike_cfg_create(certreq, force_encap, local, remote);
|
||||||
if (!me)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (my_host && !me->is_anyaddr(me) &&
|
|
||||||
!me->ip_equals(me, my_host))
|
|
||||||
{
|
|
||||||
me->destroy(me);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
other = host_create_from_string(remote, 500);
|
|
||||||
if (!other)
|
|
||||||
{
|
|
||||||
me->destroy(me);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (other_host && !other->is_anyaddr(other) &&
|
|
||||||
!other->ip_equals(other, other_host))
|
|
||||||
{
|
|
||||||
me->destroy(me);
|
|
||||||
other->destroy(other);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ike_cfg = ike_cfg_create(certreq, force_encap, me, other);
|
|
||||||
/* TODO: read proposal from db */
|
/* TODO: read proposal from db */
|
||||||
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
|
ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
|
||||||
return ike_cfg;
|
return ike_cfg;
|
||||||
|
|||||||
@@ -139,20 +139,8 @@ static void ike_data_destroy(ike_data_t *data)
|
|||||||
*/
|
*/
|
||||||
static bool ike_filter(ike_data_t *data, peer_cfg_t **in, ike_cfg_t **out)
|
static bool ike_filter(ike_data_t *data, peer_cfg_t **in, ike_cfg_t **out)
|
||||||
{
|
{
|
||||||
ike_cfg_t *ike_cfg;
|
*out = (*in)->get_ike_cfg(*in);
|
||||||
host_t *me, *other;
|
return TRUE;
|
||||||
|
|
||||||
ike_cfg = (*in)->get_ike_cfg(*in);
|
|
||||||
|
|
||||||
me = ike_cfg->get_my_host(ike_cfg);
|
|
||||||
other = ike_cfg->get_other_host(ike_cfg);
|
|
||||||
if ((!data->me || me->is_anyaddr(me) || me->ip_equals(me, data->me)) &&
|
|
||||||
(!data->other || other->is_anyaddr(other) || other->ip_equals(other, data->other)))
|
|
||||||
{
|
|
||||||
*out = ike_cfg;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -296,58 +284,50 @@ static void add_proposals(private_stroke_config_t *this, char *string,
|
|||||||
*/
|
*/
|
||||||
static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg)
|
static ike_cfg_t *build_ike_cfg(private_stroke_config_t *this, stroke_msg_t *msg)
|
||||||
{
|
{
|
||||||
host_t *me = NULL, *other = NULL, *tmp;
|
|
||||||
stroke_end_t tmp_end;
|
stroke_end_t tmp_end;
|
||||||
ike_cfg_t *ike_cfg;
|
ike_cfg_t *ike_cfg;
|
||||||
char *interface;
|
char *interface;
|
||||||
|
host_t *host;
|
||||||
if (msg->add_conn.me.address)
|
|
||||||
{
|
host = host_create_from_dns(msg->add_conn.other.address, 0, 0);
|
||||||
me = host_create_from_string(msg->add_conn.me.address, IKEV2_UDP_PORT);
|
if (host)
|
||||||
}
|
|
||||||
if (!me)
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, "invalid left host: %s", msg->add_conn.me.address);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (msg->add_conn.other.address)
|
|
||||||
{
|
|
||||||
other = host_create_from_string(msg->add_conn.other.address, IKEV2_UDP_PORT);
|
|
||||||
}
|
|
||||||
if (!other)
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, "invalid right host: %s", msg->add_conn.other.address);
|
|
||||||
me->destroy(me);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
interface = charon->kernel_interface->get_interface(
|
|
||||||
charon->kernel_interface, other);
|
|
||||||
if (interface)
|
|
||||||
{
|
|
||||||
DBG2(DBG_CFG, "left is other host, swapping ends");
|
|
||||||
tmp = me;
|
|
||||||
me = other;
|
|
||||||
other = tmp;
|
|
||||||
tmp_end = msg->add_conn.me;
|
|
||||||
msg->add_conn.me = msg->add_conn.other;
|
|
||||||
msg->add_conn.other = tmp_end;
|
|
||||||
free(interface);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
interface = charon->kernel_interface->get_interface(
|
interface = charon->kernel_interface->get_interface(
|
||||||
charon->kernel_interface, me);
|
charon->kernel_interface, host);
|
||||||
if (!interface)
|
host->destroy(host);
|
||||||
|
if (interface)
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "left nor right host is our side, assuming left=local");
|
DBG2(DBG_CFG, "left is other host, swapping ends");
|
||||||
|
tmp_end = msg->add_conn.me;
|
||||||
|
msg->add_conn.me = msg->add_conn.other;
|
||||||
|
msg->add_conn.other = tmp_end;
|
||||||
|
free(interface);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
free(interface);
|
host = host_create_from_dns(msg->add_conn.me.address, 0, 0);
|
||||||
|
if (host)
|
||||||
|
{
|
||||||
|
interface = charon->kernel_interface->get_interface(
|
||||||
|
charon->kernel_interface, host);
|
||||||
|
host->destroy(host);
|
||||||
|
if (!interface)
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, "left nor right host is our side, "
|
||||||
|
"assuming left=local");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
free(interface);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ike_cfg = ike_cfg_create(msg->add_conn.other.sendcert != CERT_NEVER_SEND,
|
ike_cfg = ike_cfg_create(msg->add_conn.other.sendcert != CERT_NEVER_SEND,
|
||||||
msg->add_conn.force_encap, me, other);
|
msg->add_conn.force_encap,
|
||||||
|
msg->add_conn.me.address,
|
||||||
|
msg->add_conn.other.address);
|
||||||
add_proposals(this, msg->add_conn.algorithms.ike, ike_cfg, NULL);
|
add_proposals(this, msg->add_conn.algorithms.ike, ike_cfg, NULL);
|
||||||
return ike_cfg;
|
return ike_cfg;
|
||||||
}
|
}
|
||||||
@@ -485,8 +465,14 @@ static peer_cfg_t *build_peer_cfg(private_stroke_config_t *this,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
host_t* my_host = ike_cfg->get_my_host(ike_cfg);
|
if (strchr(ike_cfg->get_my_addr(ike_cfg), ':'))
|
||||||
vip = host_create_any(my_host->get_family(my_host));
|
{
|
||||||
|
vip = host_create_any(AF_INET6);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vip = host_create_any(AF_INET);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -777,9 +763,9 @@ static void add(private_stroke_config_t *this, stroke_msg_t *msg)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* add config to backend */
|
/* add config to backend */
|
||||||
DBG1(DBG_CFG, "added configuration '%s': %H[%D]...%H[%D]", msg->add_conn.name,
|
DBG1(DBG_CFG, "added configuration '%s': %s[%D]...%s[%D]", msg->add_conn.name,
|
||||||
ike_cfg->get_my_host(ike_cfg), peer_cfg->get_my_id(peer_cfg),
|
ike_cfg->get_my_addr(ike_cfg), peer_cfg->get_my_id(peer_cfg),
|
||||||
ike_cfg->get_other_host(ike_cfg), peer_cfg->get_other_id(peer_cfg));
|
ike_cfg->get_other_addr(ike_cfg), peer_cfg->get_other_id(peer_cfg));
|
||||||
this->mutex->lock(this->mutex);
|
this->mutex->lock(this->mutex);
|
||||||
this->list->insert_last(this->list, peer_cfg);
|
this->list->insert_last(this->list, peer_cfg);
|
||||||
this->mutex->unlock(this->mutex);
|
this->mutex->unlock(this->mutex);
|
||||||
|
|||||||
@@ -229,9 +229,9 @@ static void status(private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, bo
|
|||||||
}
|
}
|
||||||
|
|
||||||
ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
|
ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
|
||||||
fprintf(out, "%12s: %H[%D]...%H[%D]\n", peer_cfg->get_name(peer_cfg),
|
fprintf(out, "%12s: %s[%D]...%s[%D]\n", peer_cfg->get_name(peer_cfg),
|
||||||
ike_cfg->get_my_host(ike_cfg), peer_cfg->get_my_id(peer_cfg),
|
ike_cfg->get_my_addr(ike_cfg), peer_cfg->get_my_id(peer_cfg),
|
||||||
ike_cfg->get_other_host(ike_cfg), peer_cfg->get_other_id(peer_cfg));
|
ike_cfg->get_other_addr(ike_cfg), peer_cfg->get_other_id(peer_cfg));
|
||||||
/* TODO: list CAs and groups */
|
/* TODO: list CAs and groups */
|
||||||
children = peer_cfg->create_child_cfg_enumerator(peer_cfg);
|
children = peer_cfg->create_child_cfg_enumerator(peer_cfg);
|
||||||
while (children->enumerate(children, &child_cfg))
|
while (children->enumerate(children, &child_cfg))
|
||||||
|
|||||||
+26
-14
@@ -410,18 +410,6 @@ static void set_peer_cfg(private_ike_sa_t *this, peer_cfg_t *peer_cfg)
|
|||||||
this->ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
|
this->ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
|
||||||
this->ike_cfg->get_ref(this->ike_cfg);
|
this->ike_cfg->get_ref(this->ike_cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* apply values, so we are ready to initate/acquire */
|
|
||||||
if (this->my_host->is_anyaddr(this->my_host))
|
|
||||||
{
|
|
||||||
host_t *me = this->ike_cfg->get_my_host(this->ike_cfg);
|
|
||||||
set_my_host(this, me->clone(me));
|
|
||||||
}
|
|
||||||
if (this->other_host->is_anyaddr(this->other_host))
|
|
||||||
{
|
|
||||||
host_t *other = this->ike_cfg->get_other_host(this->ike_cfg);
|
|
||||||
set_other_host(this, other->clone(other));
|
|
||||||
}
|
|
||||||
/* apply IDs if they are not already set */
|
/* apply IDs if they are not already set */
|
||||||
if (this->my_id->contains_wildcards(this->my_id))
|
if (this->my_id->contains_wildcards(this->my_id))
|
||||||
{
|
{
|
||||||
@@ -1041,6 +1029,28 @@ static status_t initiate_mediated(private_ike_sa_t *this, host_t *me, host_t *ot
|
|||||||
}
|
}
|
||||||
#endif /* ME */
|
#endif /* ME */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve DNS host in configuration
|
||||||
|
*/
|
||||||
|
static void resolve_hosts(private_ike_sa_t *this)
|
||||||
|
{
|
||||||
|
host_t *host;
|
||||||
|
|
||||||
|
host = host_create_from_dns(this->ike_cfg->get_my_addr(this->ike_cfg), 0,
|
||||||
|
IKEV2_UDP_PORT);
|
||||||
|
if (host)
|
||||||
|
{
|
||||||
|
set_my_host(this, host);
|
||||||
|
}
|
||||||
|
host = host_create_from_dns(this->ike_cfg->get_other_addr(this->ike_cfg),
|
||||||
|
this->my_host->get_family(this->my_host),
|
||||||
|
IKEV2_UDP_PORT);
|
||||||
|
if (host)
|
||||||
|
{
|
||||||
|
set_other_host(this, host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initiates a CHILD_SA using the appropriate reqid
|
* Initiates a CHILD_SA using the appropriate reqid
|
||||||
*/
|
*/
|
||||||
@@ -1050,6 +1060,8 @@ static status_t initiate_with_reqid(private_ike_sa_t *this, child_cfg_t *child_c
|
|||||||
|
|
||||||
if (this->state == IKE_CREATED)
|
if (this->state == IKE_CREATED)
|
||||||
{
|
{
|
||||||
|
resolve_hosts(this);
|
||||||
|
|
||||||
if (this->other_host->is_anyaddr(this->other_host)
|
if (this->other_host->is_anyaddr(this->other_host)
|
||||||
#ifdef ME
|
#ifdef ME
|
||||||
&& !this->peer_cfg->get_mediated_by(this->peer_cfg)
|
&& !this->peer_cfg->get_mediated_by(this->peer_cfg)
|
||||||
@@ -2516,8 +2528,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
|
|||||||
/* initialize private fields */
|
/* initialize private fields */
|
||||||
this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
|
this->ike_sa_id = ike_sa_id->clone(ike_sa_id);
|
||||||
this->child_sas = linked_list_create();
|
this->child_sas = linked_list_create();
|
||||||
this->my_host = host_create_any(AF_INET);
|
this->my_host = host_create_from_string("0.0.0.0", IKEV2_UDP_PORT);
|
||||||
this->other_host = host_create_any(AF_INET);
|
this->other_host = host_create_from_string("0.0.0.0", IKEV2_UDP_PORT);
|
||||||
this->my_id = identification_create_from_encoding(ID_ANY, chunk_empty);
|
this->my_id = identification_create_from_encoding(ID_ANY, chunk_empty);
|
||||||
this->other_id = identification_create_from_encoding(ID_ANY, chunk_empty);
|
this->other_id = identification_create_from_encoding(ID_ANY, chunk_empty);
|
||||||
this->extensions = 0;
|
this->extensions = 0;
|
||||||
|
|||||||
@@ -497,64 +497,70 @@ static ike_sa_t* checkout_by_config(private_ike_sa_manager_t *this,
|
|||||||
ike_cfg_t *ike_cfg;
|
ike_cfg_t *ike_cfg;
|
||||||
|
|
||||||
ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
|
ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
|
||||||
my_host = ike_cfg->get_my_host(ike_cfg);
|
|
||||||
other_host = ike_cfg->get_other_host(ike_cfg);
|
|
||||||
my_id = peer_cfg->get_my_id(peer_cfg);
|
my_id = peer_cfg->get_my_id(peer_cfg);
|
||||||
other_id = peer_cfg->get_other_id(peer_cfg);
|
other_id = peer_cfg->get_other_id(peer_cfg);
|
||||||
|
my_host = host_create_from_dns(ike_cfg->get_my_addr(ike_cfg), 0, 0);
|
||||||
|
other_host = host_create_from_dns(ike_cfg->get_other_addr(ike_cfg), 0, 0);
|
||||||
|
|
||||||
pthread_mutex_lock(&(this->mutex));
|
pthread_mutex_lock(&(this->mutex));
|
||||||
|
|
||||||
enumerator = this->ike_sa_list->create_enumerator(this->ike_sa_list);
|
if (my_host && other_host)
|
||||||
while (enumerator->enumerate(enumerator, &entry))
|
|
||||||
{
|
{
|
||||||
identification_t *found_my_id, *found_other_id;
|
enumerator = this->ike_sa_list->create_enumerator(this->ike_sa_list);
|
||||||
host_t *found_my_host, *found_other_host;
|
while (enumerator->enumerate(enumerator, &entry))
|
||||||
|
|
||||||
if (!wait_for_entry(this, entry))
|
|
||||||
{
|
{
|
||||||
continue;
|
identification_t *found_my_id, *found_other_id;
|
||||||
}
|
host_t *found_my_host, *found_other_host;
|
||||||
|
|
||||||
if (entry->ike_sa->get_state(entry->ike_sa) == IKE_DELETING)
|
if (!wait_for_entry(this, entry))
|
||||||
{
|
{
|
||||||
/* skip IKE_SA which are not useable */
|
continue;
|
||||||
continue;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
found_my_id = entry->ike_sa->get_my_id(entry->ike_sa);
|
if (entry->ike_sa->get_state(entry->ike_sa) == IKE_DELETING)
|
||||||
found_other_id = entry->ike_sa->get_other_id(entry->ike_sa);
|
{
|
||||||
found_my_host = entry->ike_sa->get_my_host(entry->ike_sa);
|
/* skip IKE_SA which are not useable */
|
||||||
found_other_host = entry->ike_sa->get_other_host(entry->ike_sa);
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (found_my_id->get_type(found_my_id) == ID_ANY &&
|
found_my_id = entry->ike_sa->get_my_id(entry->ike_sa);
|
||||||
found_other_id->get_type(found_other_id) == ID_ANY)
|
found_other_id = entry->ike_sa->get_other_id(entry->ike_sa);
|
||||||
{
|
found_my_host = entry->ike_sa->get_my_host(entry->ike_sa);
|
||||||
/* IKE_SA has no IDs yet, so we can't use it */
|
found_other_host = entry->ike_sa->get_other_host(entry->ike_sa);
|
||||||
continue;
|
|
||||||
}
|
if (found_my_id->get_type(found_my_id) == ID_ANY &&
|
||||||
DBG2(DBG_MGR, "candidate IKE_SA for \n\t%H[%D]...%H[%D]\n\t%H[%D]...%H[%D]",
|
found_other_id->get_type(found_other_id) == ID_ANY)
|
||||||
my_host, my_id, other_host, other_id,
|
{
|
||||||
found_my_host, found_my_id, found_other_host, found_other_id);
|
/* IKE_SA has no IDs yet, so we can't use it */
|
||||||
/* compare ID and hosts. Supplied ID may contain wildcards, and IP
|
continue;
|
||||||
* may be %any. */
|
}
|
||||||
if ((my_host->is_anyaddr(my_host) ||
|
DBG2(DBG_MGR, "candidate IKE_SA for \n\t"
|
||||||
my_host->ip_equals(my_host, found_my_host)) &&
|
"%H[%D]...%H[%D]\n\t%H[%D]...%H[%D]",
|
||||||
(other_host->is_anyaddr(other_host) ||
|
my_host, my_id, other_host, other_id,
|
||||||
other_host->ip_equals(other_host, found_other_host)) &&
|
found_my_host, found_my_id, found_other_host, found_other_id);
|
||||||
found_my_id->matches(found_my_id, my_id) &&
|
/* compare ID and hosts. Supplied ID may contain wildcards, and IP
|
||||||
found_other_id->matches(found_other_id, other_id) &&
|
* may be %any. */
|
||||||
streq(peer_cfg->get_name(peer_cfg),
|
if ((my_host->is_anyaddr(my_host) ||
|
||||||
entry->ike_sa->get_name(entry->ike_sa)))
|
my_host->ip_equals(my_host, found_my_host)) &&
|
||||||
{
|
(other_host->is_anyaddr(other_host) ||
|
||||||
/* looks good, we take this one */
|
other_host->ip_equals(other_host, found_other_host)) &&
|
||||||
DBG2(DBG_MGR, "found an existing IKE_SA for %H[%D]...%H[%D]",
|
found_my_id->matches(found_my_id, my_id) &&
|
||||||
my_host, my_id, other_host, other_id);
|
found_other_id->matches(found_other_id, other_id) &&
|
||||||
entry->checked_out = TRUE;
|
streq(peer_cfg->get_name(peer_cfg),
|
||||||
ike_sa = entry->ike_sa;
|
entry->ike_sa->get_name(entry->ike_sa)))
|
||||||
break;
|
{
|
||||||
|
/* looks good, we take this one */
|
||||||
|
DBG2(DBG_MGR, "found an existing IKE_SA for %H[%D]...%H[%D]",
|
||||||
|
my_host, my_id, other_host, other_id);
|
||||||
|
entry->checked_out = TRUE;
|
||||||
|
ike_sa = entry->ike_sa;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
DESTROY_IF(my_host);
|
||||||
|
DESTROY_IF(other_host);
|
||||||
|
|
||||||
if (!ike_sa)
|
if (!ike_sa)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ static status_t build_i(private_ike_init_t *this, message_t *message)
|
|||||||
this->config = this->ike_sa->get_ike_cfg(this->ike_sa);
|
this->config = this->ike_sa->get_ike_cfg(this->ike_sa);
|
||||||
SIG(IKE_UP_START, "initiating IKE_SA '%s' to %H",
|
SIG(IKE_UP_START, "initiating IKE_SA '%s' to %H",
|
||||||
this->ike_sa->get_name(this->ike_sa),
|
this->ike_sa->get_name(this->ike_sa),
|
||||||
this->config->get_other_host(this->config));
|
this->ike_sa->get_other_host(this->ike_sa));
|
||||||
this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING);
|
this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING);
|
||||||
|
|
||||||
if (this->retry++ >= MAX_RETRIES)
|
if (this->retry++ >= MAX_RETRIES)
|
||||||
|
|||||||
@@ -18,11 +18,14 @@
|
|||||||
* $Id$
|
* $Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <netdb.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <printf.h>
|
#include <printf.h>
|
||||||
|
|
||||||
#include "host.h"
|
#include "host.h"
|
||||||
|
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
typedef struct private_host_t private_host_t;
|
typedef struct private_host_t private_host_t;
|
||||||
|
|
||||||
@@ -448,6 +451,56 @@ host_t *host_create_from_string(char *string, u_int16_t port)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Described in header.
|
||||||
|
*/
|
||||||
|
host_t *host_create_from_dns(char *string, int af, u_int16_t port)
|
||||||
|
{
|
||||||
|
private_host_t *this;
|
||||||
|
struct hostent host, *ptr;
|
||||||
|
char buf[512];
|
||||||
|
int err, ret;
|
||||||
|
|
||||||
|
if (af)
|
||||||
|
{
|
||||||
|
ret = gethostbyname2_r(string, af, &host, buf, sizeof(buf), &ptr, &err);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = gethostbyname_r(string, &host, buf, sizeof(buf), &ptr, &err);
|
||||||
|
}
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
DBG1("resolving '%s' failed: %s", string, hstrerror(err));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (ptr == NULL)
|
||||||
|
{
|
||||||
|
DBG1("resolving '%s' failed", string);
|
||||||
|
}
|
||||||
|
this = host_create_empty();
|
||||||
|
this->address.sa_family = host.h_addrtype;
|
||||||
|
switch (af)
|
||||||
|
{
|
||||||
|
case AF_INET:
|
||||||
|
memcpy(&this->address4.sin_addr.s_addr,
|
||||||
|
host.h_addr_list[0], host.h_length);
|
||||||
|
this->address4.sin_port = htons(port);
|
||||||
|
this->socklen = sizeof(struct sockaddr_in);
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
memcpy(&this->address6.sin6_addr.s6_addr,
|
||||||
|
host.h_addr_list[0], host.h_length);
|
||||||
|
this->address6.sin6_port = htons(port);
|
||||||
|
this->socklen = sizeof(struct sockaddr_in6);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
free(this);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return &this->public;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Described in header.
|
* Described in header.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -159,6 +159,16 @@ struct host_t {
|
|||||||
*/
|
*/
|
||||||
host_t *host_create_from_string(char *string, u_int16_t port);
|
host_t *host_create_from_string(char *string, u_int16_t port);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor to create a host_t from a DNS name.
|
||||||
|
*
|
||||||
|
* @param string hostname to resolve
|
||||||
|
* @param family family to prefer, 0 for first match
|
||||||
|
* @param port port number
|
||||||
|
* @return host_t, NULL lookup failed
|
||||||
|
*/
|
||||||
|
host_t *host_create_from_dns(char *string, int family, u_int16_t port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor to create a host_t object from an address chunk
|
* Constructor to create a host_t object from an address chunk
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -250,6 +250,8 @@ char *whitelist[] = {
|
|||||||
"getprotobynumber",
|
"getprotobynumber",
|
||||||
"getservbyport",
|
"getservbyport",
|
||||||
"getservbyname",
|
"getservbyname",
|
||||||
|
"gethostbyname_r",
|
||||||
|
"gethostbyname2_r",
|
||||||
"getpwnam_r",
|
"getpwnam_r",
|
||||||
"getgrnam_r",
|
"getgrnam_r",
|
||||||
"register_printf_function",
|
"register_printf_function",
|
||||||
|
|||||||
Reference in New Issue
Block a user