From 5447f70f9c9cc8420e59bff223b8de1c3d2ab20f Mon Sep 17 00:00:00 2001 From: blymn Date: Sat, 23 Nov 2002 10:52:49 +0000 Subject: [PATCH] Renamed verified exec fingerprint loader. --- sbin/veriexecctl/Makefile | 14 +++ sbin/veriexecctl/veriexecctl.8 | 94 +++++++++++++++++ sbin/veriexecctl/veriexecctl.c | 62 +++++++++++ sbin/veriexecctl/veriexecctl_conf.l | 52 ++++++++++ sbin/veriexecctl/veriexecctl_parse.y | 148 +++++++++++++++++++++++++++ 5 files changed, 370 insertions(+) create mode 100644 sbin/veriexecctl/Makefile create mode 100644 sbin/veriexecctl/veriexecctl.8 create mode 100644 sbin/veriexecctl/veriexecctl.c create mode 100644 sbin/veriexecctl/veriexecctl_conf.l create mode 100644 sbin/veriexecctl/veriexecctl_parse.y diff --git a/sbin/veriexecctl/Makefile b/sbin/veriexecctl/Makefile new file mode 100644 index 000000000000..3b1ec190e4ca --- /dev/null +++ b/sbin/veriexecctl/Makefile @@ -0,0 +1,14 @@ +# $NetBSD: Makefile,v 1.1 2002/11/23 10:52:49 blymn Exp $ + +PROG= veriexecctl +MAN= veriexecctl.8 +SRCS= veriexecctl_parse.y veriexecctl_conf.l veriexecctl.c + +YHEADER= 1 +CPPFLAGS+= -I. +DPADD+= ${LIBL} +LDADD+= -ll + +LDSTATIC= -static + +.include diff --git a/sbin/veriexecctl/veriexecctl.8 b/sbin/veriexecctl/veriexecctl.8 new file mode 100644 index 000000000000..6011a595fa8c --- /dev/null +++ b/sbin/veriexecctl/veriexecctl.8 @@ -0,0 +1,94 @@ +.\" $NetBSD: veriexecctl.8,v 1.1 2002/11/23 10:52:49 blymn Exp $ +.\" +.\" Copyright (c) 1999 +.\" Brett Lymn - blymn@baea.com.au, brett_lymn@yahoo.com.au +.\" +.\" This code is donated to The NetBSD Foundation by the author. +.\" +.\" 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. The name of the Author may not be used to endorse or promote +.\" products derived from this software without specific prior written +.\" permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. +.\" +.\" $Id: veriexecctl.8,v 1.1 2002/11/23 10:52:49 blymn Exp $ +.\" +.Dd October 29, 2002 +.Dt VERIEXECCTL 8 +.Os +.Sh NAME +.Nm veriexecctl +.Nd load verified exec fingerprints +.Sh SYNOPSIS +.Nm +.Ar fingerprints +.Sh DESCRIPTION +The +.Nm +command loads the in-kernel fingerprint table from the fingerprints +given in the +.Ar fingerprints +file. +Once loaded the kernel can then validate executed programs +or files against the loaded fingerprints and report when fingerprints +do not match. +.Pp +The +.Ar fingerprints +file contains lines of fields (separated by one or more whitespace +characters) of the form: +.Dl path fingerprint type options +Where path is the full path to the executable and fingerprint is a +hexadecimal representation of the fingerprint for the executable. +Type is the type of fingerprint used, currently this may be either +md5 or sha1. +Other fingerprints may be available depending on kernel support. +Options are the associated options for the executable. +Currently there are two valid options: +.Bl -tag -width INDIRECT -compact +.It Pa INDIRECT +If this option is set then the executable cannot be invoked directly, it +can only be used as an interpreter in shell scripts. +.It Pa FILE +Indicates that the fingerprint is associated with a file, not an +executable. +Files have their fingerprints verified during +.Xr open 2 +and are automatically made read only. +.El +There must be only one executable/fingerprint pair per line. +Comments are indicated by the first character of a line being a +.Sq \&# +character. +.Sh FILES +.Bl -tag -width /dev/verifiedexec -compact +.It Pa /dev/verifiedexec +verified executable device node +.El +.Sh HISTORY +.Nm +first appeared in +.Nx 1.7 . +.Sh NOTES +.Nm +requires the kernel to have been configured with the +.Dv VERIFIED_EXEC +option and the verifiedexec pseudo-device. diff --git a/sbin/veriexecctl/veriexecctl.c b/sbin/veriexecctl/veriexecctl.c new file mode 100644 index 000000000000..404778c0b2f0 --- /dev/null +++ b/sbin/veriexecctl/veriexecctl.c @@ -0,0 +1,62 @@ +/* $NetBSD: veriexecctl.c,v 1.1 2002/11/23 10:52:49 blymn Exp $ */ + +/*- + * Copyright (c) 1998-1999 Brett Lymn + * (blymn@baea.com.au, brett_lymn@yahoo.com.au) + * All rights reserved. + * + * This code has been donated to The NetBSD Foundation by the Author. + * + * 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. The name of the author may not be used to endorse or promote products + * derived from this software withough specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 +#include + +/* globals */ +int fd; +extern FILE *yyin; +int yyparse(void); + +int +main(int argc, char *argv[]) +{ + if (argv[1] == NULL) { + fprintf(stderr, "Usage: verifiedexec_load signature_file\n"); + exit(1); + } + + fd = open("/dev/veriexec", O_WRONLY, 0); + if (fd < 0) { + fprintf(stderr, "Dev open failed\n"); + exit(1); + } + + if ((yyin = fopen(argv[1], "r")) == NULL) { + fprintf(stderr, "Input file open failed\n"); + exit(1); + } + + yyparse(); + exit(0); +} diff --git a/sbin/veriexecctl/veriexecctl_conf.l b/sbin/veriexecctl/veriexecctl_conf.l new file mode 100644 index 000000000000..b8df9058de67 --- /dev/null +++ b/sbin/veriexecctl/veriexecctl_conf.l @@ -0,0 +1,52 @@ +%{ +/* + * Configuration file lexer for Verified exec + * + * + */ + +#include +#include +#include "veriexecctl_parse.h" + +int lineno = 1; + +void yyerror(const char *message); +void warning(const char *message); +int yylex __P((void)); + +%} + +%% + +path { return PATH; } +string { return STRING; } +eol { return EOL; } + +\/[^ ]+ { + yylval.string = strdup(yytext); + return PATH; +} + +[0-9a-zA-Z]+ { + yylval.string = strdup(yytext); + return STRING; +} + +\n { + lineno++; /* for error reporting */ + return EOL; +} + +[ \t\r] ; /* eat white ones */ + +#.* ; /* comment */ + +. yyerror("invalid character"); + +%% + +void yyerror(const char *string) +{ + fprintf(stderr, "%d: %s at %s\n", lineno, string, yytext); +} diff --git a/sbin/veriexecctl/veriexecctl_parse.y b/sbin/veriexecctl/veriexecctl_parse.y new file mode 100644 index 000000000000..4cce0d3a24f0 --- /dev/null +++ b/sbin/veriexecctl/veriexecctl_parse.y @@ -0,0 +1,148 @@ +%{ +/* + * Parser for verified exec fingerprint file. + * + * $NetBSD: veriexecctl_parse.y,v 1.1 2002/11/23 10:52:49 blymn Exp $ + * + */ + +#include +#include +#include +#include +#include + +/* yacc internal function */ +static int yygrowstack __P((void)); +int yylex __P((void)); +void yyerror __P((const char *)); + +/* function prototypes */ +static int +convert(char *fp, unsigned int count, unsigned char *out); + +/* ioctl parameter struct */ +struct verified_exec_params params; +extern int fd; +extern int lineno; + +%} + +%union { + char *string; + int intval; +} + +%token EOL +%token PATH +%token STRING + +%% + +statement: /* empty */ + | statement path type fingerprint flags eol + ; + +path: PATH +{ + strncpy(params.file, $1, 255); + params.type = VERIEXEC_DIRECT; +}; + +type: STRING +{ + if (strcasecmp($1, "md5") == 0) { + params.fp_type = FINGERPRINT_TYPE_MD5; + } else if (strcasecmp($1, "sha1") == 0) { + params.fp_type = FINGERPRINT_TYPE_SHA1; + } else { + fprintf(stderr, "%s %s at %d, %s\n", + "verifiedexec_load: bad fingerprint type", $1, lineno, + "assuming MD5"); + params.fp_type = FINGERPRINT_TYPE_MD5; + } +}; + + +fingerprint: STRING +{ + unsigned int count; + + if (params.fp_type == FINGERPRINT_TYPE_SHA1) + count = SHA1_FINGERPRINTLEN; + else + count = MD5_FINGERPRINTLEN; + + if (convert($1, count, params.fingerprint) < 0) { + fprintf(stderr, + "verifiedexec_load: bad fingerprint at line %d\n", + lineno); + } +}; + +flags: /* empty */ + | flag_spec flags; + +flag_spec: STRING +{ + params.type = VERIEXEC_DIRECT; + if (strcasecmp($1, "indirect") == 0) { + params.type = VERIEXEC_INDIRECT; + } else if (strcasecmp($1, "file") == 0) { + params.type = VERIEXEC_FILE; + } +}; + +eol: EOL +{ + do_ioctl(); +}; + +%% + +/* + * Convert: takes the hexadecimal string pointed to by fp and converts + * it to a "count" byte binary number which is stored in the array pointed to + * by out. Returns -1 if the conversion fails. + */ +static int +convert(char *fp, unsigned int count, unsigned char *out) +{ + int i, value, error = 0; + + for (i = 0; i < count; i++) { + if ((fp[2*i] >= '0') && (fp[2*i] <= '9')) { + value = 16 * (fp[2*i] - '0'); + } else if ((fp[2*i] >= 'a') && (fp[2*i] <= 'f')) { + value = 16 * (10 + fp[2*i] - 'a'); + } else { + error = -1; + break; + } + + if ((fp[2*i + 1] >= '0') && (fp[2*i + 1] <= '9')) { + value += fp[2*i + 1] - '0'; + } else if ((fp[2*i + 1] >= 'a') && (fp[2*i + 1] <= 'f')) { + value += fp[2*i + 1] - 'a' + 10; + } else { + error = -1; + break; + } + + out[i] = value; + } + + return error; +} + +/* + * Perform the load of the fingerprint. Assumes that the fingerprint + * pseudo-device is opened and the file handle is in fd. + */ +static void +do_ioctl(void) +{ + if (ioctl(fd, VERIEXECLOAD, ¶ms) < 0) + fprintf(stderr, "Ioctl failed with error `%s' on file %s\n", + strerror(errno), params.file); +}