1 %{ 2 /* 3 * Parser for verified exec fingerprint file. 4 * 5 * $NetBSD: veriexecctl_parse.y,v 1.1 2002/11/23 10:52:49 blymn Exp $ 6 * 7 */ 8 9 #include <stdio.h> 10 #include <string.h> 11 #include <errno.h> 12 #include <sys/ioctl.h> 13 #include <sys/verified_exec.h> 14 15 /* yacc internal function */ 16 static int yygrowstack __P((void)); 17 int yylex __P((void)); 18 void yyerror __P((const char *)); 19 20 /* function prototypes */ 21 static int 22 convert(char *fp, unsigned int count, unsigned char *out); 23 24 /* ioctl parameter struct */ 25 struct verified_exec_params params; 26 extern int fd; 27 extern int lineno; 28 29 %} 30 31 %union { 32 char *string; 33 int intval; 34 } 35 36 %token EOL 37 %token <string> PATH 38 %token <string> STRING 39 40 %% 41 42 statement: /* empty */ 43 | statement path type fingerprint flags eol 44 ; 45 46 path: PATH 47 { 48 strncpy(params.file, $1, 255); 49 params.type = VERIEXEC_DIRECT; 50 }; 51 52 type: STRING 53 { 54 if (strcasecmp($1, "md5") == 0) { 55 params.fp_type = FINGERPRINT_TYPE_MD5; 56 } else if (strcasecmp($1, "sha1") == 0) { 57 params.fp_type = FINGERPRINT_TYPE_SHA1; 58 } else { 59 fprintf(stderr, "%s %s at %d, %s\n", 60 "verifiedexec_load: bad fingerprint type", $1, lineno, 61 "assuming MD5"); 62 params.fp_type = FINGERPRINT_TYPE_MD5; 63 } 64 }; 65 66 67 fingerprint: STRING 68 { 69 unsigned int count; 70 71 if (params.fp_type == FINGERPRINT_TYPE_SHA1) 72 count = SHA1_FINGERPRINTLEN; 73 else 74 count = MD5_FINGERPRINTLEN; 75 76 if (convert($1, count, params.fingerprint) < 0) { 77 fprintf(stderr, 78 "verifiedexec_load: bad fingerprint at line %d\n", 79 lineno); 80 } 81 }; 82 83 flags: /* empty */ 84 | flag_spec flags; 85 86 flag_spec: STRING 87 { 88 params.type = VERIEXEC_DIRECT; 89 if (strcasecmp($1, "indirect") == 0) { 90 params.type = VERIEXEC_INDIRECT; 91 } else if (strcasecmp($1, "file") == 0) { 92 params.type = VERIEXEC_FILE; 93 } 94 }; 95 96 eol: EOL 97 { 98 do_ioctl(); 99 }; 100 101 %% 102 103 /* 104 * Convert: takes the hexadecimal string pointed to by fp and converts 105 * it to a "count" byte binary number which is stored in the array pointed to 106 * by out. Returns -1 if the conversion fails. 107 */ 108 static int 109 convert(char *fp, unsigned int count, unsigned char *out) 110 { 111 int i, value, error = 0; 112 113 for (i = 0; i < count; i++) { 114 if ((fp[2*i] >= '0') && (fp[2*i] <= '9')) { 115 value = 16 * (fp[2*i] - '0'); 116 } else if ((fp[2*i] >= 'a') && (fp[2*i] <= 'f')) { 117 value = 16 * (10 + fp[2*i] - 'a'); 118 } else { 119 error = -1; 120 break; 121 } 122 123 if ((fp[2*i + 1] >= '0') && (fp[2*i + 1] <= '9')) { 124 value += fp[2*i + 1] - '0'; 125 } else if ((fp[2*i + 1] >= 'a') && (fp[2*i + 1] <= 'f')) { 126 value += fp[2*i + 1] - 'a' + 10; 127 } else { 128 error = -1; 129 break; 130 } 131 132 out[i] = value; 133 } 134 135 return error; 136 } 137 138 /* 139 * Perform the load of the fingerprint. Assumes that the fingerprint 140 * pseudo-device is opened and the file handle is in fd. 141 */ 142 static void 143 do_ioctl(void) 144 { 145 if (ioctl(fd, VERIEXECLOAD, ¶ms) < 0) 146 fprintf(stderr, "Ioctl failed with error `%s' on file %s\n", 147 strerror(errno), params.file); 148 } 149