veriexecctl_parse.y revision 1.21
11.1Sblymn%{ 21.21Selad/* $NetBSD: veriexecctl_parse.y,v 1.21 2007/05/15 19:47:47 elad Exp $ */ 31.5Sblymn 41.5Sblymn/*- 51.18Selad * Copyright 2005 Elad Efrat <elad@NetBSD.org> 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.21Selad#include <sys/stat.h> 351.21Selad#include <sys/verified_exec.h> 361.5Sblymn 371.5Sblymn#include <ctype.h> 381.1Sblymn#include <stdio.h> 391.1Sblymn#include <string.h> 401.5Sblymn#include <err.h> 411.5Sblymn 421.19Selad#include <prop/proplib.h> 431.19Selad 441.5Sblymn#include "veriexecctl.h" 451.1Sblymn 461.21Seladextern int yylex(void); 471.21Seladextern size_t line; 481.21Seladextern int verbose, error; 491.21Selad 501.21Seladboolean_t keep_filename = FALSE, eval_on_load = FALSE; 511.19Seladprop_dictionary_t load_params; 521.1Sblymn 531.1Sblymn%} 541.1Sblymn 551.1Sblymn%union { 561.5Sblymn char *string; 571.5Sblymn int intval; 581.1Sblymn} 591.1Sblymn 601.1Sblymn%token <string> PATH 611.1Sblymn%token <string> STRING 621.10Selad%token EOL TOKEN_COMMA 631.1Sblymn 641.1Sblymn%% 651.1Sblymn 661.5Sblymnstatement : /* empty */ 671.5Sblymn | statement path type fingerprint flags eol { 681.21Selad extern int gfd; 691.7Schristos struct stat sb; 701.7Schristos 711.19Selad if (stat(dict_gets(load_params, "file"), &sb) == -1) { 721.21Selad if (verbose) 731.21Selad warnx("Line %zu: Can't stat `%s'", line, 741.21Selad dict_gets(load_params, "file")); 751.21Selad error = EXIT_FAILURE; 761.21Selad goto skip; 771.7Schristos } 781.7Schristos 791.7Schristos /* Only regular files */ 801.7Schristos if (!S_ISREG(sb.st_mode)) { 811.21Selad if (verbose) 821.21Selad warnx("Line %zu: %s is not a regular file", line, 831.21Selad dict_gets(load_params, "file")); 841.21Selad error = EXIT_FAILURE; 851.21Selad goto skip; 861.7Schristos } 871.7Schristos 881.21Selad if (verbose) { 891.21Selad (void)printf( "Adding file `%s'.\n", 901.21Selad dict_gets(load_params, "file")); 911.21Selad } 921.16Selad 931.21Selad prop_dictionary_set(load_params, "keep-filename", 941.21Selad prop_bool_create(keep_filename)); 951.19Selad 961.21Selad prop_dictionary_set(load_params, "eval-on-load", 971.21Selad prop_bool_create(eval_on_load)); 981.19Selad 991.21Selad if (prop_dictionary_send_ioctl(load_params, gfd, VERIEXEC_LOAD) != 0) { 1001.21Selad if (verbose) 1011.21Selad warn("Cannot load params from `%s'", 1021.21Selad dict_gets(load_params, "file")); 1031.21Selad error = EXIT_FAILURE; 1041.16Selad } 1051.16Selad 1061.21Selad skip: 1071.21Selad prop_object_release(load_params); 1081.19Selad load_params = NULL; 1091.7Schristos} 1101.5Sblymn | statement eol 1111.5Sblymn | statement error eol { 1121.7Schristos yyerrok; 1131.7Schristos} 1141.5Sblymn ; 1151.5Sblymn 1161.5Sblymnpath : PATH { 1171.19Selad if (load_params == NULL) 1181.19Selad load_params = prop_dictionary_create(); 1191.19Selad 1201.19Selad dict_sets(load_params, "file", $1); 1211.7Schristos} 1221.5Sblymn ; 1231.5Sblymn 1241.5Sblymntype : STRING { 1251.21Selad dict_sets(load_params, "fp-type", $1); 1261.7Schristos} 1271.5Sblymn ; 1281.1Sblymn 1291.1Sblymn 1301.5Sblymnfingerprint : STRING { 1311.21Selad char *fp; 1321.21Selad size_t n; 1331.21Selad 1341.21Selad fp = malloc(strlen($1) / 2); 1351.21Selad if (fp == NULL) 1361.21Selad err(1, "Cannot allocate memory for fingerprint"); 1371.19Selad 1381.21Selad n = convert($1, fp); 1391.21Selad if (n == -1) { 1401.19Selad free(fp); 1411.21Selad if (verbose) 1421.21Selad warnx("Bad fingerprint `%s' in line %zu", $1, line); 1431.21Selad error = EXIT_FAILURE; 1441.21Selad YYERROR; 1451.7Schristos } 1461.21Selad 1471.21Selad dict_setd(load_params, "fp", fp, n); 1481.21Selad free(fp); 1491.7Schristos} 1501.7Schristos ; 1511.1Sblymn 1521.13Seladflags : /* empty */ 1531.10Selad | flags_spec 1541.10Selad ; 1551.10Selad 1561.10Seladflags_spec : flag_spec 1571.10Selad | flags_spec TOKEN_COMMA flag_spec 1581.5Sblymn ; 1591.1Sblymn 1601.5Sblymnflag_spec : STRING { 1611.21Selad uint8_t t = 0; 1621.20Selad 1631.21Selad prop_dictionary_get_uint8(load_params, "entry-type", &t); 1641.19Selad 1651.21Selad if (strcasecmp($1, "direct") == 0) { 1661.21Selad t |= VERIEXEC_DIRECT; 1671.21Selad } else if (strcasecmp($1, "indirect") == 0) { 1681.21Selad t |= VERIEXEC_INDIRECT; 1691.21Selad } else if (strcasecmp($1, "file") == 0) { 1701.21Selad t |= VERIEXEC_FILE; 1711.21Selad } else if (strcasecmp($1, "program") == 0) { 1721.21Selad t |= VERIEXEC_DIRECT; 1731.21Selad } else if (strcasecmp($1, "interpreter") == 0) { 1741.21Selad t |= VERIEXEC_INDIRECT; 1751.21Selad } else if (strcasecmp($1, "script") == 0) { 1761.21Selad t |= (VERIEXEC_FILE | VERIEXEC_DIRECT); 1771.21Selad } else if (strcasecmp($1, "library") == 0) { 1781.21Selad t |= (VERIEXEC_FILE | VERIEXEC_INDIRECT); 1791.21Selad } else if (strcasecmp($1, "untrusted") == 0) { 1801.21Selad t |= VERIEXEC_UNTRUSTED; 1811.21Selad } else { 1821.21Selad if (verbose) 1831.21Selad warnx("Bad flag `%s' in line %zu", $1, line); 1841.21Selad error = EXIT_FAILURE; 1851.21Selad YYERROR; 1861.7Schristos } 1871.1Sblymn 1881.21Selad prop_dictionary_set_uint8(load_params, "entry-type", t); 1891.7Schristos} 1901.5Sblymn ; 1911.1Sblymn 1921.5Sblymneol : EOL 1931.5Sblymn ; 1941.1Sblymn 1951.1Sblymn%% 1961.21Selad 1971.1Sblymn/* 1981.5Sblymn * Takes the hexadecimal string pointed to by "fp" and converts it to a 1991.5Sblymn * "count" byte binary number which is stored in the array pointed to 2001.5Sblymn * by "out". Returns the number of bytes converted or -1 if the conversion 2011.5Sblymn * fails. 2021.1Sblymn */ 2031.19Seladstatic size_t 2041.7Schristosconvert(u_char *fp, u_char *out) 2051.7Schristos{ 2061.7Schristos size_t i, count; 2071.7Schristos u_char value; 2081.5Sblymn 2091.5Sblymn count = strlen(fp); 2101.5Sblymn 2111.7Schristos /* 2121.7Schristos * if there are not an even number of hex digits then there is 2131.7Schristos * not an integral number of bytes in the fingerprint. 2141.7Schristos */ 2151.5Sblymn if ((count % 2) != 0) 2161.5Sblymn return -1; 2171.5Sblymn 2181.5Sblymn count /= 2; 2191.7Schristos 2201.7Schristos#define cvt(cv) \ 2211.7Schristos if (isdigit(cv)) \ 2221.7Schristos value += (cv) - '0'; \ 2231.7Schristos else if (isxdigit(cv)) \ 2241.7Schristos value += 10 + tolower(cv) - 'a'; \ 2251.7Schristos else \ 2261.7Schristos return -1 2271.5Sblymn 2281.5Sblymn for (i = 0; i < count; i++) { 2291.7Schristos value = 0; 2301.7Schristos cvt(fp[2 * i]); 2311.7Schristos value <<= 4; 2321.7Schristos cvt(fp[2 * i + 1]); 2331.5Sblymn out[i] = value; 2341.5Sblymn } 2351.1Sblymn 2361.7Schristos return count; 2371.1Sblymn} 2381.21Selad 2391.21Seladstatic void 2401.21Seladyyerror(const char *msg) 2411.21Selad{ 2421.21Selad if (verbose) 2431.21Selad warnx("%s in line %zu", msg, line); 2441.21Selad} 245