veriexecctl_parse.y revision 1.7
11.1Sblymn%{
21.7Schristos/*	$NetBSD: veriexecctl_parse.y,v 1.7 2005/04/21 12:45:12 christos Exp $	*/
31.5Sblymn
41.5Sblymn/*-
51.5Sblymn * Copyright 2005 Elad Efrat <elad@bsd.org.il>
61.5Sblymn * Copyright 2005 Brett Lymn <blymn@netbsd.org>
71.5Sblymn *
81.5Sblymn * All rights reserved.
91.5Sblymn *
101.5Sblymn * This code has been donated to The NetBSD Foundation by the Author.
111.5Sblymn *
121.5Sblymn * Redistribution and use in source and binary forms, with or without
131.5Sblymn * modification, are permitted provided that the following conditions
141.5Sblymn * are met:
151.5Sblymn * 1. Redistributions of source code must retain the above copyright
161.5Sblymn *    notice, this list of conditions and the following disclaimer.
171.5Sblymn * 2. The name of the author may not be used to endorse or promote products
181.5Sblymn *    derived from this software withough specific prior written permission
191.5Sblymn *
201.5Sblymn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
211.5Sblymn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
221.5Sblymn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
231.5Sblymn * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
241.5Sblymn * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
251.5Sblymn * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
261.5Sblymn * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
271.5Sblymn * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
281.5Sblymn * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
291.5Sblymn * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
301.1Sblymn *
311.1Sblymn *
321.1Sblymn */
331.1Sblymn
341.5Sblymn#include <sys/param.h>
351.5Sblymn#include <sys/ioctl.h>
361.5Sblymn#include <sys/statvfs.h>
371.5Sblymn#include <sys/mount.h>
381.5Sblymn
391.5Sblymn#include <sys/verified_exec.h>
401.5Sblymn#include <ctype.h>
411.1Sblymn#include <stdio.h>
421.1Sblymn#include <string.h>
431.1Sblymn#include <errno.h>
441.5Sblymn#include <err.h>
451.5Sblymn
461.5Sblymn#include "veriexecctl.h"
471.1Sblymn
481.5Sblymnstruct veriexec_params params;
491.7Schristosstatic int convert(u_char *, u_char *);
501.1Sblymn
511.1Sblymn%}
521.1Sblymn
531.1Sblymn%union {
541.5Sblymn	char *string;
551.5Sblymn	int intval;
561.1Sblymn}
571.1Sblymn
581.1Sblymn%token <string> PATH
591.1Sblymn%token <string> STRING
601.5Sblymn%token EOL
611.1Sblymn
621.1Sblymn%%
631.1Sblymn
641.5Sblymnstatement	:	/* empty */
651.5Sblymn		|	statement path type fingerprint flags eol {
661.7Schristos	struct stat sb;
671.7Schristos	struct vexec_up *p;
681.5Sblymn
691.7Schristos	if (phase == 2) {
701.7Schristos		phase2_load();
711.7Schristos		goto phase_2_end;
721.7Schristos	}
731.7Schristos
741.7Schristos	if (stat(params.file, &sb) == -1) {
751.7Schristos		warnx("Line %lu: Can't stat `%s'",
761.7Schristos		    (unsigned long)line, params.file);
771.7Schristos		goto phase_2_end;
781.7Schristos	}
791.7Schristos
801.7Schristos	/* Only regular files */
811.7Schristos	if (!S_ISREG(sb.st_mode)) {
821.7Schristos		warnx("Line %lu: %s is not a regular file",
831.7Schristos		    (unsigned long)line, params.file);
841.7Schristos		goto phase_2_end;
851.7Schristos	}
861.7Schristos
871.7Schristos	if ((p = dev_lookup(sb.st_dev)) == NULL) {
881.7Schristos	    (p->vu_param.hash_size)++;
891.7Schristos	    goto phase_2_end;
901.7Schristos	}
911.7Schristos
921.7Schristos	if (verbose) {
931.7Schristos		struct statvfs sf;
941.7Schristos		if (statvfs(params.file, &sf) == -1)
951.7Schristos			err(1, "Cannot statvfs `%s'", params.file);
961.5Sblymn
971.7Schristos		(void)printf( " => Adding device ID %d. (%s)\n",
981.7Schristos		    sb.st_dev, sf.f_mntonname);
991.7Schristos	}
1001.7Schristos	dev_add(sb.st_dev);
1011.5Sblymnphase_2_end:
1021.7Schristos	(void)memset(&params, 0, sizeof(params));
1031.7Schristos}
1041.5Sblymn		|	statement eol
1051.5Sblymn		|	statement error eol {
1061.7Schristos	yyerrok;
1071.7Schristos}
1081.5Sblymn		;
1091.5Sblymn
1101.5Sblymnpath		:	PATH {
1111.7Schristos	(void)strlcpy(params.file, $1, MAXPATHLEN);
1121.7Schristos}
1131.5Sblymn		;
1141.5Sblymn
1151.5Sblymntype		:	STRING {
1161.7Schristos	if (phase != 1) {
1171.7Schristos		if (strlen($1) >= sizeof(params.fp_type)) {
1181.7Schristos			yyerror("Fingerprint type too long");
1191.7Schristos			YYERROR;
1201.7Schristos		}
1211.7Schristos
1221.7Schristos		(void)strlcpy(params.fp_type, $1, sizeof(params.fp_type));
1231.7Schristos	}
1241.7Schristos}
1251.5Sblymn		;
1261.1Sblymn
1271.1Sblymn
1281.5Sblymnfingerprint	:	STRING {
1291.7Schristos	if (phase != 1) {
1301.7Schristos		params.fingerprint = malloc(strlen($1) / 2);
1311.7Schristos		if (params.fingerprint == NULL)
1321.7Schristos			err(1, "Fingerprint mem alloc failed");
1331.5Sblymn
1341.7Schristos		if ((params.size = convert($1, params.fingerprint)) == -1) {
1351.7Schristos			free(params.fingerprint);
1361.7Schristos			yyerror("Bad fingerprint");
1371.7Schristos			YYERROR;
1381.7Schristos		}
1391.7Schristos	}
1401.5Sblymn
1411.7Schristos}
1421.7Schristos	    ;
1431.1Sblymn
1441.5Sblymnflags		:	/* empty */ {
1451.7Schristos	if (phase == 2)
1461.7Schristos		params.type = VERIEXEC_DIRECT;
1471.7Schristos}
1481.5Sblymn		|	flags flag_spec
1491.5Sblymn		;
1501.1Sblymn
1511.5Sblymnflag_spec	:	STRING {
1521.7Schristos	if (phase != 1) {
1531.7Schristos		if (strcasecmp($1, "direct") == 0)
1541.7Schristos			params.type = VERIEXEC_DIRECT;
1551.7Schristos		else if (strcasecmp($1, "indirect") == 0)
1561.7Schristos			params.type = VERIEXEC_INDIRECT;
1571.7Schristos#ifdef notdef
1581.7Schristos		else if (strcasecmp($1, "shell") == 0)
1591.7Schristos			params.vxp_type = VEXEC_SHELL;
1601.7Schristos#endif
1611.7Schristos		else if (strcasecmp($1, "file") == 0)
1621.7Schristos			params.type = VERIEXEC_FILE;
1631.7Schristos		else {
1641.7Schristos			yyerror("Bad option");
1651.7Schristos			YYERROR;
1661.7Schristos		}
1671.7Schristos	}
1681.1Sblymn
1691.7Schristos}
1701.5Sblymn		;
1711.1Sblymn
1721.5Sblymneol		:	EOL
1731.5Sblymn		;
1741.1Sblymn
1751.1Sblymn%%
1761.1Sblymn
1771.1Sblymn/*
1781.5Sblymn * Takes the hexadecimal string pointed to by "fp" and converts it to a
1791.5Sblymn * "count" byte binary number which is stored in the array pointed to
1801.5Sblymn * by "out".  Returns the number of bytes converted or -1 if the conversion
1811.5Sblymn * fails.
1821.1Sblymn */
1831.7Schristosstatic int
1841.7Schristosconvert(u_char *fp, u_char *out)
1851.7Schristos{
1861.7Schristos	size_t i, count;
1871.7Schristos	u_char value;
1881.5Sblymn
1891.5Sblymn	count = strlen(fp);
1901.5Sblymn
1911.7Schristos	/*
1921.7Schristos	 * if there are not an even number of hex digits then there is
1931.7Schristos	 * not an integral number of bytes in the fingerprint.
1941.7Schristos	 */
1951.5Sblymn	if ((count % 2) != 0)
1961.5Sblymn		return -1;
1971.5Sblymn
1981.5Sblymn	count /= 2;
1991.7Schristos
2001.7Schristos#define cvt(cv) \
2011.7Schristos	if (isdigit(cv)) \
2021.7Schristos		value += (cv) - '0'; \
2031.7Schristos	else if (isxdigit(cv)) \
2041.7Schristos		value += 10 + tolower(cv) - 'a'; \
2051.7Schristos	else \
2061.7Schristos		return -1
2071.5Sblymn
2081.5Sblymn	for (i = 0; i < count; i++) {
2091.7Schristos		value = 0;
2101.7Schristos		cvt(fp[2 * i]);
2111.7Schristos		value <<= 4;
2121.7Schristos		cvt(fp[2 * i + 1]);
2131.5Sblymn		out[i] = value;
2141.5Sblymn	}
2151.1Sblymn
2161.7Schristos	return count;
2171.1Sblymn}
218