veriexecctl_parse.y revision 1.6
1%{ 2/* $NetBSD: veriexecctl_parse.y,v 1.6 2005/04/21 11:21:58 he Exp $ */ 3 4/*- 5 * Copyright 2005 Elad Efrat <elad@bsd.org.il> 6 * Copyright 2005 Brett Lymn <blymn@netbsd.org> 7 * 8 * All rights reserved. 9 * 10 * This code has been donated to The NetBSD Foundation by the Author. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. The name of the author may not be used to endorse or promote products 18 * derived from this software withough specific prior written permission 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * 31 * 32 */ 33 34#include <sys/param.h> 35#include <sys/ioctl.h> 36#include <sys/statvfs.h> 37#include <sys/mount.h> 38 39#include <sys/verified_exec.h> 40#include <ctype.h> 41#include <stdio.h> 42#include <string.h> 43#include <errno.h> 44#include <err.h> 45 46#include "veriexecctl.h" 47 48struct veriexec_params params; 49 50%} 51 52%union { 53 char *string; 54 int intval; 55} 56 57%token <string> PATH 58%token <string> STRING 59%token EOL 60 61%% 62 63statement : /* empty */ 64 | statement path type fingerprint flags eol { 65 struct stat sb; 66 67 if (phase == 2) { 68 phase2_load(); 69 goto phase_2_end; 70 } 71 72 if (stat(params.file, &sb) == 0) { 73 struct vexec_up *p; 74 75 /* Only regular files */ 76 if (!S_ISREG(sb.st_mode)) { 77 (void) fprintf(stderr, 78 "Line %u: " 79 "%s is not a regular file.\n", 80 line, 81 params.file); 82 } 83 84 if ((p = dev_lookup(sb.st_dev)) != NULL) { 85 (p->vu_param.hash_size)++; 86 } else { 87 if (verbose) { 88 struct statvfs sf; 89 90 statvfs(params.file, 91 &sf); 92 93 (void) printf( 94 " => Adding device" 95 " ID %d. (%s)\n", 96 sb.st_dev, 97 sf.f_mntonname); 98 } 99 100 dev_add(sb.st_dev); 101 } 102 } else { 103 (void) fprintf(stderr, 104 "Line %u: Can't stat" 105 " %s.\n", 106 line, params.file); 107 } 108 109phase_2_end: 110 bzero(¶ms, sizeof(params)); 111 } 112 | statement eol 113 | statement error eol { 114 yyerrok; 115 } 116 ; 117 118path : PATH { 119 strlcpy(params.file, $1, MAXPATHLEN); 120 } 121 ; 122 123type : STRING { 124 if (phase != 1) { 125 if (strlen($1) >= 126 sizeof(params.fp_type)) { 127 yyerror("Fingerprint type too " "long"); 128 YYERROR; 129 } 130 131 strlcpy(params.fp_type, $1, 132 sizeof(params.fp_type)); 133 } 134 } 135 ; 136 137 138fingerprint : STRING { 139 if (phase != 1) { 140 params.fingerprint = (char *) 141 malloc(strlen($1) / 2); 142 if (params.fingerprint == NULL) { 143 fprintf(stderr, "Fingerprint" 144 "mem alloc failed, " 145 "cannot continue.\n"); 146 exit(1); 147 } 148 149 if ((params.size = 150 convert($1, params.fingerprint)) 151 == -1) { 152 free(params.fingerprint); 153 yyerror("Bad fingerprint"); 154 YYERROR; 155 } 156 } 157 158 } 159 ; 160 161flags : /* empty */ { 162 if (phase == 2) 163 params.type = VERIEXEC_DIRECT; 164 } 165 | flags flag_spec 166 ; 167 168flag_spec : STRING { 169 if (phase != 1) { 170 if (strcasecmp($1, "direct") == 0) { 171 params.type = VERIEXEC_DIRECT; 172 } else if (strcasecmp($1, "indirect") 173 == 0) { 174 params.type = VERIEXEC_INDIRECT; 175/* } else if (strcasecmp($1, "shell") == 0) { 176 params.vxp_type = VEXEC_SHELL;*/ 177 } else if (strcasecmp($1, "file") 178 == 0) { 179 params.type = VERIEXEC_FILE; 180 } else { 181 yyerror("Bad option"); 182 YYERROR; 183 } 184 } 185 186 } 187 ; 188 189eol : EOL 190 ; 191 192%% 193 194/* 195 * Takes the hexadecimal string pointed to by "fp" and converts it to a 196 * "count" byte binary number which is stored in the array pointed to 197 * by "out". Returns the number of bytes converted or -1 if the conversion 198 * fails. 199 */ 200int convert(u_char *fp, u_char *out) { 201 int i, value, error, count; 202 203 count = strlen(fp); 204 205 /* 206 * if there are not an even number of hex digits then there is 207 * not an integral number of bytes in the fingerprint. 208 */ 209 if ((count % 2) != 0) 210 return -1; 211 212 count /= 2; 213 error = count; 214 215 for (i = 0; i < count; i++) { 216 if ((fp[2*i] >= '0') && (fp[2*i] <= '9')) { 217 value = 16 * (fp[2*i] - '0'); 218 } else if ((tolower(fp[2*i]) >= 'a') 219 && (tolower(fp[2*i]) <= 'f')) { 220 value = 16 * (10 + tolower(fp[2*i]) - 'a'); 221 } else { 222 error = -1; 223 break; 224 } 225 226 if ((fp[2*i + 1] >= '0') && (fp[2*i + 1] <= '9')) { 227 value += fp[2*i + 1] - '0'; 228 } else if ((tolower(fp[2*i + 1]) >= 'a') 229 && (tolower(fp[2*i + 1]) <= 'f')) { 230 value += tolower(fp[2*i + 1]) - 'a' + 10; 231 } else { 232 error = -1; 233 break; 234 } 235 236 out[i] = value; 237 } 238 239 return (error); 240} 241