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(¶ms, 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