Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

If the responder does not have any policy in SPD during phase 2 negot…

…iation,

and the directive is set on, then racoon will choice the first proposal
in the SA payload from the initiator, and generate policy entries from
the proposal.  This function is for the responder, and ignored in the
initiator case.

XXX only transport mode case is checked.  should be checked tunnel mode case.
XXX need more consideration about many case.
  • Loading branch information...
commit 9a4ca748efd62b02583a279ea9e87378e85d5ac6 1 parent 6c4eddb
sakane authored
View
6 kame/kame/racoon/handler.c
@@ -1,4 +1,4 @@
-/* $KAME: handler.c,v 1.47 2001/04/03 15:51:55 thorpej Exp $ */
+/* $KAME: handler.c,v 1.48 2001/04/06 14:23:47 sakane Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -479,6 +479,10 @@ initph2(iph2)
flushsaprop(iph2->approval);
iph2->approval = NULL;
}
+ if (iph2->spidx_gen) {
+ racoon_free(iph2->spidx_gen);
+ iph2->spidx_gen = NULL;
+ }
if (iph2->pfsgrp) {
oakley_dhgrp_free(iph2->pfsgrp);
View
3  kame/kame/racoon/handler.h
@@ -1,4 +1,4 @@
-/* $KAME: handler.h,v 1.38 2001/03/05 18:37:07 thorpej Exp $ */
+/* $KAME: handler.h,v 1.39 2001/04/06 14:23:47 sakane Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -247,6 +247,7 @@ struct ph2handle {
struct sainfo *sainfo; /* place holder of sainfo */
struct saprop *proposal; /* SA(s) proposal. */
struct saprop *approval; /* SA(s) approved. */
+ caddr_t spidx_gen; /* policy from peer's proposal */
struct dhgroup *pfsgrp; /* DH; prime number */
vchar_t *dhpriv; /* DH; private value */
View
20 kame/kame/racoon/ipsec_doi.c
@@ -1,4 +1,4 @@
-/* $KAME: ipsec_doi.c,v 1.132 2001/04/04 04:58:15 sakane Exp $ */
+/* $KAME: ipsec_doi.c,v 1.133 2001/04/06 14:23:47 sakane Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -98,7 +98,6 @@ static void free_proppair0 __P((struct prop_pair *));
static int get_transform
__P((struct isakmp_pl_p *, struct prop_pair **, int *));
-static vchar_t *get_sabyproppair __P((struct prop_pair *, struct ph1handle *));
static u_int32_t ipsecdoi_set_ld __P((vchar_t *));
static int check_doi __P((u_int32_t));
@@ -1314,7 +1313,7 @@ get_transform(prop, pair, num_p)
* make a new SA payload from prop_pair.
* NOTE: this function make spi value clear.
*/
-static vchar_t *
+vchar_t *
get_sabyproppair(pair, iph1)
struct prop_pair *pair;
struct ph1handle *iph1;
@@ -2918,6 +2917,21 @@ ipproto2doi(proto)
return -1; /* XXX */
}
+int
+doi2ipproto(proto)
+ int proto;
+{
+ switch (proto) {
+ case IPSECDOI_PROTO_IPSEC_AH:
+ return IPPROTO_AH;
+ case IPSECDOI_PROTO_IPSEC_ESP:
+ return IPPROTO_ESP;
+ case IPSECDOI_PROTO_IPCOMP:
+ return IPPROTO_IPCOMP;
+ }
+ return -1; /* XXX */
+}
+
/*
* check the following:
* - In main mode with pre-shared key, only address type can be used.
View
5 kame/kame/racoon/ipsec_doi.h
@@ -1,4 +1,4 @@
-/* $KAME: ipsec_doi.h,v 1.31 2000/10/19 03:23:35 sakane Exp $ */
+/* $KAME: ipsec_doi.h,v 1.32 2001/04/06 14:23:48 sakane Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -182,6 +182,7 @@ extern int ipsecdoi_selectph2proposal __P((struct ph2handle *));
extern int ipsecdoi_checkph2proposal __P((struct ph2handle *));
extern struct prop_pair **get_proppair __P((vchar_t *, int));
+extern vchar_t *get_sabyproppair __P((struct prop_pair *, struct ph1handle *));
extern int ipsecdoi_updatespi __P((struct ph2handle *iph2));
extern vchar_t *get_sabysaprop __P((struct saprop *, vchar_t *));
extern int ipsecdoi_checkid1 __P((struct ph1handle *));
@@ -199,9 +200,11 @@ extern int ipsecdoi_transportmode __P((struct ph2handle *));
extern int ipsecdoi_get_defaultlifetime __P((void));
extern int ipsecdoi_checkalgtypes __P((int, int, int, int));
extern int ipproto2doi __P((int));
+extern int doi2ipproto __P((int));
extern int ipsecdoi_t2satrns __P((struct isakmp_pl_t *,
struct saprop *, struct saproto *, struct satrns *));
extern int ipsecdoi_authalg2trnsid __P((int));
extern int idtype2doi __P((int));
extern int doi2idtype __P((int));
+
View
100 kame/kame/racoon/isakmp_quick.c
@@ -1,4 +1,4 @@
-/* $KAME: isakmp_quick.c,v 1.77 2001/04/04 04:58:15 sakane Exp $ */
+/* $KAME: isakmp_quick.c,v 1.78 2001/04/06 14:23:48 sakane Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -1014,24 +1014,40 @@ quick_r1recv(iph2, msg0)
}
/* get sainfo */
- if (get_sainfo_r(iph2) != 0) {
+ error = get_sainfo_r(iph2);
+ if (error) {
plog(LLV_ERROR, LOCATION, NULL,
"failed to get sainfo.\n");
- error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
goto end;
}
/* check the existence of ID payload and create responder's proposal */
- if (get_proposal_r(iph2) < 0) {
+ error = get_proposal_r(iph2);
+ switch (error) {
+ case 0:
+ /* select single proposal or reject it. */
+ if (ipsecdoi_selectph2proposal(iph2) < 0) {
+ error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
+ goto end;
+ }
+ break;
+ case -2:
+ /*
+ * generate a policy from peer's proposal.
+ * if there is no suitable policy in SPD and
+ */
+ error = set_proposal_from_proposal(iph2);
+ if (error) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "failed to generate saprop "
+ "from client's proposal.\n");
+
+ return ISAKMP_INTERNAL_ERROR;
+ }
+ break;
+ default:
plog(LLV_ERROR, LOCATION, NULL,
"failed to get proposal for responder.\n");
- error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
- goto end;
- }
-
- /* select single proposal or reject it. */
- if (ipsecdoi_selectph2proposal(iph2) < 0) {
- error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
goto end;
}
@@ -1553,6 +1569,44 @@ quick_r3prep(iph2, msg0)
}
plog(LLV_DEBUG, LOCATION, NULL, "pfkey add sent.\n");
+ /*
+ * set policies into SPD if the policy is generated
+ * from peer's policy.
+ */
+ if (iph2->spidx_gen) {
+
+ struct policyindex *spidx;
+ struct sockaddr_storage addr;
+ u_int8_t pref;
+
+ /* make inbound policy */
+ if (pk_sendspdadd2(iph2) < 0) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "pfkey spdadd2(inbound) failed.\n");
+ goto end;
+ }
+ plog(LLV_DEBUG, LOCATION, NULL,
+ "pfkey spdadd2(inbound) sent.\n");
+
+ /* make outbound policy */
+ spidx = (struct policyindex *)iph2->spidx_gen;
+ spidx->dir = IPSEC_DIR_OUTBOUND;
+ addr = spidx->src;
+ spidx->src = spidx->dst;
+ spidx->dst = addr;
+ pref = spidx->prefs;
+ spidx->prefs = spidx->prefd;
+ spidx->prefd = pref;
+
+ if (pk_sendspdadd2(iph2) < 0) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "pfkey spdadd2(outbound) failed.\n");
+ goto end;
+ }
+ plog(LLV_DEBUG, LOCATION, NULL,
+ "pfkey spdadd2(outbound) sent.\n");
+ }
+
error = 0;
end:
@@ -1728,7 +1782,7 @@ get_proposal_r(iph2)
struct policyindex spidx;
struct secpolicy *sp_in, *sp_out;
int idi2type = 0; /* switch whether copy IDs into id[src,dst]. */
- int error;
+ int error = ISAKMP_INTERNAL_ERROR;
/* check the existence of ID payload */
if ((iph2->id_p != NULL && iph2->id == NULL)
@@ -1750,7 +1804,6 @@ get_proposal_r(iph2)
#define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type
/* make a spidx; a key to search SPD */
- /* get inbound policy */
spidx.dir = IPSEC_DIR_INBOUND;
spidx.ul_proto = 0;
@@ -1888,10 +1941,27 @@ get_proposal_r(iph2)
saddr2str((struct sockaddr *)&spidx.dst),
spidx.prefd, spidx.ul_proto);
+ /* clear spidx, just make sure */
+ if (iph2->spidx_gen) {
+ racoon_free(iph2->spidx_gen);
+ iph2->spidx_gen = NULL;
+ }
+
+ /* get inbound policy */
sp_in = getsp_r(&spidx);
if (sp_in == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "no policy found: %s\n", spidx2str(&spidx));
+ if (iph2->ph1->rmconf->gen_policy) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "no policy found: %s\n", spidx2str(&spidx));
+ iph2->spidx_gen = racoon_malloc(sizeof(spidx));
+ if (!iph2->spidx_gen) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "buffer allocation failed.\n");
+ return ISAKMP_INTERNAL_ERROR;
+ }
+ memcpy(iph2->spidx_gen, &spidx, sizeof(spidx));
+ return -2; /* special value */
+ }
return ISAKMP_INTERNAL_ERROR;
}
View
106 kame/kame/racoon/pfkey.c
@@ -1,4 +1,4 @@
-/* $KAME: pfkey.c,v 1.108 2001/04/03 15:51:56 thorpej Exp $ */
+/* $KAME: pfkey.c,v 1.109 2001/04/06 14:23:48 sakane Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -1724,6 +1724,110 @@ pk_recvspdupdate(mhp)
return 0;
}
+/*
+ * this function has to be used by responder side.
+ */
+int
+pk_sendspdadd2(iph2)
+ struct ph2handle *iph2;
+{
+ struct policyindex *spidx;
+ struct saproto *pr;
+ u_int64_t ltime, vtime;
+ struct sadb_x_policy *xpl;
+ struct sadb_x_ipsecrequest *xisr;
+ u_int satype, mode;
+ caddr_t policy = NULL, p;
+ int policylen;
+
+ spidx = (struct policyindex *)iph2->spidx_gen;
+
+ ltime = iph2->approval->lifetime;
+ vtime = 0;
+
+ /* get policy buffer size */
+ policylen = sizeof(struct sadb_x_policy);
+ for (pr = iph2->approval->head; pr; pr = pr->next) {
+ policylen += PFKEY_ALIGN8(sizeof(*xisr)
+ + iph2->src->sa_len
+ + iph2->dst->sa_len);
+ }
+
+ /* make policy structure */
+ policy = racoon_malloc(policylen);
+ if (!policy) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "buffer allocation failed.\n");
+ return -1;
+ }
+
+ xpl = (struct sadb_x_policy *)policy;
+ xpl->sadb_x_policy_len = PFKEY_UNIT64(policylen);
+ xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
+ xpl->sadb_x_policy_type = IPSEC_POLICY_IPSEC;
+ xpl->sadb_x_policy_dir = spidx->dir; /* always inbound */
+ xpl->sadb_x_policy_id = 0;
+ xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);
+
+ for (pr = iph2->approval->head; pr; pr = pr->next) {
+
+ satype = doi2ipproto(pr->proto_id);
+ if (satype == ~0) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "invalid proto_id %d\n", pr->proto_id);
+ goto end;
+ }
+ mode = ipsecdoi2pfkey_mode(pr->encmode);
+ if (mode == ~0) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "invalid encmode %d\n", pr->encmode);
+ goto end;
+ }
+
+ /*
+ * the policy level cannot be unique because the policy
+ * is defined later than SA, so req_id cannot be bound to SA.
+ */
+ xisr->sadb_x_ipsecrequest_proto = satype;
+ xisr->sadb_x_ipsecrequest_mode = mode;
+ xisr->sadb_x_ipsecrequest_level = IPSEC_LEVEL_REQUIRE;
+ xisr->sadb_x_ipsecrequest_reqid = 0;
+ p = (caddr_t)(xisr + 1);
+
+ memcpy(p, iph2->src, iph2->src->sa_len);
+ p += iph2->src->sa_len;
+
+ memcpy(p, iph2->dst, iph2->dst->sa_len);
+ p += iph2->dst->sa_len;
+
+ xisr->sadb_x_ipsecrequest_len = PFKEY_ALIGN8(sizeof(*xisr)
+ + iph2->src->sa_len
+ + iph2->dst->sa_len);
+ }
+
+ if (pfkey_send_spdadd2(
+ lcconf->sock_pfkey,
+ (struct sockaddr *)&spidx->src,
+ spidx->prefs,
+ (struct sockaddr *)&spidx->dst,
+ spidx->prefd,
+ spidx->ul_proto,
+ ltime, vtime,
+ policy, policylen, 0) < 0) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "libipsec failed send spdadd2 (%s)\n",
+ ipsec_strerror());
+ goto end;
+ }
+ plog(LLV_DEBUG, LOCATION, NULL, "call pfkey_send_spdadd2\n");
+
+end:
+ if (policy)
+ racoon_free(policy);
+
+ return 0;
+}
+
static int
pk_recvspdadd(mhp)
caddr_t *mhp;
View
3  kame/kame/racoon/pfkey.h
@@ -1,4 +1,4 @@
-/* $KAME: pfkey.h,v 1.16 2001/03/05 18:37:07 thorpej Exp $ */
+/* $KAME: pfkey.h,v 1.17 2001/04/06 14:23:48 sakane Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -51,6 +51,7 @@ extern int pk_sendgetspi __P((struct ph2handle *));
extern int pk_sendupdate __P((struct ph2handle *));
extern int pk_sendadd __P((struct ph2handle *));
extern int pk_sendeacquire __P((struct ph2handle *));
+extern int pk_sendspdadd2 __P((struct ph2handle *));
extern void pfkey_timeover_stub __P((void *));
extern void pfkey_timeover __P((struct ph2handle *));
View
59 kame/kame/racoon/proposal.c
@@ -1,4 +1,4 @@
-/* $KAME: proposal.c,v 1.30 2001/04/03 15:51:56 thorpej Exp $ */
+/* $KAME: proposal.c,v 1.31 2001/04/06 14:23:48 sakane Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -1010,3 +1010,60 @@ set_proposal_from_policy(iph2, sp_in, sp_out)
err:
return -1;
}
+
+/*
+ * generate a policy from peer's proposal.
+ * this function unconditionally choices first proposal in SA payload
+ * passed by peer.
+ */
+int
+set_proposal_from_proposal(iph2)
+ struct ph2handle *iph2;
+{
+ struct prop_pair **pair;
+ struct saprop *pp;
+ struct saproto *pr;
+ int error = -1;
+ int i;
+
+ /* get proposal pair */
+ pair = get_proppair(iph2->sa, IPSECDOI_TYPE_PH2);
+ if (pair == NULL)
+ goto end;
+
+ /* choice the first proposal */
+ for (i = 0; i < MAXPROPPAIRLEN; i++) {
+ if (pair[i] != NULL)
+ break;
+ }
+
+ if (i == MAXPROPPAIRLEN)
+ goto end;
+
+ pp = aproppair2saprop(pair[i]);
+ if (!pp)
+ goto end;
+
+ /* reverse SPI */
+ for (pr = pp->head; pr; pr = pr->next) {
+ pr->spi_p = pr->spi; /* copy peer's SPI */
+ pr->spi = 0; /* initialize */
+ }
+
+ plog(LLV_DEBUG, LOCATION, NULL, "choice a proposal from peer's:\n");
+ printsaprop0(LLV_DEBUG, pp);
+
+ iph2->approval = pp;
+
+ /* make a SA to be replayed. */
+ /* SPI must be updated later. */
+ iph2->sa_ret = get_sabyproppair(pair[i], iph2->ph1);
+ if (iph2->sa_ret == NULL)
+ goto end;
+
+ error = 0;
+
+end:
+ free_proppair(pair);
+ return error;
+}
View
3  kame/kame/racoon/proposal.h
@@ -1,4 +1,4 @@
-/* $KAME: proposal.h,v 1.14 2001/02/21 05:19:11 sakane Exp $ */
+/* $KAME: proposal.h,v 1.15 2001/04/06 14:23:48 sakane Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -201,3 +201,4 @@ extern void print_proppair0 __P((int, struct prop_pair *, int));
extern void print_proppair __P((int, struct prop_pair *));
extern int set_proposal_from_policy __P((struct ph2handle *,
struct secpolicy *, struct secpolicy *));
+extern int set_proposal_from_proposal __P((struct ph2handle *));
View
13 kame/kame/racoon/racoon.conf.5
@@ -1,4 +1,4 @@
-.\" $KAME: racoon.conf.5,v 1.77 2001/02/22 02:40:06 itojun Exp $
+.\" $KAME: racoon.conf.5,v 1.78 2001/04/06 14:23:48 sakane Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
.\" All rights reserved.
@@ -374,6 +374,17 @@ If this value is set on then both values of ID payloads in phase 2 exchange
are always used as the addresses of end-point of IPsec-SAs.
The default is off.
.\"
+.It Ic generate_policy (on \(ba off) ;
+This directive is for the responder.
+If the responder does not have any policy in SPD during phase 2 negotiation,
+and the directive is set on, then racoon will choice the first proposal in the
+SA payload from the initiator, and generate policy entries from the proposal.
+It is useful to negotiate with the client which is allocated IP address
+dynamically and the communication needs IPSec tunnel mode.
+This directive is ignored in the initiator case.
+The default value is
+.Ic off .
+.\"
.It Ic nonce_size Ar number ;
define the byte size of nonce value.
Racoon can send any value although
View
4 kame/kame/racoon/remoteconf.h
@@ -1,4 +1,4 @@
-/* $KAME: remoteconf.h,v 1.22 2001/03/27 02:39:57 thorpej Exp $ */
+/* $KAME: remoteconf.h,v 1.23 2001/04/06 14:23:48 sakane Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -63,7 +63,7 @@ struct remoteconf {
int nonce_size; /* the number of bytes of nonce */
int keepalive; /* XXX may not use */
int support_mip6; /* support mip6 */
- int gen_policy; /* XXX not yet, for anonymous client. */
+ int gen_policy; /* generate policy if no policy found */
int ini_contact; /* initial contact */
int pcheck_level; /* level of propocl checking */
Please sign in to comment.
Something went wrong with that request. Please try again.