Subject: kern/17459: racoon(8) SPD lookup hits wrong entries
To: None <>
From: None <>
List: netbsd-bugs
Date: 07/02/2002 18:18:58
>Number:         17459
>Category:       kern
>Synopsis:       racoon(8) SPD lookup hits wrong entries
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Jul 02 09:20:00 PDT 2002
>Originator:     Matthias Drochner
>Release:        NetBSD 1.6B
	KFA Juelich
System: NetBSD zelz26 1.6B NetBSD 1.6B (TEST) #23: Mon Jul 1 12:05:04 MEST 2002 drochner@zelz26:/home/drochner/netbsd/sys/arch/i386/compile/TEST i386
Architecture: i386
Machine: i386
	After I added two rules like these as first lines to /etc/ipsec.conf:

spdadd icmp -P out none;
spdadd icmp -P in none;

which are supposed to allow ICMP traffic pass through unencrypted, key
negotiations stopped working. On the ISAKMP responder side, racoon generated
the following debug messages:

INFO: isakmp.c:1046:isakmp_ph2begin_r(): respond new phase 2 negotiation:[0]<=>[0]
ERROR: isakmp_quick.c:2064:get_proposal_r(): policy found, but no IPsec required:[0][0] proto=any dir=out
ERROR: isakmp_quick.c:1071:quick_r1recv(): failed to get proposal for responder.
ERROR: isakmp.c:1060:isakmp_ph2begin_r(): failed to pre-process packet.

This is a "leaf-node tunnel" setup where and are the
tunnel endpoints and is an end node at the same time.
Authentication is done by x509 certificates.

	Add the "spdadd ... icmp ... none" entries mentioned above to the SPD
and see key negotiations fail.

	The problem seems to be that the call to getsp_r() in
isakmp_quick.c for the inbound policy returns the "icmp" policy
entry. The ul_proto member of spidx is set to IPSEC_ULPROTO_ANY
at this point which is treated as wildcard by getsp_r().
The following patch:

*** isakmp_quick.c.~1.4.~	Tue May 21 17:21:28 2002
--- isakmp_quick.c	Tue Jul  2 14:53:47 2002
*** 2011,2017 ****
--- 2011,2021 ----
  		spidx.ul_proto = IPSEC_ULPROTO_ANY;
  	/* get inbound policy */
+ #if 0
  	sp_in = getsp_r(&spidx);
+ #else
+ 	sp_in = getsp(&spidx);
+ #endif
  	if (sp_in == NULL) {
  		if (iph2->ph1->rmconf->gen_policy) {
*** 2045,2051 ****
--- 2049,2059 ----
  	spidx.prefs = spidx.prefd;
  	spidx.prefd = pref;
+ #if 0
  	sp_out = getsp_r(&spidx);
+ #else
+ 	sp_out = getsp(&spidx);
+ #endif
  	if (!sp_out) {
  			"no outbound policy found: %s\n",

fixes it for me.
(The second hunk is not strictly necessary.)

[begin of speculation section]

My patch requires that
-SPD entries are symmetrical for "in" and "out", and
-there is always an entry with "upper protocol" set to "any".

This is certainly not ideal, but the existing code is likely
to fail too if this is not given, at least look up different
SPD entries than the kernel, which leads to problems if
the "struct secpolicy" parts differ.

Imho the root of the problem is that racoon doesn't have
the same information like the kernel - the original
"upper proto" and "port" get lost in the "pfkey" layer.
See sys/netkey/key.c:key_acquire().