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(&params, 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