veriexecctl_parse.y revision 1.25
11.1Sblymn%{ 21.25Sdholland/* $NetBSD: veriexecctl_parse.y,v 1.25 2008/08/31 23:37:45 dholland Exp $ */ 31.5Sblymn 41.5Sblymn/*- 51.18Selad * Copyright 2005 Elad Efrat <elad@NetBSD.org> 61.25Sdholland * 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.22Spavel#include <stdbool.h> 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.22Spavelbool 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.1Sblymn} 581.1Sblymn 591.1Sblymn%token <string> PATH 601.1Sblymn%token <string> STRING 611.10Selad%token EOL TOKEN_COMMA 621.1Sblymn 631.1Sblymn%% 641.1Sblymn 651.5Sblymnstatement : /* empty */ 661.5Sblymn | statement path type fingerprint flags eol { 671.21Selad extern int gfd; 681.7Schristos struct stat sb; 691.7Schristos 701.19Selad if (stat(dict_gets(load_params, "file"), &sb) == -1) { 711.21Selad if (verbose) 721.21Selad warnx("Line %zu: Can't stat `%s'", line, 731.21Selad dict_gets(load_params, "file")); 741.21Selad error = EXIT_FAILURE; 751.21Selad goto skip; 761.7Schristos } 771.7Schristos 781.7Schristos /* Only regular files */ 791.7Schristos if (!S_ISREG(sb.st_mode)) { 801.21Selad if (verbose) 811.21Selad warnx("Line %zu: %s is not a regular file", line, 821.21Selad dict_gets(load_params, "file")); 831.21Selad error = EXIT_FAILURE; 841.21Selad goto skip; 851.7Schristos } 861.7Schristos 871.21Selad if (verbose) { 881.21Selad (void)printf( "Adding file `%s'.\n", 891.21Selad dict_gets(load_params, "file")); 901.21Selad } 911.16Selad 921.21Selad prop_dictionary_set(load_params, "keep-filename", 931.21Selad prop_bool_create(keep_filename)); 941.19Selad 951.21Selad prop_dictionary_set(load_params, "eval-on-load", 961.21Selad prop_bool_create(eval_on_load)); 971.19Selad 981.21Selad if (prop_dictionary_send_ioctl(load_params, gfd, VERIEXEC_LOAD) != 0) { 991.21Selad if (verbose) 1001.21Selad warn("Cannot load params from `%s'", 1011.21Selad dict_gets(load_params, "file")); 1021.21Selad error = EXIT_FAILURE; 1031.16Selad } 1041.16Selad 1051.21Selad skip: 1061.21Selad prop_object_release(load_params); 1071.19Selad load_params = NULL; 1081.7Schristos} 1091.5Sblymn | statement eol 1101.5Sblymn | statement error eol { 1111.7Schristos yyerrok; 1121.7Schristos} 1131.5Sblymn ; 1141.5Sblymn 1151.5Sblymnpath : PATH { 1161.19Selad if (load_params == NULL) 1171.19Selad load_params = prop_dictionary_create(); 1181.19Selad 1191.19Selad dict_sets(load_params, "file", $1); 1201.7Schristos} 1211.5Sblymn ; 1221.5Sblymn 1231.5Sblymntype : STRING { 1241.21Selad dict_sets(load_params, "fp-type", $1); 1251.7Schristos} 1261.5Sblymn ; 1271.1Sblymn 1281.1Sblymn 1291.5Sblymnfingerprint : STRING { 1301.24Sdholland u_char *fp; 1311.21Selad size_t n; 1321.21Selad 1331.21Selad fp = malloc(strlen($1) / 2); 1341.21Selad if (fp == NULL) 1351.21Selad err(1, "Cannot allocate memory for fingerprint"); 1361.19Selad 1371.21Selad n = convert($1, fp); 1381.21Selad if (n == -1) { 1391.19Selad free(fp); 1401.21Selad if (verbose) 1411.21Selad warnx("Bad fingerprint `%s' in line %zu", $1, line); 1421.21Selad error = EXIT_FAILURE; 1431.21Selad YYERROR; 1441.7Schristos } 1451.21Selad 1461.21Selad dict_setd(load_params, "fp", fp, n); 1471.21Selad free(fp); 1481.7Schristos} 1491.7Schristos ; 1501.1Sblymn 1511.13Seladflags : /* empty */ 1521.10Selad | flags_spec 1531.10Selad ; 1541.10Selad 1551.10Seladflags_spec : flag_spec 1561.10Selad | flags_spec TOKEN_COMMA flag_spec 1571.5Sblymn ; 1581.1Sblymn 1591.5Sblymnflag_spec : STRING { 1601.21Selad uint8_t t = 0; 1611.20Selad 1621.21Selad prop_dictionary_get_uint8(load_params, "entry-type", &t); 1631.19Selad 1641.21Selad if (strcasecmp($1, "direct") == 0) { 1651.21Selad t |= VERIEXEC_DIRECT; 1661.21Selad } else if (strcasecmp($1, "indirect") == 0) { 1671.21Selad t |= VERIEXEC_INDIRECT; 1681.21Selad } else if (strcasecmp($1, "file") == 0) { 1691.21Selad t |= VERIEXEC_FILE; 1701.21Selad } else if (strcasecmp($1, "program") == 0) { 1711.21Selad t |= VERIEXEC_DIRECT; 1721.21Selad } else if (strcasecmp($1, "interpreter") == 0) { 1731.21Selad t |= VERIEXEC_INDIRECT; 1741.21Selad } else if (strcasecmp($1, "script") == 0) { 1751.21Selad t |= (VERIEXEC_FILE | VERIEXEC_DIRECT); 1761.21Selad } else if (strcasecmp($1, "library") == 0) { 1771.21Selad t |= (VERIEXEC_FILE | VERIEXEC_INDIRECT); 1781.21Selad } else if (strcasecmp($1, "untrusted") == 0) { 1791.21Selad t |= VERIEXEC_UNTRUSTED; 1801.21Selad } else { 1811.21Selad if (verbose) 1821.21Selad warnx("Bad flag `%s' in line %zu", $1, line); 1831.21Selad error = EXIT_FAILURE; 1841.21Selad YYERROR; 1851.7Schristos } 1861.1Sblymn 1871.21Selad prop_dictionary_set_uint8(load_params, "entry-type", t); 1881.7Schristos} 1891.5Sblymn ; 1901.1Sblymn 1911.5Sblymneol : EOL 1921.5Sblymn ; 1931.1Sblymn 1941.1Sblymn%% 1951.21Selad 1961.1Sblymn/* 1971.25Sdholland * Takes the hexadecimal string pointed to by "fp" and converts it to a 1981.5Sblymn * "count" byte binary number which is stored in the array pointed to 1991.5Sblymn * by "out". Returns the number of bytes converted or -1 if the conversion 2001.5Sblymn * fails. 2011.1Sblymn */ 2021.19Seladstatic size_t 2031.24Sdhollandconvert(char *fp, u_char *out) 2041.7Schristos{ 2051.7Schristos size_t i, count; 2061.7Schristos u_char value; 2071.5Sblymn 2081.5Sblymn count = strlen(fp); 2091.5Sblymn 2101.7Schristos /* 2111.7Schristos * if there are not an even number of hex digits then there is 2121.7Schristos * not an integral number of bytes in the fingerprint. 2131.7Schristos */ 2141.5Sblymn if ((count % 2) != 0) 2151.5Sblymn return -1; 2161.25Sdholland 2171.5Sblymn count /= 2; 2181.7Schristos 2191.7Schristos#define cvt(cv) \ 2201.24Sdholland if (isdigit((unsigned char) cv)) \ 2211.7Schristos value += (cv) - '0'; \ 2221.24Sdholland else if (isxdigit((unsigned char) cv)) \ 2231.24Sdholland value += 10 + tolower((unsigned char) cv) - 'a'; \ 2241.7Schristos else \ 2251.7Schristos return -1 2261.5Sblymn 2271.5Sblymn for (i = 0; i < count; i++) { 2281.7Schristos value = 0; 2291.7Schristos cvt(fp[2 * i]); 2301.7Schristos value <<= 4; 2311.7Schristos cvt(fp[2 * i + 1]); 2321.5Sblymn out[i] = value; 2331.5Sblymn } 2341.1Sblymn 2351.7Schristos return count; 2361.1Sblymn} 2371.21Selad 2381.21Seladstatic void 2391.21Seladyyerror(const char *msg) 2401.21Selad{ 2411.21Selad if (verbose) 2421.21Selad warnx("%s in line %zu", msg, line); 2431.21Selad} 244