veriexecctl_parse.y revision 1.5
11.1Sblymn%{
21.5Sblymn/*	$NetBSD: veriexecctl_parse.y,v 1.5 2005/04/20 13:44:45 blymn 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.1Sblymn
501.1Sblymn%}
511.1Sblymn
521.1Sblymn%union {
531.5Sblymn	char *string;
541.5Sblymn	int intval;
551.1Sblymn}
561.1Sblymn
571.1Sblymn%token <string> PATH
581.1Sblymn%token <string> STRING
591.5Sblymn%token EOL
601.1Sblymn
611.1Sblymn%%
621.1Sblymn
631.5Sblymnstatement	:	/* empty */
641.5Sblymn		|	statement path type fingerprint flags eol {
651.5Sblymn				struct stat sb;
661.5Sblymn
671.5Sblymn				if (phase == 2) {
681.5Sblymn					phase2_load();
691.5Sblymn					goto phase_2_end;
701.5Sblymn				}
711.5Sblymn
721.5Sblymn				if (stat(params.file, &sb) == 0) {
731.5Sblymn					struct vexec_up *p;
741.5Sblymn
751.5Sblymn					/* Only regular files */
761.5Sblymn					if (!S_ISREG(sb.st_mode)) {
771.5Sblymn						(void) fprintf(stderr,
781.5Sblymn							       "Line %u: "
791.5Sblymn						    "%s is not a regular file.\n",
801.5Sblymn							       line,
811.5Sblymn							       params.file);
821.5Sblymn					}
831.5Sblymn
841.5Sblymn					if ((p = dev_lookup(sb.st_dev)) != NULL) {
851.5Sblymn						(p->vu_param.hash_size)++;
861.5Sblymn					} else {
871.5Sblymn						if (verbose) {
881.5Sblymn							struct statvfs sf;
891.5Sblymn
901.5Sblymn							statvfs(params.file,
911.5Sblymn							       &sf);
921.5Sblymn
931.5Sblymn							(void) printf(
941.5Sblymn							    " => Adding device"
951.5Sblymn							    " ID %d. (%s)\n",
961.5Sblymn							    sb.st_dev,
971.5Sblymn							    sf.f_mntonname);
981.5Sblymn						}
991.5Sblymn
1001.5Sblymn						dev_add(sb.st_dev);
1011.5Sblymn					}
1021.5Sblymn				} else {
1031.5Sblymn					(void) fprintf(stderr,
1041.5Sblymn						       "Line %u: Can't stat"
1051.5Sblymn						       " %s.\n",
1061.5Sblymn					    line, params.file);
1071.5Sblymn				}
1081.5Sblymn
1091.5Sblymnphase_2_end:
1101.5Sblymn				bzero(&params, sizeof(params));
1111.5Sblymn			}
1121.5Sblymn		|	statement eol
1131.5Sblymn		|	statement error eol {
1141.5Sblymn				yyerrok;
1151.5Sblymn			}
1161.5Sblymn		;
1171.5Sblymn
1181.5Sblymnpath		:	PATH {
1191.5Sblymn				strlcpy(params.file, $1, MAXPATHLEN);
1201.5Sblymn			}
1211.5Sblymn		;
1221.5Sblymn
1231.5Sblymntype		:	STRING {
1241.5Sblymn				if (phase != 1) {
1251.5Sblymn					if (strlen($1) >=
1261.5Sblymn					    sizeof(params.fp_type)) {
1271.5Sblymn						yyerror("Fingerprint type too "								"long");
1281.5Sblymn						YYERROR;
1291.5Sblymn					}
1301.5Sblymn
1311.5Sblymn					strlcpy(params.fp_type, $1,
1321.5Sblymn						sizeof(params.fp_type));
1331.5Sblymn				}
1341.5Sblymn			}
1351.5Sblymn		;
1361.1Sblymn
1371.1Sblymn
1381.5Sblymnfingerprint	:	STRING {
1391.5Sblymn				if (phase != 1) {
1401.5Sblymn					params.fingerprint = (char *)
1411.5Sblymn						malloc(strlen($1) / 2);
1421.5Sblymn					if (params.fingerprint == NULL) {
1431.5Sblymn						fprintf(stderr, "Fingerprint"
1441.5Sblymn							"mem alloc failed, "
1451.5Sblymn							"cannot continue.\n");
1461.5Sblymn						exit(1);
1471.5Sblymn					}
1481.5Sblymn
1491.5Sblymn					if ((params.size =
1501.5Sblymn					       convert($1, params.fingerprint))
1511.5Sblymn					     == -1) {
1521.5Sblymn						free(params.fingerprint);
1531.5Sblymn						yyerror("Bad fingerprint");
1541.5Sblymn						YYERROR;
1551.5Sblymn					}
1561.5Sblymn				}
1571.5Sblymn
1581.5Sblymn			}
1591.5Sblymn		;
1601.1Sblymn
1611.5Sblymnflags		:	/* empty */ {
1621.5Sblymn				if (phase == 2)
1631.5Sblymn					params.type = VERIEXEC_DIRECT;
1641.5Sblymn			}
1651.5Sblymn		|	flags flag_spec
1661.5Sblymn		;
1671.1Sblymn
1681.5Sblymnflag_spec	:	STRING {
1691.5Sblymn				if (phase != 1) {
1701.5Sblymn					if (strcasecmp($1, "direct") == 0) {
1711.5Sblymn						params.type = VERIEXEC_DIRECT;
1721.5Sblymn					} else if (strcasecmp($1, "indirect")
1731.5Sblymn						   == 0) {
1741.5Sblymn						params.type = VERIEXEC_INDIRECT;
1751.5Sblymn/*					} else if (strcasecmp($1, "shell") == 0) {
1761.5Sblymn						params.vxp_type = VEXEC_SHELL;*/
1771.5Sblymn					} else if (strcasecmp($1, "file")
1781.5Sblymn						   == 0) {
1791.5Sblymn						params.type = VERIEXEC_FILE;
1801.5Sblymn					} else {
1811.5Sblymn						yyerror("Bad option");
1821.5Sblymn						YYERROR;
1831.5Sblymn					}
1841.5Sblymn				}
1851.1Sblymn
1861.5Sblymn			}
1871.5Sblymn		;
1881.1Sblymn
1891.5Sblymneol		:	EOL
1901.5Sblymn		;
1911.1Sblymn
1921.1Sblymn%%
1931.1Sblymn
1941.1Sblymn/*
1951.5Sblymn * Takes the hexadecimal string pointed to by "fp" and converts it to a
1961.5Sblymn * "count" byte binary number which is stored in the array pointed to
1971.5Sblymn * by "out".  Returns the number of bytes converted or -1 if the conversion
1981.5Sblymn * fails.
1991.1Sblymn */
2001.5Sblymnint convert(char *fp, u_char *out) {
2011.5Sblymn        int i, value, error, count;
2021.5Sblymn
2031.5Sblymn	count = strlen(fp);
2041.5Sblymn
2051.5Sblymn	  /*
2061.5Sblymn	   * if there are not an even number of hex digits then there is
2071.5Sblymn	   * not an integral number of bytes in the fingerprint.
2081.5Sblymn	   */
2091.5Sblymn	if ((count % 2) != 0)
2101.5Sblymn		return -1;
2111.5Sblymn
2121.5Sblymn	count /= 2;
2131.5Sblymn	error = count;
2141.5Sblymn
2151.5Sblymn	for (i = 0; i < count; i++) {
2161.5Sblymn		if ((fp[2*i] >= '0') && (fp[2*i] <= '9')) {
2171.5Sblymn			value = 16 * (fp[2*i] - '0');
2181.5Sblymn		} else if ((tolower(fp[2*i]) >= 'a')
2191.5Sblymn			   && (tolower(fp[2*i]) <= 'f')) {
2201.5Sblymn			value = 16 * (10 + tolower(fp[2*i]) - 'a');
2211.5Sblymn		} else {
2221.5Sblymn			error = -1;
2231.5Sblymn			break;
2241.5Sblymn		}
2251.5Sblymn
2261.5Sblymn		if ((fp[2*i + 1] >= '0') && (fp[2*i + 1] <= '9')) {
2271.5Sblymn			value += fp[2*i + 1] - '0';
2281.5Sblymn		} else if ((tolower(fp[2*i + 1]) >= 'a')
2291.5Sblymn			   && (tolower(fp[2*i + 1]) <= 'f')) {
2301.5Sblymn			value += tolower(fp[2*i + 1]) - 'a' + 10;
2311.5Sblymn		} else {
2321.5Sblymn			error = -1;
2331.5Sblymn			break;
2341.5Sblymn		}
2351.5Sblymn
2361.5Sblymn		out[i] = value;
2371.5Sblymn	}
2381.1Sblymn
2391.5Sblymn	return (error);
2401.1Sblymn}
241