Subject: port-sparc64/26486: TCP_SIGNATURE not seeming to be sent
To: None <gnats-bugs@gnats.NetBSD.org>
From: Peter Eisch <peter@boku.net>
List: netbsd-bugs
Date: 07/30/2004 23:47:57
>Number:         26486
>Category:       port-sparc64
>Synopsis:       though requested, No MD5 digest in tcp packets
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    port-sparc64-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Jul 31 04:49:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Charlie Root
>Release:        NetBSD 2.0G
>Organization:
    
>Environment:
System: NetBSD mons 2.0G NetBSD 2.0G (PETER-FW) #0: Thu Jul 29 18:44:45 CDT
2004 
peter@gvlsite:/builds/current/sparc64/obj/builds/current/src/sys/arch/sparc6
4/compile/PETER-FW sparc64
Architecture: sparc64
Machine: sparc64
>Description:
while running zebra-0.94 (I'll try to remember the patch below)
and
running on a kernel that's no more than GENERIC (64-bit) with these options
as well:

options               IPSEC           # IP security
options               IPSEC_ESP       # IP security (encryption part; define
w/IPSEC)
options               IPSEC_DEBUG     # debug for IP security
options               TCP_SIGNATURE   # TCP MD5 Signatures, for BGP routing
sessions
options               GATEWAY

Sources for the kernel were from 29 July.  On the remote side, the cisco
isn't complaining about a bad MD5 key, it's more astute to note:

Jul 30 23:39:27.340: %TCP-6-BADAUTH: No MD5 digest from sparc64:63943 to
cisco:179


>How-To-Repeat:

--- zebra-0.94.orig/bgpd/bgp_network.c  2003-11-04 12:00:42.000000000 -0600
+++ zebra-0.94/bgpd/bgp_network.c       2004-07-29 19:44:55.000000000 -0500
@@ -33,6 +33,11 @@ Software Foundation, Inc., 59 Temple Pla
 #include "bgpd/bgp_attr.h"
 #include "bgpd/bgp_debug.h"
 #include "bgpd/bgp_network.h"
+  
+#ifndef TCP_SIG_SPI_BASE
+#define TCP_SIG_SPI_BASE 1000 /* XXX this will go away */
+#endif
+
 

 /* Accept bgp connection. */
 static int
@@ -137,6 +142,15 @@ bgp_bind (struct peer *peer)
       return ret;
     }
 #endif /* SO_BINDTODEVICE */
+
+#ifdef TCP_MD5SIG
+  if (CHECK_FLAG (peer->flags, PEER_FLAG_TCP_SIGNATURE))
+    sockopt_tcp_signature (peer->su.sa.sa_family, peer->fd,
+      TCP_SIG_SPI_BASE + peer->port);
+  else
+    sockopt_tcp_signature (peer->su.sa.sa_family, peer->fd, 0);
+#endif /* TCP_MD5SIG */
+
   return 0;
 }
 
@@ -233,6 +247,12 @@ bgp_connect (struct peer *peer)
     ifindex = if_nametoindex (peer->ifname);
 #endif /* HAVE_IPV6 */
 
+#ifdef TCP_MD5SIG
+  if (CHECK_FLAG (peer->flags, PEER_FLAG_TCP_SIGNATURE))
+    sockopt_tcp_signature (peer->su.sa.sa_family, peer->fd,
+      TCP_SIG_SPI_BASE + peer->port);
+#endif /* TCP_MD5SIG */
+
   if (BGP_DEBUG (events, EVENTS))
     plog_info (peer->log, "%s [Event] Connect start to %s fd %d",
               peer->host, peer->host, peer->fd);
--- zebra-0.94.orig/bgpd/bgp_vty.c      2003-11-04 12:00:42.000000000 -0600
+++ zebra-0.94/bgpd/bgp_vty.c   2004-07-29 19:45:08.000000000 -0500
@@ -1353,6 +1353,45 @@ ALIAS (no_neighbor_local_as,
        "AS number used as local AS\n"
        "Do not prepend local-as to updates from ebgp peers\n");
 

+#ifdef TCP_MD5SIG
+DEFUN (neighbor_password,
+       neighbor_password_cmd,
+       NEIGHBOR_CMD2 "password WORD",
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Specify a password for TCPMD5 authentication with this peer\n")
+{
+  struct peer *peer;
+  int ret;
+
+  peer = peer_and_group_lookup_vty (vty, argv[0]);
+  if (! peer)
+    return CMD_WARNING;
+
+  ret = peer_password_set (peer, argv[1]);
+  return bgp_vty_return (vty, ret);
+}
+
+DEFUN (no_neighbor_password,
+       no_neighbor_password_cmd,
+       NO_NEIGHBOR_CMD2 "password",
+       NO_STR
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Disable TCPMD5 authentication with this peer\n")
+{
+  struct peer *peer;
+  int ret;
+
+  peer = peer_and_group_lookup_vty (vty, argv[0]);
+  if (! peer)
+    return CMD_WARNING;
+
+  ret = peer_password_unset (peer);
+  return bgp_vty_return (vty, ret);
+}
+#endif /* TCP_MD5SIG */
+

 DEFUN (neighbor_activate,
        neighbor_activate_cmd,
        NEIGHBOR_CMD2 "activate",
@@ -7866,6 +7905,10 @@ bgp_vty_init ()
   install_element (BGP_NODE, &no_neighbor_local_as_val_cmd);
   install_element (BGP_NODE, &no_neighbor_local_as_val2_cmd);
 
+  /* "neighbor password" commands. */
+  install_element (BGP_NODE, &neighbor_password_cmd);
+  install_element (BGP_NODE, &no_neighbor_password_cmd);
+
   /* "neighbor activate" commands. */
   install_element (BGP_NODE, &neighbor_activate_cmd);
   install_element (BGP_IPV4_NODE, &neighbor_activate_cmd);
--- zebra-0.94.orig/bgpd/bgpd.c 2003-11-04 12:00:42.000000000 -0600
+++ zebra-0.94/bgpd/bgpd.c      2004-07-29 19:45:38.000000000 -0500
@@ -59,6 +59,9 @@ Software Foundation, Inc., 59 Temple Pla
 #ifdef HAVE_SNMP
 #include "bgpd/bgp_snmp.h"
 #endif /* HAVE_SNMP */
+#ifndef TCP_SIG_SPI_BASE
+#define TCP_SIG_SPI_BASE 1000 /* XXX this will go away */
+#endif
 

 /* BGP process wide configuration.  */
 static struct bgp_master bgp_master;
@@ -3177,6 +3180,55 @@ peer_local_as_unset (struct peer *peer)
   return 0;
 }
 

+#ifdef TCP_MD5SIG
+/* Set password for authenticating with the peer. */
+int
+peer_password_set (struct peer *peer, char *password)
+{
+  struct bgp *bgp = peer->bgp;
+  int len;
+
+  len = strlen(password);
+
+  if ((len < PEER_PASSWORD_MINLEN) || (len > PEER_PASSWORD_MAXLEN))
+    return BGP_ERR_INVALID_VALUE;
+
+  memcpy(peer->password, password, len);
+
+  /*
+   * XXX Need to do PF_KEY operation here to add an SA entry,
+   * and add an SP entry for this peer's packet flows also.
+   */
+
+  SET_FLAG (peer->flags, PEER_FLAG_TCP_SIGNATURE);
+
+  if (peer->fd >= 0)
+    sockopt_tcp_signature (peer->su.sa.sa_family, peer->fd,
TCP_SIG_SPI_BASE +
+      peer->port);
+
+  return 0;
+}
+
+int
+peer_password_unset (struct peer *peer)
+{
+  struct bgp *bgp = peer->bgp;
+
+  UNSET_FLAG (peer->flags, PEER_FLAG_TCP_SIGNATURE);
+  /* Paranoia. */
+  memset(peer->password, 0, sizeof(peer->password));
+
+  if (peer->fd >= 0)
+    sockopt_tcp_signature (peer->su.sa.sa_family, peer->fd, 0);
+
+  /*
+   * XXX Need to do PF_KEY operation here to remove the SA and SP.
+   */
+
+  return 0;
+}
+#endif /* TCP_MD5SIG */
+

 /* Set distribute list to the peer. */
 int
 peer_distribute_set (struct peer *peer, afi_t afi, safi_t safi, int direct,
@@ -4161,6 +4213,13 @@ bgp_config_write_peer (struct vty *vty,
        vty_out (vty, " neighbor %s description %s%s", addr, peer->desc,
                 VTY_NEWLINE);
 
+#ifdef TCP_MD5SIG
+      /* tcp-md5 session password. XXX the password should be obfuscated */
+      if (CHECK_FLAG (peer->flags, PEER_FLAG_TCP_SIGNATURE))
+       vty_out (vty, " neighbor %s password %s%s", addr, peer->password,
+                VTY_NEWLINE);
+#endif /* TCP_MD5SIG */
+
       /* Shutdown. */
       if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN))
         if (! peer_group_active (peer) ||
--- zebra-0.94.orig/bgpd/bgpd.h 2003-11-04 12:00:42.000000000 -0600
+++ zebra-0.94/bgpd/bgpd.h      2004-07-29 19:45:45.000000000 -0500
@@ -312,6 +312,9 @@ struct peer
 #define PEER_FLAG_DYNAMIC_CAPABILITY        (1 << 6) /* dynamic capability
*/
 #define PEER_FLAG_ENFORCE_MULTIHOP          (1 << 7) /* enforce-multihop */
 #define PEER_FLAG_LOCAL_AS_NO_PREPEND       (1 << 8) /* local-as no-prepend
*/
+#ifdef TCP_MD5SIG /* XXX should move to AF_INET/SFI_UNICAST below */
+#define PEER_FLAG_TCP_SIGNATURE             (1 << 9) /* use TCP-MD5 digest
*/
+#endif /* TCP_MD5SIG */
 
   /* Per AF configuration flags. */
   u_int32_t af_flags[AFI_MAX][SAFI_MAX];
@@ -469,6 +472,13 @@ struct peer
 #define PEER_RMAP_TYPE_REDISTRIBUTE   (1 << 3) /* redistribute route-map */
 #define PEER_RMAP_TYPE_DEFAULT        (1 << 4) /* default-originate
route-map */
 #define PEER_RMAP_TYPE_NOSET          (1 << 5) /* not allow to set commands
*/
+
+#ifdef TCP_MD5SIG
+  /* TCP-MD5 Password Support -- bms */
+#define PEER_PASSWORD_MINLEN           1
+#define PEER_PASSWORD_MAXLEN           80      /* width of password field
*/
+ char password[PEER_PASSWORD_MAXLEN];
+#endif /* TCP_MD5SIG */
 };
 
 /* This structure's member directly points incoming packet data
@@ -846,6 +856,11 @@ int peer_allowas_in_unset (struct peer *
 int peer_local_as_set (struct peer *, as_t, int);
 int peer_local_as_unset (struct peer *);
 
+#ifdef TCP_MD5SIG
+int peer_password_set (struct peer *, char *);
+int peer_password_unset (struct peer *);
+#endif /* TCP_MD5SIG */
+
 int peer_prefix_list_set (struct peer *, afi_t, safi_t, int, char *);
 int peer_prefix_list_unset (struct peer *, afi_t, safi_t, int);
 
--- zebra-0.94.orig/lib/sockopt.c       2003-11-04 12:00:42.000000000 -0600
+++ zebra-0.94/lib/sockopt.c    2004-07-29 19:46:12.000000000 -0500
@@ -197,3 +197,29 @@ setsockopt_multicast_ipv4(int sock,
 #endif /* #if OS_TYPE */
 
 }
+
+int
+sockopt_tcp_signature (int family, int sock, int enable)
+{
+  int ret;
+
+#ifdef TCP_MD5SIG
+  if (family == AF_INET)
+    {
+      ret = setsockopt (sock, IPPROTO_TCP, TCP_MD5SIG,
+                        (void *) &enable, sizeof (int));
+      if (ret < 0)
+        {
+          zlog (NULL, LOG_WARNING, "can't set sockopt TCP_MD5SIG %d to
socket %d", enable, sock);
+          return -1;
+        }
+      return 0;
+    }
+#endif /* TCP_MD5SIG */
+
+  /* fallthrough */
+
+  zlog (NULL, LOG_WARNING, "can't set sockopt TCP_MD5SIG on socket %d with
family %d",
+                 sock, family);
+  return -1;
+}
--- zebra-0.94.orig/lib/sockopt.h       2003-11-04 12:00:42.000000000 -0600
+++ zebra-0.94/lib/sockopt.h    2004-07-29 19:46:16.000000000 -0500
@@ -37,5 +37,8 @@ int setsockopt_multicast_ipv4(int sock,
                             unsigned int mcast_addr,
                             unsigned int ifindex);
 
+#ifdef TCP_MD5SIG
+int sockopt_tcp_signature(int family, int sock, int enable);
+#endif /* TCP_MD5SIG */
 
 #endif /*_ZEBRA_SOCKOPT_H */


>Fix:
    


>Release-Note:
>Audit-Trail:
>Unformatted: