From: Matthew Dillon Date: Mon, 6 Sep 2010 18:04:35 +0000 (-0700) Subject: userland - Port TCP-MD5 (RFC 2385) implementation. X-Git-Url: https://gitweb.dragonflybsd.org/~lentferj/dragonfly.git/commitdiff_plain/51006084f1e4cea9c0c14548e15322bb9e5cb5a7 userland - Port TCP-MD5 (RFC 2385) implementation. Userland portion of he TCP_SIGNATURE port. Submitted-by: David =?iso-8859-1?Q?B=C9RARD?= Ported-from: FreeBSD --- diff --git a/lib/libipsec/ipsec_dump_policy.c b/lib/libipsec/ipsec_dump_policy.c index 0d1460c059..05a7b44424 100644 --- a/lib/libipsec/ipsec_dump_policy.c +++ b/lib/libipsec/ipsec_dump_policy.c @@ -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; diff --git a/lib/libipsec/pfkey.c b/lib/libipsec/pfkey.c index 75b1cb1679..ee881bc363 100644 --- a/lib/libipsec/pfkey.c +++ b/lib/libipsec/pfkey.c @@ -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: diff --git a/lib/libipsec/pfkey_dump.c b/lib/libipsec/pfkey_dump.c index ba4d2bba5a..2b4901c97c 100644 --- a/lib/libipsec/pfkey_dump.c +++ b/lib/libipsec/pfkey_dump.c @@ -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 diff --git a/lib/libipsec/policy_token.l b/lib/libipsec/policy_token.l index f51607d923..77ff00b493 100644 --- a/lib/libipsec/policy_token.l +++ b/lib/libipsec/policy_token.l @@ -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); } diff --git a/share/man/man4/tcp.4 b/share/man/man4/tcp.4 index 1c140065fc..1b06358286 100644 --- a/share/man/man4/tcp.4 +++ b/share/man/man4/tcp.4 @@ -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 diff --git a/usr.sbin/setkey/parse.y b/usr.sbin/setkey/parse.y index f2c11490f8..5609f3737d 100644 --- a/usr.sbin/setkey/parse.y +++ b/usr.sbin/setkey/parse.y @@ -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 PORT PREFIX EXTENSION MODE -%type UP_PROTO PR_ESP PR_AH PR_IPCOMP +%type UP_PROTO PR_ESP PR_AH PR_IPCOMP PR_TCP %type ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP %type DECSTRING %type 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()); diff --git a/usr.sbin/setkey/setkey.8 b/usr.sbin/setkey/setkey.8 index 84d575d2e6..b72db79157 100644 --- a/usr.sbin/setkey/setkey.8 +++ b/usr.sbin/setkey/setkey.8 @@ -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 diff --git a/usr.sbin/setkey/token.l b/usr.sbin/setkey/token.l index a0f7865746..afb8300416 100644 --- a/usr.sbin/setkey/token.l +++ b/usr.sbin/setkey/token.l @@ -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 */