summaryrefslogtreecommitdiff
path: root/src/pluto/kernel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pluto/kernel.c')
-rw-r--r--src/pluto/kernel.c187
1 files changed, 108 insertions, 79 deletions
diff --git a/src/pluto/kernel.c b/src/pluto/kernel.c
index f698de2c8..46edac1cd 100644
--- a/src/pluto/kernel.c
+++ b/src/pluto/kernel.c
@@ -1,6 +1,7 @@
/* routines that interface with the kernel's IPsec mechanism
* Copyright (C) 1997 Angelos D. Keromytis.
* Copyright (C) 1998-2002 D. Hugh Redelmeier.
+ * Copyright (C) 2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -1849,7 +1850,7 @@ static bool setup_half_ipsec_sa(struct state *st, bool inbound)
if (st->nat_traversal & NAT_T_DETECTED)
{
natt_type = (st->nat_traversal & NAT_T_WITH_PORT_FLOATING) ?
- ESPINUDP_WITH_NON_ESP : ESPINUDP_WITH_NON_IKE;
+ ESPINUDP_WITH_NON_ESP : ESPINUDP_WITH_NON_IKE;
natt_sport = inbound? c->spd.that.host_port : c->spd.this.host_port;
natt_dport = inbound? c->spd.this.host_port : c->spd.that.host_port;
natt_oa = st->nat_oa;
@@ -1860,12 +1861,11 @@ static bool setup_half_ipsec_sa(struct state *st, bool inbound)
if (ei == &esp_info[countof(esp_info)])
{
/* Check for additional kernel alg */
-#ifndef NO_KERNEL_ALG
if ((ei=kernel_alg_esp_info(st->st_esp.attrs.transid,
- st->st_esp.attrs.auth))!=NULL) {
- break;
+ st->st_esp.attrs.auth))!=NULL)
+ {
+ break;
}
-#endif
/* note: enum_show may use a static buffer, so two
* calls in one printf would be a mistake.
@@ -1878,9 +1878,11 @@ static bool setup_half_ipsec_sa(struct state *st, bool inbound)
goto fail;
}
- if (st->st_esp.attrs.transid == ei->transid
- && st->st_esp.attrs.auth == ei->auth)
+ if (st->st_esp.attrs.transid == ei->transid &&
+ st->st_esp.attrs.auth == ei->auth)
+ {
break;
+ }
}
key_len = st->st_esp.attrs.key_len/8;
@@ -1899,40 +1901,52 @@ static bool setup_half_ipsec_sa(struct state *st, bool inbound)
{
key_len = ei->enckeylen;
}
- /* Grrrrr.... f*cking 7 bits jurassic algos */
-
- /* 168 bits in kernel, need 192 bits for keymat_len */
- if (ei->transid == ESP_3DES && key_len == 21)
- key_len = 24;
- /* 56 bits in kernel, need 64 bits for keymat_len */
- if (ei->transid == ESP_DES && key_len == 7)
- key_len = 8;
+ switch (ei->transid)
+ {
+ case ESP_3DES:
+ /* 168 bits in kernel, need 192 bits for keymat_len */
+ if (key_len == 21)
+ {
+ key_len = 24;
+ }
+ break;
+ case ESP_DES:
+ /* 56 bits in kernel, need 64 bits for keymat_len */
+ if (key_len == 7)
+ {
+ key_len = 8;
+ }
+ break;
+ case ESP_AES_CCM_8:
+ case ESP_AES_CCM_12:
+ case ESP_AES_CCM_16:
+ key_len += 3;
+ break;
+ case ESP_AES_GCM_8:
+ case ESP_AES_GCM_12:
+ case ESP_AES_GCM_16:
+ case ESP_AES_CTR:
+ key_len += 4;
+ break;
+ default:
+ break;
+ }
/* divide up keying material */
- /* passert(st->st_esp.keymat_len == ei->enckeylen + ei->authkeylen); */
- DBG(DBG_KLIPS|DBG_CONTROL|DBG_PARSING,
- if(st->st_esp.keymat_len != key_len + ei->authkeylen)
- DBG_log("keymat_len=%d key_len=%d authkeylen=%d",
- st->st_esp.keymat_len, (int)key_len, (int)ei->authkeylen);
- )
- passert(st->st_esp.keymat_len == key_len + ei->authkeylen);
-
set_text_said(text_said, &dst.addr, esp_spi, SA_ESP);
-
said_next->src = &src.addr;
said_next->dst = &dst.addr;
said_next->src_client = &src_client;
said_next->dst_client = &dst_client;
said_next->spi = esp_spi;
said_next->satype = SADB_SATYPE_ESP;
- said_next->replay_window = (kernel_ops->type == KERNEL_TYPE_KLIPS) ? REPLAY_WINDOW : REPLAY_WINDOW_XFRM;
+ said_next->replay_window = (kernel_ops->type == KERNEL_TYPE_KLIPS) ?
+ REPLAY_WINDOW : REPLAY_WINDOW_XFRM;
said_next->authalg = ei->authalg;
said_next->authkeylen = ei->authkeylen;
- /* said_next->authkey = esp_dst_keymat + ei->enckeylen; */
said_next->authkey = esp_dst_keymat + key_len;
said_next->encalg = ei->encryptalg;
- /* said_next->enckeylen = ei->enckeylen; */
said_next->enckeylen = key_len;
said_next->enckey = esp_dst_keymat;
said_next->encapsulation = encapsulation;
@@ -1945,10 +1959,10 @@ static bool setup_half_ipsec_sa(struct state *st, bool inbound)
said_next->text_said = text_said;
if (!kernel_ops->add_sa(said_next, replace))
+ {
goto fail;
-
+ }
said_next++;
-
encapsulation = ENCAPSULATION_MODE_TRANSPORT;
}
@@ -1963,29 +1977,27 @@ static bool setup_half_ipsec_sa(struct state *st, bool inbound)
switch (st->st_ah.attrs.auth)
{
- case AUTH_ALGORITHM_HMAC_MD5:
- authalg = SADB_AALG_MD5HMAC;
- break;
-
- case AUTH_ALGORITHM_HMAC_SHA1:
- authalg = SADB_AALG_SHA1HMAC;
- break;
-
- default:
- loglog(RC_LOG_SERIOUS, "%s not implemented yet"
- , enum_show(&auth_alg_names, st->st_ah.attrs.auth));
+ case AUTH_ALGORITHM_HMAC_MD5:
+ authalg = SADB_AALG_MD5HMAC;
+ break;
+ case AUTH_ALGORITHM_HMAC_SHA1:
+ authalg = SADB_AALG_SHA1HMAC;
+ break;
+ default:
+ loglog(RC_LOG_SERIOUS, "%s not implemented yet",
+ enum_show(&auth_alg_names, st->st_ah.attrs.auth));
goto fail;
}
set_text_said(text_said, &dst.addr, ah_spi, SA_AH);
-
said_next->src = &src.addr;
said_next->dst = &dst.addr;
said_next->src_client = &src_client;
said_next->dst_client = &dst_client;
said_next->spi = ah_spi;
said_next->satype = SADB_SATYPE_AH;
- said_next->replay_window = (kernel_ops->type == KERNEL_TYPE_KLIPS) ? REPLAY_WINDOW : REPLAY_WINDOW_XFRM;
+ said_next->replay_window = (kernel_ops->type == KERNEL_TYPE_KLIPS) ?
+ REPLAY_WINDOW : REPLAY_WINDOW_XFRM;
said_next->authalg = authalg;
said_next->authkeylen = st->st_ah.keymat_len;
said_next->authkey = ah_dst_keymat;
@@ -1994,10 +2006,10 @@ static bool setup_half_ipsec_sa(struct state *st, bool inbound)
said_next->text_said = text_said;
if (!kernel_ops->add_sa(said_next, replace))
+ {
goto fail;
-
+ }
said_next++;
-
encapsulation = ENCAPSULATION_MODE_TRANSPORT;
}
@@ -2093,7 +2105,9 @@ static bool setup_half_ipsec_sa(struct state *st, bool inbound)
s[1].text_said = text_said1;
if (!kernel_ops->grp_sa(s + 1, s))
+ {
goto fail;
+ }
}
/* could update said, but it will not be used */
}
@@ -2104,8 +2118,10 @@ fail:
{
/* undo the done SPIs */
while (said_next-- != said)
- (void) del_spi(said_next->spi, said_next->proto
- , &src.addr, said_next->dst);
+ {
+ (void) del_spi(said_next->spi, said_next->proto, &src.addr,
+ said_next->dst);
+ }
return FALSE;
}
}
@@ -2216,8 +2232,9 @@ bool get_sa_info(struct state *st, bool inbound, u_int *bytes, time_t *use_time)
*use_time = UNDEFINED_TIME;
if (kernel_ops->get_sa == NULL || !st->st_esp.present)
+ {
return FALSE;
-
+ }
memset(&sa, 0, sizeof(sa));
sa.proto = SA_ESP;
@@ -2241,7 +2258,9 @@ bool get_sa_info(struct state *st, bool inbound, u_int *bytes, time_t *use_time)
DBG_log("get %s", text_said)
)
if (!kernel_ops->get_sa(&sa, bytes))
+ {
return FALSE;
+ }
DBG(DBG_KLIPS,
DBG_log(" current: %d bytes", *bytes)
)
@@ -2266,7 +2285,9 @@ bool get_sa_info(struct state *st, bool inbound, u_int *bytes, time_t *use_time)
sa.dst_client = &c->spd.that.client;
}
if (!kernel_ops->get_policy(&sa, inbound, use_time))
+ {
return FALSE;
+ }
DBG(DBG_KLIPS,
DBG_log(" use_time: %T", use_time, FALSE)
)
@@ -2349,15 +2370,21 @@ bool install_inbound_ipsec_sa(struct state *st)
struct connection *o = route_owner(c, &esr, NULL, NULL);
if (o == NULL)
+ {
break; /* nobody has a route */
+ }
/* note: we ignore the client addresses at this end */
- if (sameaddr(&o->spd.that.host_addr, &c->spd.that.host_addr)
- && o->interface == c->interface)
+ if (sameaddr(&o->spd.that.host_addr, &c->spd.that.host_addr) &&
+ o->interface == c->interface)
+ {
break; /* existing route is compatible */
+ }
if (o->kind == CK_TEMPLATE && streq(o->name, c->name))
+ {
break; /* ??? is this good enough?? */
+ }
loglog(RC_LOG_SERIOUS, "route to peer's client conflicts with \"%s\" %s; releasing old connection to free the route"
, o->name, ip_str(&o->spd.that.host_addr));
@@ -2369,12 +2396,11 @@ bool install_inbound_ipsec_sa(struct state *st)
/* check that we will be able to route and eroute */
switch (could_route(c))
{
- case route_easy:
- case route_nearconflict:
- break;
-
- default:
- return FALSE;
+ case route_easy:
+ case route_nearconflict:
+ break;
+ default:
+ return FALSE;
}
#ifdef KLIPS
@@ -2471,10 +2497,14 @@ bool route_and_eroute(struct connection *c USED_BY_KLIPS,
/* if no state provided, then install a shunt for later */
if (st == NULL)
+ {
eroute_installed = shunt_eroute(c, sr, RT_ROUTED_PROSPECTIVE
, ERO_ADD, "add");
+ }
else
+ {
eroute_installed = sag_eroute(st, sr, ERO_ADD, "add");
+ }
}
/* notify the firewall of a new tunnel */
@@ -2507,8 +2537,7 @@ bool route_and_eroute(struct connection *c USED_BY_KLIPS,
(void) do_command(c, sr, "prepare"); /* just in case; ignore failure */
route_installed = do_command(c, sr, "route");
}
- else if (routed(sr->routing)
- || routes_agree(ro, c))
+ else if (routed(sr->routing) || routes_agree(ro, c))
{
route_installed = TRUE; /* nothing to be done */
}
@@ -2658,11 +2687,13 @@ bool route_and_eroute(struct connection *c USED_BY_KLIPS,
{
/* there was no previous eroute: delete whatever we installed */
if (st == NULL)
- (void) shunt_eroute(c, sr
- , sr->routing, ERO_DELETE, "delete");
+ {
+ (void) shunt_eroute(c, sr, sr->routing, ERO_DELETE, "delete");
+ }
else
- (void) sag_eroute(st, sr
- , ERO_DELETE, "delete");
+ {
+ (void) sag_eroute(st, sr, ERO_DELETE, "delete");
+ }
}
}
@@ -2685,18 +2716,19 @@ bool install_ipsec_sa(struct state *st, bool inbound_also USED_BY_KLIPS)
switch (could_route(st->st_connection))
{
- case route_easy:
- case route_nearconflict:
- break;
-
- default:
- return FALSE;
+ case route_easy:
+ case route_nearconflict:
+ break;
+ default:
+ return FALSE;
}
/* (attempt to) actually set up the SA group */
- if ((inbound_also && !setup_half_ipsec_sa(st, TRUE))
- || !setup_half_ipsec_sa(st, FALSE))
+ if ((inbound_also && !setup_half_ipsec_sa(st, TRUE)) ||
+ !setup_half_ipsec_sa(st, FALSE))
+ {
return FALSE;
+ }
for (sr = &st->st_connection->spd; sr != NULL; sr = sr->next)
{
@@ -2730,12 +2762,11 @@ bool install_ipsec_sa(struct state *st, bool inbound_also USED_BY_KLIPS)
switch (could_route(st->st_connection))
{
- case route_easy:
- case route_nearconflict:
- break;
-
- default:
- return FALSE;
+ case route_easy:
+ case route_nearconflict:
+ break;
+ default:
+ return FALSE;
}
@@ -2778,8 +2809,7 @@ void delete_ipsec_sa(struct state *st USED_BY_KLIPS,
? RT_ROUTED_PROSPECTIVE : RT_ROUTED_FAILURE;
(void) do_command(c, sr, "down");
- if ((c->policy & POLICY_DONT_REKEY)
- && c->kind == CK_INSTANCE)
+ if ((c->policy & POLICY_DONT_REKEY) && c->kind == CK_INSTANCE)
{
/* in this special case, even if the connection
* is still alive (due to an ISAKMP SA),
@@ -2888,8 +2918,7 @@ bool was_eroute_idle(struct state *st, time_t idle_max, time_t *idle_time)
/* Can't open the file, perhaps were are on 26sec? */
time_t use_time;
- if (get_sa_info(st, TRUE, &bytes, &use_time)
- && use_time != UNDEFINED_TIME)
+ if (get_sa_info(st, TRUE, &bytes, &use_time) && use_time != UNDEFINED_TIME)
{
*idle_time = time(NULL) - use_time;
ret = *idle_time >= idle_max;