Handle RESPONDER-LIFETIME notification in quick mode.

This commit is contained in:
tteras 2008-07-14 05:45:15 +00:00
parent 583275a951
commit 56a42db6a6
6 changed files with 156 additions and 9 deletions

View File

@ -9,6 +9,12 @@
src/racoon/strnames.c : clean ups to notification payload handling,
and handle INITIAL-CONTACT notification in last main mode exchange
(delayed) and during quick mode exchanges (Track:264)
* src/racoon/handler.h
src/racoon/ipsec_doi.c
src/racoon/ipsec_doi.h
src/racoon/isakmp_quick.c
src/racoon/pfkey.c : handle RESPONDER-LIFETIME notification
according to proposal check level (Track:265)
2008-07-11 Timo Teras <timo.teras@iki.fi>
Track:259, original patch from Atis Elsts <the.kfx@gmail.com>:

View File

@ -1,4 +1,4 @@
/* $NetBSD: handler.h,v 1.13 2008/07/14 05:40:13 tteras Exp $ */
/* $NetBSD: handler.h,v 1.14 2008/07/14 05:45:15 tteras Exp $ */
/* Id: handler.h,v 1.19 2006/02/25 08:25:12 manubsd Exp */
@ -294,6 +294,8 @@ struct ph2handle {
struct sainfo *sainfo; /* place holder of sainfo */
struct saprop *proposal; /* SA(s) proposal. */
struct saprop *approval; /* SA(s) approved. */
u_int32_t lifetime_secs; /* responder lifetime (seconds) */
u_int32_t lifetime_kb; /* responder lifetime (kbytes) */
caddr_t spidx_gen; /* policy from peer's proposal */
struct dhgroup *pfsgrp; /* DH; prime number */

View File

@ -1,4 +1,4 @@
/* $NetBSD: ipsec_doi.c,v 1.35 2008/06/18 06:47:25 mgrooms Exp $ */
/* $NetBSD: ipsec_doi.c,v 1.36 2008/07/14 05:45:15 tteras Exp $ */
/* Id: ipsec_doi.c,v 1.55 2006/08/17 09:20:41 vanhu Exp */
@ -1824,6 +1824,96 @@ ipsecdoi_set_ld(buf)
return ld;
}
/*
* parse responder-lifetime attributes from payload
*/
int
ipsecdoi_parse_responder_lifetime(notify, lifetime_sec, lifetime_kb)
struct isakmp_pl_n *notify;
u_int32_t *lifetime_sec;
u_int32_t *lifetime_kb;
{
struct isakmp_data *d;
int flag, type, tlen, ld_type = -1;
u_int16_t lorv;
u_int32_t value;
tlen = ntohs(notify->h.len) - sizeof(*notify) - notify->spi_size;
d = (struct isakmp_data *)((char *)(notify + 1) +
notify->spi_size);
while (tlen >= sizeof(struct isakmp_data)) {
type = ntohs(d->type) & ~ISAKMP_GEN_MASK;
flag = ntohs(d->type) & ISAKMP_GEN_MASK;
lorv = ntohs(d->lorv);
plog(LLV_DEBUG, LOCATION, NULL,
"type=%s, flag=0x%04x, lorv=%s\n",
s_ipsecdoi_attr(type), flag,
s_ipsecdoi_attr_v(type, lorv));
switch (type) {
case IPSECDOI_ATTR_SA_LD_TYPE:
if (! flag) {
plog(LLV_ERROR, LOCATION, NULL,
"must be TV when LD_TYPE.\n");
return -1;
}
ld_type = lorv;
break;
case IPSECDOI_ATTR_SA_LD:
if (flag)
value = lorv;
else if (lorv == 2)
value = ntohs(*(u_int16_t *)(d + 1));
else if (lorv == 4)
value = ntohl(*(u_int32_t *)(d + 1));
else {
plog(LLV_ERROR, LOCATION, NULL,
"payload length %d for lifetime "
"data length is unsupported.\n", lorv);
return -1;
}
switch (ld_type) {
case IPSECDOI_ATTR_SA_LD_TYPE_SEC:
if (lifetime_sec != NULL)
*lifetime_sec = value;
plog(LLV_INFO, LOCATION, NULL,
"received RESPONDER-LIFETIME: %d "
"seconds\n", value);
break;
case IPSECDOI_ATTR_SA_LD_TYPE_KB:
if (lifetime_kb != NULL)
*lifetime_kb = value;
plog(LLV_INFO, LOCATION, NULL,
"received RESPONDER-LIFETIME: %d "
"kbytes\n", value);
break;
default:
plog(LLV_ERROR, LOCATION, NULL,
"lifetime data received without "
"lifetime data type.\n");
return -1;
}
break;
}
if (flag) {
tlen -= sizeof(*d);
d = (struct isakmp_data *)((char *)d
+ sizeof(*d));
} else {
tlen -= (sizeof(*d) + lorv);
d = (struct isakmp_data *)((char *)d
+ sizeof(*d) + lorv);
}
}
return 0;
}
/*%%%*/
/*
* check DOI

View File

@ -1,4 +1,4 @@
/* $NetBSD: ipsec_doi.h,v 1.10 2007/12/04 19:52:30 mgrooms Exp $ */
/* $NetBSD: ipsec_doi.h,v 1.11 2008/07/14 05:45:15 tteras Exp $ */
/* Id: ipsec_doi.h,v 1.15 2006/08/11 16:06:30 vanhu Exp */
@ -245,5 +245,8 @@ extern int ipsecdoi_authalg2trnsid __P((int));
extern int idtype2doi __P((int));
extern int doi2idtype __P((int));
extern int ipsecdoi_parse_responder_lifetime __P((struct isakmp_pl_n *notify,
u_int32_t *lifetime_sec, u_int32_t *liftime_kb));
#endif /* _IPSEC_DOI_H */

View File

@ -1,4 +1,4 @@
/* $NetBSD: isakmp_quick.c,v 1.18 2008/07/14 05:40:13 tteras Exp $ */
/* $NetBSD: isakmp_quick.c,v 1.19 2008/07/14 05:45:15 tteras Exp $ */
/* Id: isakmp_quick.c,v 1.29 2006/08/22 18:17:17 manubsd Exp */
@ -2482,15 +2482,55 @@ ph2_recv_n(iph2, gen)
struct ph2handle *iph2;
struct isakmp_gen *gen;
{
struct ph1handle *iph1 = iph2->ph1;
struct isakmp_pl_n *notify = (struct isakmp_pl_n *) gen;
u_int type;
int check_level;
type = ntohs(notify->type);
switch (type) {
case ISAKMP_NTYPE_CONNECTED:
break;
case ISAKMP_NTYPE_INITIAL_CONTACT:
return isakmp_info_recv_initialcontact(iph2->ph1, iph2);
return isakmp_info_recv_initialcontact(iph1, iph2);
case ISAKMP_NTYPE_RESPONDER_LIFETIME:
ipsecdoi_parse_responder_lifetime(notify,
&iph2->lifetime_secs, &iph2->lifetime_kb);
if (iph1 != NULL && iph1->rmconf != NULL) {
check_level = iph1->rmconf->pcheck_level;
} else {
if (iph1 != NULL)
plog(LLV_DEBUG, LOCATION, NULL,
"No phase1 rmconf found !\n");
else
plog(LLV_DEBUG, LOCATION, NULL,
"No phase1 found !\n");
check_level = PROP_CHECK_EXACT;
}
switch (check_level) {
case PROP_CHECK_OBEY:
break;
case PROP_CHECK_STRICT:
case PROP_CHECK_CLAIM:
if (iph2->sainfo == NULL
|| iph2->sainfo->lifetime <= iph2->lifetime_secs) {
plog(LLV_WARNING, LOCATION, NULL,
"RESPONDER-LIFETIME: lifetime mismatch\n");
iph2->lifetime_secs = 0;
}
break;
case PROP_CHECK_EXACT:
if (iph2->sainfo == NULL
|| iph2->sainfo->lifetime != iph2->lifetime_secs) {
plog(LLV_WARNING, LOCATION, NULL,
"RESPONDER-LIFETIME: lifetime mismatch\n");
iph2->lifetime_secs = 0;
}
break;
}
break;
default:
isakmp_log_notify(iph2->ph1, notify, "phase2 exchange");
isakmp_info_send_n2(iph2, ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE,

View File

@ -1,6 +1,6 @@
/* $NetBSD: pfkey.c,v 1.28 2008/06/18 06:11:38 mgrooms Exp $ */
/* $NetBSD: pfkey.c,v 1.29 2008/07/14 05:45:15 tteras Exp $ */
/* $Id: pfkey.c,v 1.28 2008/06/18 06:11:38 mgrooms Exp $ */
/* $Id: pfkey.c,v 1.29 2008/07/14 05:45:15 tteras Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -1058,7 +1058,10 @@ pk_sendupdate(iph2)
/* fill in some needed for pfkey_send_update2 */
memset (&sa_args, 0, sizeof (sa_args));
sa_args.so = lcconf->sock_pfkey;
sa_args.l_addtime = iph2->approval->lifetime;
if (iph2->lifetime_secs)
sa_args.l_addtime = iph2->lifetime_secs;
else
sa_args.l_addtime = iph2->approval->lifetime;
sa_args.seq = iph2->seq;
sa_args.wsize = 4;
@ -1344,7 +1347,10 @@ pk_sendadd(iph2)
/* fill in some needed for pfkey_send_update2 */
memset (&sa_args, 0, sizeof (sa_args));
sa_args.so = lcconf->sock_pfkey;
sa_args.l_addtime = iph2->approval->lifetime;
if (iph2->lifetime_secs)
sa_args.l_addtime = iph2->lifetime_secs;
else
sa_args.l_addtime = iph2->approval->lifetime;
sa_args.seq = iph2->seq;
sa_args.wsize = 4;