userland - Port TCP-MD5 (RFC 2385) implementation.
authorMatthew Dillon <dillon@apollo.backplane.com>
Mon, 6 Sep 2010 18:04:35 +0000 (11:04 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Mon, 6 Sep 2010 18:04:35 +0000 (11:04 -0700)
Userland portion of he TCP_SIGNATURE port.

Submitted-by: David =?iso-8859-1?Q?B=C9RARD?= <david@nfrance.com>
Ported-from: FreeBSD

lib/libipsec/ipsec_dump_policy.c
lib/libipsec/pfkey.c
lib/libipsec/pfkey_dump.c
lib/libipsec/policy_token.l
share/man/man4/tcp.4
usr.sbin/setkey/parse.y
usr.sbin/setkey/setkey.8
usr.sbin/setkey/token.l

index 0d1460c..05a7b44 100644 (file)
@@ -191,6 +191,9 @@ ipsec_dump_ipsecrequest(char *buf, size_t len,
        case IPPROTO_IPCOMP:
                proto = "ipcomp";
                break;
+       case IPPROTO_TCP:
+               proto = "tcp";
+               break;
        default:
                __ipsec_errcode = EIPSEC_INVAL_PROTO;
                return NULL;
index 75b1cb1..ee881bc 100644 (file)
@@ -79,12 +79,13 @@ static caddr_t pfkey_setsadbxsa2 (caddr_t, caddr_t, u_int32_t, u_int32_t);
 /*
  * make and search supported algorithm structure.
  */
-static struct sadb_supported *ipsec_supported[] = { NULL, NULL, NULL, };
+static struct sadb_supported *ipsec_supported[] = { NULL, NULL, NULL, NULL};
 
 static int supported_map[] = {
        SADB_SATYPE_AH,
        SADB_SATYPE_ESP,
        SADB_X_SATYPE_IPCOMP,
+       SADB_X_SATYPE_TCPSIGNATURE,
 };
 
 static int
@@ -1166,6 +1167,16 @@ pfkey_send_x1(so, type, satype, mode, src, dst, spi, reqid, wsize,
                        return -1;
                }
                break;
+       case SADB_X_SATYPE_TCPSIGNATURE:
+               if (e_type != SADB_EALG_NONE) {
+                       __ipsec_errcode = EIPSEC_INVAL_ALGS;
+                       return -1;
+               }
+               if (a_type != SADB_X_AALG_TCP_MD5) {
+                       __ipsec_errcode = EIPSEC_INVAL_ALGS;
+                       return -1;
+               }
+               break;
        default:
                __ipsec_errcode = EIPSEC_INVAL_SATYPE;
                return -1;
@@ -1376,6 +1387,7 @@ pfkey_send_x3(so, type, satype)
                case SADB_SATYPE_AH:
                case SADB_SATYPE_ESP:
                case SADB_X_SATYPE_IPCOMP:
+               case SADB_X_SATYPE_TCPSIGNATURE:
                        break;
                default:
                        __ipsec_errcode = EIPSEC_INVAL_SATYPE;
@@ -1835,6 +1847,7 @@ pfkey_check(mhp)
        case SADB_SATYPE_ESP:
        case SADB_SATYPE_AH:
        case SADB_X_SATYPE_IPCOMP:
+       case SADB_X_SATYPE_TCPSIGNATURE:
                switch (msg->sadb_msg_type) {
                case SADB_X_SPDADD:
                case SADB_X_SPDDELETE:
index ba4d2bb..2b4901c 100644 (file)
@@ -124,6 +124,8 @@ static char *str_satype[] = {
        "ripv2",
        "mip",
        "ipcomp",
+       "policy",
+       "tcp",
 };
 
 static char *str_mode[] = {
@@ -162,6 +164,7 @@ static struct val2str str_alg_auth[] = {
        { SADB_X_AALG_MD5, "md5", },
        { SADB_X_AALG_SHA, "sha", },
        { SADB_X_AALG_NULL, "null", },
+       { SADB_X_AALG_TCP_MD5, "tcp-md5", },
 #ifdef SADB_X_AALG_SHA2_256
        { SADB_X_AALG_SHA2_256, "hmac-sha2-256", },
 #endif
index f51607d..77ff00b 100644 (file)
@@ -104,6 +104,7 @@ entrust             { yylval.num = IPSEC_POLICY_ENTRUST; return(ACTION); }
 esp            { yylval.num = IPPROTO_ESP; return(PROTOCOL); }
 ah             { yylval.num = IPPROTO_AH; return(PROTOCOL); }
 ipcomp         { yylval.num = IPPROTO_IPCOMP; return(PROTOCOL); }
+tcp            { yylval.num = IPPROTO_TCP; return(PROTOCOL); }
 
 transport      { yylval.num = IPSEC_MODE_TRANSPORT; return(MODE); }
 tunnel         { yylval.num = IPSEC_MODE_TUNNEL; return(MODE); }
index 1c14006..1b06358 100644 (file)
@@ -156,6 +156,31 @@ option is set to a non-zero value,
 .Tn TCP
 will delay sending any data at all until either the socket is closed,
 or the internal send buffer is filled.
+.It Dv TCP_SIGNATURE_ENABLE
+This option enables the use of MD5 digests (also known as TCP-MD5)
+on writes to the specified socket.
+In the current release, only outgoing traffic is digested;
+digests on incoming traffic are not verified.
+The current default behavior for the system is to respond to a system
+advertising this option with TCP-MD5; this may change.
+.Pp
+One common use for this in a DragonFlyBSD router deployment is to enable
+based routers to interwork with Cisco equipment at peering points.
+Support for this feature conforms to RFC 2385.
+Only IPv4 (AF_INET) sessions are supported.
+.Pp
+In order for this option to function correctly, it is necessary for the
+administrator to add a tcp-md5 key entry to the system's security
+associations database (SADB) using the
+.Xr setkey 8
+utility.
+This entry must have an SPI of 0x1000 and can therefore only be specified
+on a per-host basis at this time.
+.Pp
+If an SADB entry cannot be found for the destination, the outgoing traffic
+will have an invalid digest option prepended, and the following error message
+will be visible on the system console:
+.Em "tcpsignature_compute: SADB lookup failed for %d.%d.%d.%d" .
 .El
 .Pp
 The option level for the
@@ -381,6 +406,7 @@ address.
 .Xr blackhole 4 ,
 .Xr inet 4 ,
 .Xr intro 4 ,
+.Xr setkey 8,
 .Xr ip 4
 .Rs
 .%A V. Jacobson
@@ -389,6 +415,11 @@ address.
 .%T "TCP Extensions for High Performance"
 .%O RFC 1323
 .Re
+.Rs
+.%A "A. Heffernan"
+.%T "Protection of BGP Sessions via the TCP MD5 Signature Option"
+.%O "RFC 2385"
+.Re
 .Sh HISTORY
 The
 .Nm
index f2c1149..5609f37 100644 (file)
@@ -102,7 +102,7 @@ extern void yyerror(const char *);
 %token EOT
 %token ADD GET DELETE DELETEALL FLUSH DUMP
 %token ADDRESS PREFIX PORT PORTANY
-%token UP_PROTO PR_ESP PR_AH PR_IPCOMP
+%token UP_PROTO PR_ESP PR_AH PR_IPCOMP PR_TCP
 %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI
 %token F_MODE MODE F_REQID
 %token F_EXT EXTENSION NOCYCLICSEQ
@@ -114,7 +114,7 @@ extern void yyerror(const char *);
 %token F_POLICY PL_REQUESTS
 
 %type <num> PORT PREFIX EXTENSION MODE
-%type <num> UP_PROTO PR_ESP PR_AH PR_IPCOMP
+%type <num> UP_PROTO PR_ESP PR_AH PR_IPCOMP PR_TCP
 %type <num> ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP
 %type <num> DECSTRING
 %type <val> ADDRESS PL_REQUESTS
@@ -230,6 +230,10 @@ protocol_spec
                {
                        p_satype = SADB_X_SATYPE_IPCOMP;
                }
+       |       PR_TCP
+               {
+                       p_satype = SADB_X_SATYPE_TCPSIGNATURE;
+               }
        ;
        
 spi
@@ -349,7 +353,11 @@ auth_key
                        p_key_auth_len = $1.len;
                        p_key_auth = pp_key;
 
-                       if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
+                       if (p_alg_auth == SADB_X_AALG_TCP_MD5) {
+                               if ((p_key_auth_len < 1) || (p_key_auth_len >
+                                       80))
+                                       return -1;
+                       } else if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
                                        p_alg_auth,
                                        PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
                                yyerror(ipsec_strerror());
index 84d575d..b72db79 100644 (file)
@@ -220,6 +220,8 @@ AH based on rfc2402
 AH based on rfc1826
 .It Li ipcomp
 IPCOMP
+.It Li tcp
+TCP-MD5 based on rfc2385
 .El
 .\"
 .Pp
@@ -230,6 +232,8 @@ You cannot use the set of SPI values in the range 0 through 255.
 (with
 .Li 0x
 attached).
+TCP-MD5 associations must use 0x1000 and therefore only have per-host
+granularity at this time.
 .\"
 .Pp
 .It Ar extensions
@@ -547,6 +551,7 @@ hmac-sha2-384       384             ah: 96bit ICV (no document)
                384             ah-old: 128bit ICV (no document)
 hmac-sha2-512  512             ah: 96bit ICV (no document)
                512             ah-old: 128bit ICV (no document)
+tcp-md5                8 to 640        tcp: rfc2385
 .Ed
 .Pp
 Followings are the list of encryption algorithms that can be used as
@@ -602,6 +607,8 @@ dump esp ;
 spdadd 10.0.11.41/32[21] 10.0.11.33/32[any] any
                -P out ipsec esp/tunnel/192.168.0.1-192.168.1.2/require ;
 
+add 10.1.10.34 10.1.10.36 tcp 0x1000 -A tcp-md5 "TCP-MD5 BGP secret" ;
+
 .Ed
 .\"
 .Sh DIAGNOSTICS
index a0f7865..afb8300 100644 (file)
@@ -163,6 +163,7 @@ esp         { PREPROC; yylval.num = 0; return(PR_ESP); }
 ah-old         { PREPROC; yylval.num = 1; return(PR_AH); }
 esp-old                { PREPROC; yylval.num = 1; return(PR_ESP); }
 ipcomp         { PREPROC; yylval.num = 0; return(PR_IPCOMP); }
+tcp            { PREPROC; yylval.num = 0; return(PR_TCP); }
 
        /* authentication alogorithm */
 {hyphen}A      { PREPROC; return(F_AUTH); }
@@ -173,6 +174,7 @@ keyed-sha1  { PREPROC; yylval.num = SADB_X_AALG_SHA; return(ALG_AUTH); }
 hmac-sha2-256  { PREPROC; yylval.num = SADB_X_AALG_SHA2_256; return(ALG_AUTH); }
 hmac-sha2-384  { PREPROC; yylval.num = SADB_X_AALG_SHA2_384; return(ALG_AUTH); }
 hmac-sha2-512  { PREPROC; yylval.num = SADB_X_AALG_SHA2_512; return(ALG_AUTH); }
+tcp-md5        { PREPROC; yylval.num = SADB_X_AALG_TCP_MD5; return(ALG_AUTH); }
 null           { PREPROC; yylval.num = SADB_X_AALG_NULL; return(ALG_AUTH); }
 
        /* encryption alogorithm */