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