NetBSD/sbin/setkey/token.l
jonathan 887b782b0b Initial commit of a port of the FreeBSD implementation of RFC 2385
(MD5 signatures for TCP, as used with BGP).  Credit for original
FreeBSD code goes to Bruce M. Simpson, with FreeBSD sponsorship
credited to sentex.net.  Shortening of the setsockopt() name
attributed to Vincent Jardin.

This commit is a minimal, working version of the FreeBSD code, as
MFC'ed to FreeBSD-4. It has received minimal testing with a ttcp
modified to set the TCP-MD5 option; BMS's additions to tcpdump-current
(tcpdump -M) confirm that the MD5 signatures are correct.  Committed
as-is for further testing between a NetBSD BGP speaker (e.g., quagga)
and industry-standard BGP speakers (e.g., Cisco, Juniper).


NOTE: This version has two potential flaws. First, I do see any code
that verifies recieved TCP-MD5 signatures.  Second, the TCP-MD5
options are internally padded and assumed to be 32-bit aligned. A more
space-efficient scheme is to pack all TCP options densely (and
possibly unaligned) into the TCP header ; then do one final padding to
a 4-byte boundary.  Pre-existing comments note that accounting for
TCP-option space when we add SACK is yet to be done. For now, I'm
punting on that; we can solve it properly, in a way that will handle
SACK blocks, as a separate exercise.

In case a pullup to NetBSD-2 is requested, this adds sys/netipsec/xform_tcp.c
,and modifies:

sys/net/pfkeyv2.h,v 1.15
sys/netinet/files.netinet,v 1.5
sys/netinet/ip.h,v 1.25
sys/netinet/tcp.h,v 1.15
sys/netinet/tcp_input.c,v 1.200
sys/netinet/tcp_output.c,v 1.109
sys/netinet/tcp_subr.c,v 1.165
sys/netinet/tcp_usrreq.c,v 1.89
sys/netinet/tcp_var.h,v 1.109
sys/netipsec/files.netipsec,v 1.3
sys/netipsec/ipsec.c,v 1.11
sys/netipsec/ipsec.h,v 1.7
sys/netipsec/key.c,v 1.11
share/man/man4/tcp.4,v 1.16
lib/libipsec/pfkey.c,v 1.20
lib/libipsec/pfkey_dump.c,v 1.17
lib/libipsec/policy_token.l,v 1.8
sbin/setkey/parse.y,v 1.14
sbin/setkey/setkey.8,v 1.27
sbin/setkey/token.l,v 1.15

Note that the preceding two revisions to tcp.4 will be
required to cleanly apply this diff.
2004-04-25 22:25:03 +00:00

283 lines
8.3 KiB
Plaintext

/* $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/usr.sbin/setkey/token.l,v 1.2.2.4 2004/02/14 22:28:29 bms Exp $ */
/* $KAME: token.l,v 1.43 2003/07/25 09:35:28 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
%{
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <net/route.h>
#include <net/pfkeyv2.h>
#include <netkey/keydb.h>
#include <netkey/key_debug.h>
#include <netinet/in.h>
#include <netinet6/ipsec.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
#include "vchar.h"
#ifdef __NetBSD__
#include "parse.h"
#else
#include "y.tab.h"
#endif
int lineno = 1;
extern u_char m_buf[BUFSIZ];
extern u_int m_len;
extern int f_debug;
int yylex __P((void));
void yyfatal __P((const char *s));
void yyerror __P((const char *s));
extern void parse_init __P((void));
int parse __P((FILE **));
int yyparse __P((void));
%}
/* common section */
nl \n
ws [ \t]+
digit [0-9]
letter [0-9A-Za-z]
hexdigit [0-9A-Fa-f]
dot \.
hyphen \-
slash \/
blcl \[
elcl \]
semi \;
comment \#.*
quotedstring \"[^"]*\"
decstring {digit}+
hexstring 0[xX]{hexdigit}+
ipaddress [a-fA-F0-9:]([a-fA-F0-9:\.]*|[a-fA-F0-9:\.]*%[a-zA-Z0-9]*)
ipaddrmask {slash}{digit}{1,3}
name {letter}(({letter}|{digit}|{hyphen})*({letter}|{digit}))*
hostname {name}(({dot}{name})+{dot}?)?
%s S_PL S_AUTHALG S_ENCALG
%%
add { return(ADD); }
delete { return(DELETE); }
deleteall { return(DELETEALL); }
get { return(GET); }
flush { return(FLUSH); }
dump { return(DUMP); }
/* for management SPD */
spdadd { return(SPDADD); }
spddelete { return(SPDDELETE); }
spddump { return(SPDDUMP); }
spdflush { return(SPDFLUSH); }
tagged { return(TAGGED); }
{hyphen}P { BEGIN S_PL; return(F_POLICY); }
<S_PL>[a-zA-Z0-9:\.\-_/ \n\t][a-zA-Z0-9:\.%\-_/ \n\t]* {
yymore();
/* count up for nl */
{
char *p;
for (p = yytext; *p != 0; p++)
if (*p == '\n')
lineno++;
}
yylval.val.len = strlen(yytext);
yylval.val.buf = strdup(yytext);
if (!yylval.val.buf)
yyfatal("insufficient memory");
return(PL_REQUESTS);
}
<S_PL>{semi} { BEGIN INITIAL; return(EOT); }
/* address resolution flags */
{hyphen}[n46][n46]* {
yylval.val.len = strlen(yytext);
yylval.val.buf = strdup(yytext);
if (!yylval.val.buf)
yyfatal("insufficient memory");
return(F_AIFLAGS);
}
/* security protocols */
ah { yylval.num = 0; return(PR_AH); }
esp { yylval.num = 0; return(PR_ESP); }
ah-old { yylval.num = 1; return(PR_AH); }
esp-old { yylval.num = 1; return(PR_ESP); }
ipcomp { yylval.num = 0; return(PR_IPCOMP); }
tcp { yylval.num = 0; return(PR_TCP); }
/* authentication alogorithm */
{hyphen}A { BEGIN S_AUTHALG; return(F_AUTH); }
<S_AUTHALG>hmac-md5 { yylval.num = SADB_AALG_MD5HMAC; BEGIN INITIAL; return(ALG_AUTH); }
<S_AUTHALG>hmac-sha1 { yylval.num = SADB_AALG_SHA1HMAC; BEGIN INITIAL; return(ALG_AUTH); }
<S_AUTHALG>keyed-md5 { yylval.num = SADB_X_AALG_MD5; BEGIN INITIAL; return(ALG_AUTH); }
<S_AUTHALG>keyed-sha1 { yylval.num = SADB_X_AALG_SHA; BEGIN INITIAL; return(ALG_AUTH); }
<S_AUTHALG>hmac-sha2-256 { yylval.num = SADB_X_AALG_SHA2_256; BEGIN INITIAL; return(ALG_AUTH); }
<S_AUTHALG>hmac-sha2-384 { yylval.num = SADB_X_AALG_SHA2_384; BEGIN INITIAL; return(ALG_AUTH); }
<S_AUTHALG>hmac-sha2-512 { yylval.num = SADB_X_AALG_SHA2_512; BEGIN INITIAL; return(ALG_AUTH); }
<S_AUTHALG>hmac-ripemd160 { yylval.num = SADB_X_AALG_RIPEMD160HMAC; BEGIN INITIAL; return(ALG_AUTH); }
<S_AUTHALG>aes-xcbc-mac { yylval.num = SADB_X_AALG_AES_XCBC_MAC; BEGIN INITIAL; return(ALG_AUTH); }
<S_AUTHALG>tcp-md5 { yylval.num = SADB_X_AALG_TCP_MD5; BEGIN INITIAL; return(ALG_AUTH); }
<S_AUTHALG>null { yylval.num = SADB_X_AALG_NULL; BEGIN INITIAL; return(ALG_AUTH_NOKEY); }
/* encryption alogorithm */
{hyphen}E { BEGIN S_ENCALG; return(F_ENC); }
<S_ENCALG>des-cbc { yylval.num = SADB_EALG_DESCBC; BEGIN INITIAL; return(ALG_ENC); }
<S_ENCALG>3des-cbc { yylval.num = SADB_EALG_3DESCBC; BEGIN INITIAL; return(ALG_ENC); }
<S_ENCALG>null { yylval.num = SADB_EALG_NULL; BEGIN INITIAL; return(ALG_ENC_NOKEY); }
<S_ENCALG>simple { yylval.num = SADB_EALG_NULL; BEGIN INITIAL; return(ALG_ENC_OLD); }
<S_ENCALG>blowfish-cbc { yylval.num = SADB_X_EALG_BLOWFISHCBC; BEGIN INITIAL; return(ALG_ENC); }
<S_ENCALG>cast128-cbc { yylval.num = SADB_X_EALG_CAST128CBC; BEGIN INITIAL; return(ALG_ENC); }
<S_ENCALG>des-deriv { yylval.num = SADB_EALG_DESCBC; BEGIN INITIAL; return(ALG_ENC_DESDERIV); }
<S_ENCALG>des-32iv { yylval.num = SADB_EALG_DESCBC; BEGIN INITIAL; return(ALG_ENC_DES32IV); }
<S_ENCALG>rijndael-cbc { yylval.num = SADB_X_EALG_RIJNDAELCBC; BEGIN INITIAL; return(ALG_ENC); }
<S_ENCALG>aes-ctr { yylval.num = SADB_X_EALG_AESCTR; BEGIN INITIAL; return(ALG_ENC); }
/* compression algorithms */
{hyphen}C { return(F_COMP); }
oui { yylval.num = SADB_X_CALG_OUI; return(ALG_COMP); }
deflate { yylval.num = SADB_X_CALG_DEFLATE; return(ALG_COMP); }
lzs { yylval.num = SADB_X_CALG_LZS; return(ALG_COMP); }
{hyphen}R { return(F_RAWCPI); }
/* extension */
{hyphen}m { return(F_MODE); }
transport { yylval.num = IPSEC_MODE_TRANSPORT; return(MODE); }
tunnel { yylval.num = IPSEC_MODE_TUNNEL; return(MODE); }
{hyphen}u { return(F_REQID); }
{hyphen}f { return(F_EXT); }
random-pad { yylval.num = SADB_X_EXT_PRAND; return(EXTENSION); }
seq-pad { yylval.num = SADB_X_EXT_PSEQ; return(EXTENSION); }
zero-pad { yylval.num = SADB_X_EXT_PZERO; return(EXTENSION); }
nocyclic-seq { return(NOCYCLICSEQ); }
{hyphen}r { return(F_REPLAY); }
{hyphen}lh { return(F_LIFETIME_HARD); }
{hyphen}ls { return(F_LIFETIME_SOFT); }
/* ... */
any { return(ANY); }
{ws} { }
{nl} { lineno++; }
{comment}
{semi} { return(EOT); }
/* for address parameters: /prefix, [port] */
{slash} { return SLASH; }
{blcl} { return BLCL; }
{elcl} { return ELCL; }
/* parameter */
{decstring} {
char *bp;
yylval.ulnum = strtoul(yytext, &bp, 10);
return(DECSTRING);
}
{hexstring} {
yylval.val.buf = strdup(yytext + 2);
if (!yylval.val.buf)
yyfatal("insufficient memory");
yylval.val.len = strlen(yylval.val.buf);
return(HEXSTRING);
}
{quotedstring} {
char *p = yytext;
while (*++p != '"') ;
*p = 0;
yytext++;
yylval.val.len = yyleng - 2;
yylval.val.buf = strdup(yytext);
if (!yylval.val.buf)
yyfatal("insufficient memory");
return(QUOTEDSTRING);
}
[A-Za-z0-9:][A-Za-z0-9:%\.-]* {
yylval.val.len = yyleng;
yylval.val.buf = strdup(yytext);
if (!yylval.val.buf)
yyfatal("insufficient memory");
return(STRING);
}
. {
yyfatal("Syntax error");
/*NOTREACHED*/
}
%%
void
yyfatal(s)
const char *s;
{
yyerror(s);
exit(1);
}
void
yyerror(s)
const char *s;
{
printf("line %d: %s at [%s]\n", lineno, s, yytext);
}
int
parse(fp)
FILE **fp;
{
yyin = *fp;
parse_init();
if (yyparse()) {
printf("parse failed, line %d.\n", lineno);
return(-1);
}
return(0);
}