Bug 192774 - PF_KEY ACQUIRE missing port and protocol info
Summary: PF_KEY ACQUIRE missing port and protocol info
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 10.0-STABLE
Hardware: Any Any
: --- Affects Only Me
Assignee: Andrey V. Elsukov
URL:
Keywords: patch
Depends on:
Blocks:
 
Reported: 2014-08-18 04:08 UTC by john
Modified: 2018-04-29 10:00 UTC (History)
3 users (show)

See Also:


Attachments
patch for problem. (2.23 KB, text/plain)
2014-08-18 04:08 UTC, john
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description john 2014-08-18 04:08:20 UTC
Created attachment 145951 [details]
patch for problem.

Consider an IPSEC policy such as:

 spdadd 0.0.0.0/0 XXX.XXX.XXX.XXX/32[1701] udp -P out ipsec
   esp/transport//require;
 spdadd XXX.XXX.XXX.XXX/32[1701] 0.0.0.0/0 udp -P in ipsec
   esp/transport//require;

When triggered it sends a PF_KEY ACQUIRE message that causes ISAKMP 
negotiations to occur with the remote.  Unfortunately the key_acquire 
routine in sys/netipsec/key.c doesn't contain any code to propagate 
the port / protocol information as part of the ACQUIRE message ... as 
a result racoon sees an ACQUIRE message for all traffic to the remote
system and supplies that as the proposal which fails since the remote 
system is only willing to protect L2TP with IPSEC ... not all traffic.

Note that RFC 2367 3.1.6 SADB_ACQUIRE says:

  The address(SD) extensions MUST have the port fields
  filled in with the port numbers of the session requiring
  keys if appropriate.

With the supplied patch I'm able to successfully establish a L2TP protected
by IPSEC connection from FreeBSD 10-stable to a Cisco 3845 router.
Comment 1 commit-hook freebsd_committer 2015-07-06 12:40:47 UTC
A commit references this bug:

Author: ae
Date: Mon Jul  6 12:40:32 UTC 2015
New revision: 285204
URL: https://svnweb.freebsd.org/changeset/base/285204

Log:
  Fill the port and protocol information in the SADB_ACQUIRE message
  in case when security policy has it as required by RFC 2367.

  PR:		192774
  Differential Revision:	https://reviews.freebsd.org/D2972
  MFC after:	1 week

Changes:
  head/sys/netipsec/key.c
Comment 2 commit-hook freebsd_committer 2015-07-15 21:10:40 UTC
A commit references this bug:

Author: ae
Date: Wed Jul 15 21:09:39 UTC 2015
New revision: 285614
URL: https://svnweb.freebsd.org/changeset/base/285614

Log:
  MFC r285204:
    Fill the port and protocol information in the SADB_ACQUIRE message
    in case when security policy has it as required by RFC 2367.

    PR:		192774

  Approved by:	re (delphij)

Changes:
_U  stable/10/
  stable/10/sys/netipsec/key.c
Comment 3 Andrey V. Elsukov freebsd_committer 2015-07-15 21:11:07 UTC
Merged to stable/10. Thanks!
Comment 4 longwitz 2018-04-10 20:32:06 UTC
After updating on old FreeBSD V8 server to 10 Stable my L2TP/IPSEC connections were broken. The reason for this was the commit 285204 given in this bug report. Racoon tried to connect to the remote server on port 1701 instead of 500:
  initiate new phase 1 negotiation: 192.168.14.23[500]<=>192.168.14.3[1701]

The following patch for racoon solved this problem for me:

--- src/racoon/pfkey.c.orig     2012-08-23 13:10:45.000000000 +0200
+++ src/racoon/pfkey.c  2018-04-10 15:35:17.603722000 +0200
@@ -1931,11 +1931,13 @@
                delph2(iph2);
                return -1;
        }
+       set_port(iph2->dst, 0);
        iph2->src = dupsaddr(src);
        if (iph2->src == NULL) {
                delph2(iph2);
                return -1;
        }
+       set_port(iph2->src, 0);

        /* If sa_src and sa_dst have been set, this mean we have to
         * set iph2->sa_src and iph2->sa_dst to provide the addresses

I suggest this patch should go in the files directory of the port security/ipsec-tools.
Comment 5 john 2018-04-10 23:01:48 UTC
Regarding racoon here's the fix I supplied to ipsec-tools-devel@lists.sourceforge.net in 2014:

To: ipsec-tools-devel@lists.sourceforge.net
Subject: ipsec-tools-0.8.2 patch to properly set isakmp ph1 port

Currently copy_ph1addresses assumes that an initiation is indicated
by the port numbers in the ACQUIRE msg equaling zero.  In the case
of an policy such as:

 spdadd 0.0.0.0/0 XXX.XXX.XXX.XXX/32[1701] udp -P out ipsec
   esp/transport//require;
 spdadd XXX.XXX.XXX.XXX/32[1701] 0.0.0.0/0 udp -P in ipsec
   esp/transport//require;

(designed to provide IPSEC protection for L2TP) the ACQUIRE msg
contains port information causing racoon to attempt initiate
ISAKMP phase 1 with the remote on port 1701 instead of port 500.

The supplied patch adds an explict flag to copy_ph1addresses
which indicates if the addresses are being used to initiate ISAKMP.

With this patch I'm able to successfully establish a L2TP protected
by IPSEC connection from FreeBSD 10-stable to a Cisco 3845 router.

-- John
-----------------8<------------------------8<----------------------------
--- src/racoon/isakmp.c.ORIGINAL        2012-08-29 04:55:26.000000000 -0400
+++ src/racoon/isakmp.c 2014-08-16 22:27:10.336976657 -0400
@@ -1074,7 +1074,7 @@ isakmp_ph1begin_i(rmconf, remote, local)
        iph1->approval = NULL;

        /* XXX copy remote address */
-       if (copy_ph1addresses(iph1, rmconf, remote, local) < 0) {
+       if (copy_ph1addresses(iph1, rmconf, remote, local, TRUE) < 0) {
                delph1(iph1);
                return NULL;
        }
@@ -1188,7 +1188,7 @@ isakmp_ph1begin_r(msg, remote, local, et

        /* copy remote address; remote and local always contain
         * port numbers so rmconf is not needed */
-       if (copy_ph1addresses(iph1, NULL, remote, local) < 0) {
+       if (copy_ph1addresses(iph1, NULL, remote, local, FALSE) < 0) {
                delph1(iph1);
                return -1;
        }
@@ -2904,10 +2904,11 @@ isakmp_printpacket(msg, from, my, decode
 #endif /*HAVE_PRINT_ISAKMP_C*/

 int
-copy_ph1addresses(iph1, rmconf, remote, local)
+copy_ph1addresses(iph1, rmconf, remote, local, initiator)
        struct ph1handle *iph1;
        struct remoteconf *rmconf;
        struct sockaddr *remote, *local;
+       int initiator;
 {
        u_int16_t port;

@@ -2923,7 +2924,7 @@ copy_ph1addresses(iph1, rmconf, remote,
         * if remote has port # (in case of responder - from recvfrom(2))
         * respect content of "remote".
         */
-       if (extract_port(iph1->remote) == 0) {
+       if (initiator || extract_port(iph1->remote) == 0) {
                port = 0;
                if (rmconf != NULL)
                        port = extract_port(rmconf->remote);
@@ -2939,7 +2940,7 @@ copy_ph1addresses(iph1, rmconf, remote,
        if (iph1->local == NULL)
                return -1;

-       if (extract_port(iph1->local) == 0) {
+       if (initiator || extract_port(iph1->local) == 0) {
                port = myaddr_getsport(iph1->local);
                if (port == 0)
                        port = PORT_ISAKMP;
--- src/racoon/isakmp_inf.c.ORIGINAL    2013-04-12 05:53:52.000000000 -0400
+++ src/racoon/isakmp_inf.c     2014-08-16 22:29:35.793972202 -0400
@@ -724,7 +724,7 @@ isakmp_info_send_nx(isakmp, remote, loca
 #endif

        /* copy remote address */
-       if (copy_ph1addresses(iph1, NULL, remote, local) < 0)
+       if (copy_ph1addresses(iph1, NULL, remote, local, FALSE) < 0)
                goto end;

        tlen = sizeof(*n) + spisiz;
--- src/racoon/isakmp_var.h.ORIGINAL    2010-11-12 05:36:37.000000000 -0500
+++ src/racoon/isakmp_var.h     2014-08-16 22:25:55.863985365 -0400
@@ -128,7 +128,8 @@ extern void isakmp_printpacket __P((vcha
 #endif

 extern int copy_ph1addresses __P(( struct ph1handle *,
-       struct remoteconf *, struct sockaddr *, struct sockaddr *));
+       struct remoteconf *, struct sockaddr *, struct sockaddr *,
+       int initiator));
 extern void log_ph1established __P((const struct ph1handle *));

 extern void script_hook __P((struct ph1handle *, int));
-------------------------------------------------------------------------
|   Feith Systems  |   Voice: 1-215-646-8000  |  Email: john@feith.com  |
|    John Wehle    |     Fax: 1-215-540-5495  |                         |
-------------------------------------------------------------------------
Comment 6 commit-hook freebsd_committer 2018-04-29 10:00:33 UTC
A commit references this bug:

Author: eugen
Date: Sun Apr 29 10:00:02 UTC 2018
New revision: 468617
URL: https://svnweb.freebsd.org/changeset/ports/468617

Log:
  Fix phase 1 initiation in the racoon daemon after base system change r285204

  PR:		192774, 222065
  Submitted by:	Andreas Longwitz <longwitz@incore.de>
  Approved by:	VANHULLEBUS Yvan (maintainer, implicitly)

Changes:
  head/security/ipsec-tools/Makefile
  head/security/ipsec-tools/files/patch-isakmpinit