veriexecctl_parse.y revision 1.2
1%{
2/*
3 * Parser for verified exec fingerprint file.
4 *
5 * $NetBSD: veriexecctl_parse.y,v 1.2 2002/12/21 23:41:44 wiz 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 */
16static int     yygrowstack __P((void));
17int yylex __P((void));
18void yyerror __P((const char *));
19
20/* function prototypes */
21static int
22convert(char *fp, unsigned int count, unsigned char *out);
23
24/* ioctl parameter struct */
25struct verified_exec_params params;
26extern int fd;
27extern 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
42statement: /* empty */
43  | statement path type fingerprint flags eol
44  ;
45
46path: PATH
47{
48	strncpy(params.file, $1, 255);
49	params.type = VERIEXEC_DIRECT;
50};
51
52type: 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			"veriexecctl: bad fingerprint type", $1, lineno,
61			"assuming MD5");
62		params.fp_type = FINGERPRINT_TYPE_MD5;
63	}
64};
65
66
67fingerprint: 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			"veriexecctl: bad fingerprint at line %d\n",
79			lineno);
80	}
81};
82
83flags: /* empty */
84	| flag_spec flags;
85
86flag_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
96eol: 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 */
108static int
109convert(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 */
142static void
143do_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