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, &params) < 0)
146 		fprintf(stderr,	"Ioctl failed with error `%s' on file %s\n",
147 			strerror(errno), params.file);
148 }
149