Blame


1 8d1b399b 2021-07-22 op /*
2 8d1b399b 2021-07-22 op * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
3 8d1b399b 2021-07-22 op * Copyright (c) 2018 Florian Obser <florian@openbsd.org>
4 8d1b399b 2021-07-22 op * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
5 8d1b399b 2021-07-22 op * Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org>
6 8d1b399b 2021-07-22 op * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
7 8d1b399b 2021-07-22 op * Copyright (c) 2001 Markus Friedl. All rights reserved.
8 8d1b399b 2021-07-22 op * Copyright (c) 2001 Daniel Hartmeier. All rights reserved.
9 8d1b399b 2021-07-22 op * Copyright (c) 2001 Theo de Raadt. All rights reserved.
10 8d1b399b 2021-07-22 op *
11 8d1b399b 2021-07-22 op * Permission to use, copy, modify, and distribute this software for any
12 8d1b399b 2021-07-22 op * purpose with or without fee is hereby granted, provided that the above
13 8d1b399b 2021-07-22 op * copyright notice and this permission notice appear in all copies.
14 8d1b399b 2021-07-22 op *
15 8d1b399b 2021-07-22 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
16 8d1b399b 2021-07-22 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17 8d1b399b 2021-07-22 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
18 8d1b399b 2021-07-22 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 8d1b399b 2021-07-22 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 8d1b399b 2021-07-22 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
21 8d1b399b 2021-07-22 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 8d1b399b 2021-07-22 op */
23 8d1b399b 2021-07-22 op
24 8d1b399b 2021-07-22 op %{
25 8d1b399b 2021-07-22 op #include "compat.h"
26 8d1b399b 2021-07-22 op
27 8d1b399b 2021-07-22 op #include <sys/stat.h>
28 8d1b399b 2021-07-22 op
29 8d1b399b 2021-07-22 op #include <ctype.h>
30 8d1b399b 2021-07-22 op #include <err.h>
31 8d1b399b 2021-07-22 op #include <errno.h>
32 8d1b399b 2021-07-22 op #include <event.h>
33 8d1b399b 2021-07-22 op #include <inttypes.h>
34 8d1b399b 2021-07-22 op #include <limits.h>
35 8d1b399b 2021-07-22 op #include <stdarg.h>
36 8d1b399b 2021-07-22 op #include <stdio.h>
37 8d1b399b 2021-07-22 op #include <stdlib.h>
38 8d1b399b 2021-07-22 op #include <string.h>
39 8d1b399b 2021-07-22 op #include <syslog.h>
40 8d1b399b 2021-07-22 op #include <unistd.h>
41 8d1b399b 2021-07-22 op
42 8d1b399b 2021-07-22 op #include "log.h"
43 8d1b399b 2021-07-22 op #include "kamid.h"
44 8d1b399b 2021-07-22 op #include "table.h"
45 8d1b399b 2021-07-22 op #include "utils.h"
46 8d1b399b 2021-07-22 op
47 8d1b399b 2021-07-22 op TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
48 8d1b399b 2021-07-22 op static struct file {
49 8d1b399b 2021-07-22 op TAILQ_ENTRY(file) entry;
50 8d1b399b 2021-07-22 op FILE *stream;
51 8d1b399b 2021-07-22 op char *name;
52 8d1b399b 2021-07-22 op size_t ungetpos;
53 8d1b399b 2021-07-22 op size_t ungetsize;
54 8d1b399b 2021-07-22 op u_char *ungetbuf;
55 8d1b399b 2021-07-22 op int eof_reached;
56 8d1b399b 2021-07-22 op int lineno;
57 8d1b399b 2021-07-22 op int errors;
58 8d1b399b 2021-07-22 op } *file, *topfile;
59 8d1b399b 2021-07-22 op struct file *pushfile(const char *, int);
60 8d1b399b 2021-07-22 op int popfile(void);
61 8d1b399b 2021-07-22 op int check_file_secrecy(int, const char *);
62 8d1b399b 2021-07-22 op int yyparse(void);
63 8d1b399b 2021-07-22 op int yylex(void);
64 8d1b399b 2021-07-22 op int yyerror(const char *, ...)
65 8d1b399b 2021-07-22 op __attribute__((__format__ (printf, 1, 2)))
66 8d1b399b 2021-07-22 op __attribute__((__nonnull__ (1)));
67 8d1b399b 2021-07-22 op int kw_cmp(const void *, const void *);
68 8d1b399b 2021-07-22 op int lookup(char *);
69 8d1b399b 2021-07-22 op int igetc(void);
70 8d1b399b 2021-07-22 op int lgetc(int);
71 8d1b399b 2021-07-22 op void lungetc(int);
72 8d1b399b 2021-07-22 op int findeol(void);
73 8d1b399b 2021-07-22 op
74 8d1b399b 2021-07-22 op TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead);
75 8d1b399b 2021-07-22 op struct sym {
76 8d1b399b 2021-07-22 op TAILQ_ENTRY(sym) entry;
77 8d1b399b 2021-07-22 op int used;
78 8d1b399b 2021-07-22 op int persist;
79 8d1b399b 2021-07-22 op char *nam;
80 8d1b399b 2021-07-22 op char *val;
81 8d1b399b 2021-07-22 op };
82 8d1b399b 2021-07-22 op
83 8d1b399b 2021-07-22 op int symset(const char *, const char *, int);
84 8d1b399b 2021-07-22 op char *symget(const char *);
85 8d1b399b 2021-07-22 op
86 8d1b399b 2021-07-22 op void clear_config(struct kd_conf *xconf);
87 8d1b399b 2021-07-22 op
88 8d1b399b 2021-07-22 op static void add_table(const char *, const char *, const char *);
89 8d1b399b 2021-07-22 op static struct table *findtable(const char *name);
90 8d1b399b 2021-07-22 op static void add_cert(const char *, const char *);
91 8d1b399b 2021-07-22 op static void add_key(const char *, const char *);
92 d82b9f6d 2021-07-22 op static struct kd_listen_conf *listen_new(void);
93 8d1b399b 2021-07-22 op
94 8d1b399b 2021-07-22 op static uint32_t counter;
95 8d1b399b 2021-07-22 op static struct table *table;
96 95eb4eb9 2021-07-22 op static struct kd_listen_conf *listener;
97 8d1b399b 2021-07-22 op static struct kd_conf *conf;
98 8d1b399b 2021-07-22 op static int errors;
99 8d1b399b 2021-07-22 op
100 8d1b399b 2021-07-22 op typedef struct {
101 8d1b399b 2021-07-22 op union {
102 8d1b399b 2021-07-22 op int64_t number;
103 8d1b399b 2021-07-22 op char *string;
104 8d1b399b 2021-07-22 op struct table *table;
105 8d1b399b 2021-07-22 op } v;
106 8d1b399b 2021-07-22 op int lineno;
107 8d1b399b 2021-07-22 op } YYSTYPE;
108 8d1b399b 2021-07-22 op
109 8d1b399b 2021-07-22 op %}
110 8d1b399b 2021-07-22 op
111 8d1b399b 2021-07-22 op %token AUTH
112 8d1b399b 2021-07-22 op %token CERT
113 8d1b399b 2021-07-22 op %token ERROR
114 8d1b399b 2021-07-22 op %token INCLUDE
115 8d1b399b 2021-07-22 op %token KEY
116 8d1b399b 2021-07-22 op %token LISTEN
117 8d1b399b 2021-07-22 op %token NO
118 8d1b399b 2021-07-22 op %token ON
119 8d1b399b 2021-07-22 op %token PKI PORT
120 8d1b399b 2021-07-22 op %token TABLE TLS
121 c35679af 2021-12-18 op %token USERDATA
122 c35679af 2021-12-18 op %token VIRTUAL
123 8d1b399b 2021-07-22 op %token YES
124 8d1b399b 2021-07-22 op
125 8d1b399b 2021-07-22 op %token <v.string> STRING
126 8d1b399b 2021-07-22 op %token <v.number> NUMBER
127 8d1b399b 2021-07-22 op %type <v.number> yesno
128 8d1b399b 2021-07-22 op %type <v.string> string
129 8d1b399b 2021-07-22 op %type <v.table> tableref
130 8d1b399b 2021-07-22 op
131 8d1b399b 2021-07-22 op %%
132 8d1b399b 2021-07-22 op
133 8d1b399b 2021-07-22 op grammar : /* empty */
134 8d1b399b 2021-07-22 op | grammar include '\n'
135 8d1b399b 2021-07-22 op | grammar '\n'
136 8d1b399b 2021-07-22 op | grammar table '\n'
137 8d1b399b 2021-07-22 op | grammar pki '\n'
138 8d1b399b 2021-07-22 op | grammar listen '\n'
139 8d1b399b 2021-07-22 op | grammar varset '\n'
140 8d1b399b 2021-07-22 op | grammar error '\n' { file->errors++; }
141 8d1b399b 2021-07-22 op ;
142 8d1b399b 2021-07-22 op
143 8d1b399b 2021-07-22 op include : INCLUDE STRING {
144 8d1b399b 2021-07-22 op struct file *nfile;
145 8d1b399b 2021-07-22 op
146 8d1b399b 2021-07-22 op if ((nfile = pushfile($2, 0)) == NULL) {
147 8d1b399b 2021-07-22 op yyerror("failed to include file %s", $2);
148 8d1b399b 2021-07-22 op free($2);
149 8d1b399b 2021-07-22 op YYERROR;
150 8d1b399b 2021-07-22 op }
151 8d1b399b 2021-07-22 op free($2);
152 8d1b399b 2021-07-22 op
153 8d1b399b 2021-07-22 op file = nfile;
154 8d1b399b 2021-07-22 op lungetc('\n');
155 8d1b399b 2021-07-22 op }
156 8d1b399b 2021-07-22 op ;
157 8d1b399b 2021-07-22 op
158 8d1b399b 2021-07-22 op string : string STRING {
159 8d1b399b 2021-07-22 op if (asprintf(&$$, "%s %s", $1, $2) == -1) {
160 8d1b399b 2021-07-22 op free($1);
161 8d1b399b 2021-07-22 op free($2);
162 8d1b399b 2021-07-22 op yyerror("string: asprintf");
163 8d1b399b 2021-07-22 op YYERROR;
164 8d1b399b 2021-07-22 op }
165 8d1b399b 2021-07-22 op free($1);
166 8d1b399b 2021-07-22 op free($2);
167 8d1b399b 2021-07-22 op }
168 8d1b399b 2021-07-22 op | STRING
169 8d1b399b 2021-07-22 op ;
170 8d1b399b 2021-07-22 op
171 8d1b399b 2021-07-22 op yesno : YES { $$ = 1; }
172 8d1b399b 2021-07-22 op | NO { $$ = 0; }
173 8d1b399b 2021-07-22 op ;
174 8d1b399b 2021-07-22 op
175 8d1b399b 2021-07-22 op optnl : '\n' optnl /* zero or more newlines */
176 8d1b399b 2021-07-22 op | /*empty*/
177 8d1b399b 2021-07-22 op ;
178 8d1b399b 2021-07-22 op
179 8d1b399b 2021-07-22 op nl : '\n' optnl /* one or more newlines */
180 8d1b399b 2021-07-22 op ;
181 8d1b399b 2021-07-22 op
182 8d1b399b 2021-07-22 op arrow : '=' '>' ;
183 8d1b399b 2021-07-22 op
184 8d1b399b 2021-07-22 op comma : ',' optnl
185 8d1b399b 2021-07-22 op ;
186 8d1b399b 2021-07-22 op
187 8d1b399b 2021-07-22 op varset : STRING '=' string {
188 8d1b399b 2021-07-22 op char *s = $1;
189 8d1b399b 2021-07-22 op if (verbose)
190 8d1b399b 2021-07-22 op printf("%s = \"%s\"\n", $1, $3);
191 8d1b399b 2021-07-22 op while (*s++) {
192 8d1b399b 2021-07-22 op if (isspace((unsigned char)*s)) {
193 8d1b399b 2021-07-22 op yyerror("macro name cannot contain "
194 8d1b399b 2021-07-22 op "whitespace");
195 8d1b399b 2021-07-22 op free($1);
196 8d1b399b 2021-07-22 op free($3);
197 8d1b399b 2021-07-22 op YYERROR;
198 8d1b399b 2021-07-22 op }
199 8d1b399b 2021-07-22 op }
200 8d1b399b 2021-07-22 op if (symset($1, $3, 0) == -1)
201 8d1b399b 2021-07-22 op fatal("cannot store variable");
202 8d1b399b 2021-07-22 op free($1);
203 8d1b399b 2021-07-22 op free($3);
204 8d1b399b 2021-07-22 op }
205 8d1b399b 2021-07-22 op ;
206 8d1b399b 2021-07-22 op
207 8d1b399b 2021-07-22 op pki : PKI STRING CERT STRING { add_cert($2, $4); }
208 8d1b399b 2021-07-22 op | PKI STRING KEY STRING { add_key($2, $4); }
209 8d1b399b 2021-07-22 op ;
210 8d1b399b 2021-07-22 op
211 156f1ecc 2021-11-30 op table_kp : string arrow string optnl {
212 8d1b399b 2021-07-22 op if (table_add(table, $1, $3) == -1)
213 8d1b399b 2021-07-22 op yyerror("can't add to table %s",
214 8d1b399b 2021-07-22 op table->t_name);
215 8d1b399b 2021-07-22 op free($1);
216 8d1b399b 2021-07-22 op free($3);
217 8d1b399b 2021-07-22 op }
218 8d1b399b 2021-07-22 op ;
219 8d1b399b 2021-07-22 op
220 8d1b399b 2021-07-22 op table_kps : table_kp
221 8d1b399b 2021-07-22 op | table_kp comma table_kps
222 8d1b399b 2021-07-22 op ;
223 8d1b399b 2021-07-22 op
224 8d1b399b 2021-07-22 op stringel : STRING {
225 8d1b399b 2021-07-22 op if (table_add(table, $1, NULL) == -1)
226 8d1b399b 2021-07-22 op yyerror("can't add to table %s",
227 8d1b399b 2021-07-22 op table->t_name);
228 8d1b399b 2021-07-22 op free($1);
229 8d1b399b 2021-07-22 op }
230 8d1b399b 2021-07-22 op ;
231 8d1b399b 2021-07-22 op
232 8d1b399b 2021-07-22 op string_list : stringel
233 8d1b399b 2021-07-22 op | stringel comma string_list
234 8d1b399b 2021-07-22 op ;
235 8d1b399b 2021-07-22 op
236 8d1b399b 2021-07-22 op table_vals : table_kps
237 8d1b399b 2021-07-22 op | string_list
238 8d1b399b 2021-07-22 op ;
239 8d1b399b 2021-07-22 op
240 8d1b399b 2021-07-22 op table : TABLE STRING STRING {
241 8d1b399b 2021-07-22 op char *p;
242 8d1b399b 2021-07-22 op
243 8d1b399b 2021-07-22 op if ((p = strchr($3, ':')) == NULL) {
244 8d1b399b 2021-07-22 op yyerror("invalid table %s", $2);
245 8d1b399b 2021-07-22 op YYERROR;
246 8d1b399b 2021-07-22 op }
247 8d1b399b 2021-07-22 op
248 8d1b399b 2021-07-22 op *p = '\0';
249 8d1b399b 2021-07-22 op add_table($2, $3, p+1);
250 8d1b399b 2021-07-22 op free($2);
251 8d1b399b 2021-07-22 op free($3);
252 8d1b399b 2021-07-22 op }
253 8d1b399b 2021-07-22 op | TABLE STRING {
254 8d1b399b 2021-07-22 op add_table($2, "static", NULL);
255 156f1ecc 2021-11-30 op } '{' optnl table_vals '}' {
256 8d1b399b 2021-07-22 op table = NULL;
257 8d1b399b 2021-07-22 op }
258 8d1b399b 2021-07-22 op ;
259 8d1b399b 2021-07-22 op
260 8d1b399b 2021-07-22 op tableref : '<' STRING '>' {
261 d82b9f6d 2021-07-22 op struct table *t;
262 d82b9f6d 2021-07-22 op
263 d82b9f6d 2021-07-22 op t = findtable($2);
264 d82b9f6d 2021-07-22 op free($2);
265 d82b9f6d 2021-07-22 op if (t == NULL)
266 8d1b399b 2021-07-22 op YYERROR;
267 d82b9f6d 2021-07-22 op $$ = t;
268 8d1b399b 2021-07-22 op }
269 8d1b399b 2021-07-22 op ;
270 8d1b399b 2021-07-22 op
271 95eb4eb9 2021-07-22 op listen : LISTEN { listener = listen_new(); }
272 fccfa871 2021-07-23 op listen_opts {
273 fccfa871 2021-07-23 op if (listener->auth_table == NULL)
274 fccfa871 2021-07-23 op yyerror("missing auth table");
275 2695b856 2021-07-23 op if (!(listener->flags & L_TLS))
276 2695b856 2021-07-23 op yyerror("can't define a non-tls listener");
277 fccfa871 2021-07-23 op listener = NULL;
278 9693abfe 2021-11-30 op }
279 9693abfe 2021-11-30 op ;
280 8d1b399b 2021-07-22 op
281 d82b9f6d 2021-07-22 op listen_opts : listen_opt
282 d82b9f6d 2021-07-22 op | listen_opt listen_opts
283 d82b9f6d 2021-07-22 op ;
284 d82b9f6d 2021-07-22 op
285 d82b9f6d 2021-07-22 op listen_opt : ON STRING PORT NUMBER {
286 95eb4eb9 2021-07-22 op if (*listener->iface != '\0')
287 d82b9f6d 2021-07-22 op yyerror("listen address and port already"
288 d82b9f6d 2021-07-22 op " defined");
289 95eb4eb9 2021-07-22 op strlcpy(listener->iface, $2, sizeof(listener->iface));
290 95eb4eb9 2021-07-22 op listener->port = $4;
291 d82b9f6d 2021-07-22 op }
292 d82b9f6d 2021-07-22 op | TLS PKI STRING {
293 95eb4eb9 2021-07-22 op if (*listener->pki != '\0')
294 d82b9f6d 2021-07-22 op yyerror("listen tls pki already defined");
295 fccfa871 2021-07-23 op listener->flags |= L_TLS;
296 95eb4eb9 2021-07-22 op strlcpy(listener->pki, $3, sizeof(listener->pki));
297 d82b9f6d 2021-07-22 op }
298 d82b9f6d 2021-07-22 op | AUTH tableref {
299 95eb4eb9 2021-07-22 op if (listener->auth_table != NULL)
300 d82b9f6d 2021-07-22 op yyerror("listen auth already defined");
301 95eb4eb9 2021-07-22 op listener->auth_table = $2;
302 c35679af 2021-12-18 op }
303 c35679af 2021-12-18 op | USERDATA tableref {
304 c35679af 2021-12-18 op if (listener->userdata_table != NULL)
305 c35679af 2021-12-18 op yyerror("userdata table already defined");
306 c35679af 2021-12-18 op listener->userdata_table = $2;
307 c35679af 2021-12-18 op }
308 c35679af 2021-12-18 op | VIRTUAL tableref {
309 c35679af 2021-12-18 op if (listener->virtual_table != NULL)
310 c35679af 2021-12-18 op yyerror("virtual table already defined");
311 c35679af 2021-12-18 op listener->virtual_table = $2;
312 8d1b399b 2021-07-22 op }
313 8d1b399b 2021-07-22 op ;
314 8d1b399b 2021-07-22 op
315 8d1b399b 2021-07-22 op %%
316 8d1b399b 2021-07-22 op
317 8d1b399b 2021-07-22 op struct keywords {
318 8d1b399b 2021-07-22 op const char *k_name;
319 8d1b399b 2021-07-22 op int k_val;
320 8d1b399b 2021-07-22 op };
321 8d1b399b 2021-07-22 op
322 8d1b399b 2021-07-22 op int
323 8d1b399b 2021-07-22 op yyerror(const char *fmt, ...)
324 8d1b399b 2021-07-22 op {
325 8d1b399b 2021-07-22 op va_list ap;
326 8d1b399b 2021-07-22 op char *msg;
327 8d1b399b 2021-07-22 op
328 8d1b399b 2021-07-22 op file->errors++;
329 8d1b399b 2021-07-22 op va_start(ap, fmt);
330 8d1b399b 2021-07-22 op if (vasprintf(&msg, fmt, ap) == -1)
331 8d1b399b 2021-07-22 op fatalx("yyerror vasprintf");
332 8d1b399b 2021-07-22 op va_end(ap);
333 8d1b399b 2021-07-22 op logit(LOG_CRIT, "%s:%d: %s", file->name, yylval.lineno, msg);
334 8d1b399b 2021-07-22 op free(msg);
335 8d1b399b 2021-07-22 op return 0;
336 8d1b399b 2021-07-22 op }
337 8d1b399b 2021-07-22 op
338 8d1b399b 2021-07-22 op int
339 8d1b399b 2021-07-22 op kw_cmp(const void *k, const void *e)
340 8d1b399b 2021-07-22 op {
341 8d1b399b 2021-07-22 op return strcmp(k, ((const struct keywords *)e)->k_name);
342 8d1b399b 2021-07-22 op }
343 8d1b399b 2021-07-22 op
344 8d1b399b 2021-07-22 op int
345 8d1b399b 2021-07-22 op lookup(char *s)
346 8d1b399b 2021-07-22 op {
347 8d1b399b 2021-07-22 op /* This has to be sorted always. */
348 8d1b399b 2021-07-22 op static const struct keywords keywords[] = {
349 8d1b399b 2021-07-22 op {"auth", AUTH},
350 8d1b399b 2021-07-22 op {"cert", CERT},
351 8d1b399b 2021-07-22 op {"include", INCLUDE},
352 8d1b399b 2021-07-22 op {"key", KEY},
353 8d1b399b 2021-07-22 op {"listen", LISTEN},
354 8d1b399b 2021-07-22 op {"no", NO},
355 8d1b399b 2021-07-22 op {"on", ON},
356 8d1b399b 2021-07-22 op {"pki", PKI},
357 8d1b399b 2021-07-22 op {"port", PORT},
358 8d1b399b 2021-07-22 op {"table", TABLE},
359 8d1b399b 2021-07-22 op {"tls", TLS},
360 c35679af 2021-12-18 op {"userdata", USERDATA},
361 c35679af 2021-12-18 op {"virtual", VIRTUAL},
362 8d1b399b 2021-07-22 op {"yes", YES},
363 8d1b399b 2021-07-22 op };
364 8d1b399b 2021-07-22 op const struct keywords *p;
365 8d1b399b 2021-07-22 op
366 8d1b399b 2021-07-22 op p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
367 8d1b399b 2021-07-22 op sizeof(keywords[0]), kw_cmp);
368 8d1b399b 2021-07-22 op
369 8d1b399b 2021-07-22 op if (p)
370 8d1b399b 2021-07-22 op return p->k_val;
371 8d1b399b 2021-07-22 op else
372 8d1b399b 2021-07-22 op return STRING;
373 8d1b399b 2021-07-22 op }
374 8d1b399b 2021-07-22 op
375 8d1b399b 2021-07-22 op #define START_EXPAND 1
376 8d1b399b 2021-07-22 op #define DONE_EXPAND 2
377 8d1b399b 2021-07-22 op
378 8d1b399b 2021-07-22 op static int expanding;
379 8d1b399b 2021-07-22 op
380 8d1b399b 2021-07-22 op int
381 8d1b399b 2021-07-22 op igetc(void)
382 8d1b399b 2021-07-22 op {
383 8d1b399b 2021-07-22 op int c;
384 8d1b399b 2021-07-22 op
385 8d1b399b 2021-07-22 op while (1) {
386 8d1b399b 2021-07-22 op if (file->ungetpos > 0)
387 8d1b399b 2021-07-22 op c = file->ungetbuf[--file->ungetpos];
388 8d1b399b 2021-07-22 op else
389 8d1b399b 2021-07-22 op c = getc(file->stream);
390 8d1b399b 2021-07-22 op
391 8d1b399b 2021-07-22 op if (c == START_EXPAND)
392 8d1b399b 2021-07-22 op expanding = 1;
393 8d1b399b 2021-07-22 op else if (c == DONE_EXPAND)
394 8d1b399b 2021-07-22 op expanding = 0;
395 8d1b399b 2021-07-22 op else
396 8d1b399b 2021-07-22 op break;
397 8d1b399b 2021-07-22 op }
398 8d1b399b 2021-07-22 op return c;
399 8d1b399b 2021-07-22 op }
400 8d1b399b 2021-07-22 op
401 8d1b399b 2021-07-22 op int
402 8d1b399b 2021-07-22 op lgetc(int quotec)
403 8d1b399b 2021-07-22 op {
404 8d1b399b 2021-07-22 op int c, next;
405 8d1b399b 2021-07-22 op
406 8d1b399b 2021-07-22 op if (quotec) {
407 8d1b399b 2021-07-22 op if ((c = igetc()) == EOF) {
408 8d1b399b 2021-07-22 op yyerror("reached end of file while parsing "
409 8d1b399b 2021-07-22 op "quoted string");
410 8d1b399b 2021-07-22 op if (file == topfile || popfile() == EOF)
411 8d1b399b 2021-07-22 op return EOF;
412 8d1b399b 2021-07-22 op return quotec;
413 8d1b399b 2021-07-22 op }
414 8d1b399b 2021-07-22 op return c;
415 8d1b399b 2021-07-22 op }
416 8d1b399b 2021-07-22 op
417 8d1b399b 2021-07-22 op while ((c = igetc()) == '\\') {
418 8d1b399b 2021-07-22 op next = igetc();
419 8d1b399b 2021-07-22 op if (next != '\n') {
420 8d1b399b 2021-07-22 op c = next;
421 8d1b399b 2021-07-22 op break;
422 8d1b399b 2021-07-22 op }
423 8d1b399b 2021-07-22 op yylval.lineno = file->lineno;
424 8d1b399b 2021-07-22 op file->lineno++;
425 8d1b399b 2021-07-22 op }
426 8d1b399b 2021-07-22 op
427 8d1b399b 2021-07-22 op if (c == EOF) {
428 8d1b399b 2021-07-22 op /*
429 8d1b399b 2021-07-22 op * Fake EOL when hit EOF for the first time. This gets line
430 8d1b399b 2021-07-22 op * count right if last line in included file is syntactically
431 8d1b399b 2021-07-22 op * invalid and has no newline.
432 8d1b399b 2021-07-22 op */
433 8d1b399b 2021-07-22 op if (file->eof_reached == 0) {
434 8d1b399b 2021-07-22 op file->eof_reached = 1;
435 8d1b399b 2021-07-22 op return '\n';
436 8d1b399b 2021-07-22 op }
437 8d1b399b 2021-07-22 op while (c == EOF) {
438 8d1b399b 2021-07-22 op if (file == topfile || popfile() == EOF)
439 8d1b399b 2021-07-22 op return EOF;
440 8d1b399b 2021-07-22 op c = igetc();
441 8d1b399b 2021-07-22 op }
442 8d1b399b 2021-07-22 op }
443 8d1b399b 2021-07-22 op return c;
444 8d1b399b 2021-07-22 op }
445 8d1b399b 2021-07-22 op
446 8d1b399b 2021-07-22 op void
447 8d1b399b 2021-07-22 op lungetc(int c)
448 8d1b399b 2021-07-22 op {
449 8d1b399b 2021-07-22 op if (c == EOF)
450 8d1b399b 2021-07-22 op return;
451 8d1b399b 2021-07-22 op
452 8d1b399b 2021-07-22 op if (file->ungetpos >= file->ungetsize) {
453 8d1b399b 2021-07-22 op void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
454 8d1b399b 2021-07-22 op if (p == NULL)
455 8d1b399b 2021-07-22 op err(1, "lungetc");
456 8d1b399b 2021-07-22 op file->ungetbuf = p;
457 8d1b399b 2021-07-22 op file->ungetsize *= 2;
458 8d1b399b 2021-07-22 op }
459 8d1b399b 2021-07-22 op file->ungetbuf[file->ungetpos++] = c;
460 8d1b399b 2021-07-22 op }
461 8d1b399b 2021-07-22 op
462 8d1b399b 2021-07-22 op int
463 8d1b399b 2021-07-22 op findeol(void)
464 8d1b399b 2021-07-22 op {
465 8d1b399b 2021-07-22 op int c;
466 8d1b399b 2021-07-22 op
467 8d1b399b 2021-07-22 op /* Skip to either EOF or the first real EOL. */
468 8d1b399b 2021-07-22 op while (1) {
469 8d1b399b 2021-07-22 op c = lgetc(0);
470 8d1b399b 2021-07-22 op if (c == '\n') {
471 8d1b399b 2021-07-22 op file->lineno++;
472 8d1b399b 2021-07-22 op break;
473 8d1b399b 2021-07-22 op }
474 8d1b399b 2021-07-22 op if (c == EOF)
475 8d1b399b 2021-07-22 op break;
476 8d1b399b 2021-07-22 op }
477 8d1b399b 2021-07-22 op return ERROR;
478 8d1b399b 2021-07-22 op }
479 ab51127d 2021-08-04 op
480 ab51127d 2021-08-04 op #if 0
481 ab51127d 2021-08-04 op int my_yylex(void);
482 8d1b399b 2021-07-22 op
483 8d1b399b 2021-07-22 op int
484 8d1b399b 2021-07-22 op yylex(void)
485 8d1b399b 2021-07-22 op {
486 ab51127d 2021-08-04 op int x;
487 ab51127d 2021-08-04 op
488 ab51127d 2021-08-04 op switch (x = my_yylex()) {
489 ab51127d 2021-08-04 op case AUTH:
490 ab51127d 2021-08-04 op puts("auth");
491 ab51127d 2021-08-04 op break;
492 ab51127d 2021-08-04 op case CERT:
493 ab51127d 2021-08-04 op puts("cert");
494 ab51127d 2021-08-04 op break;
495 ab51127d 2021-08-04 op case ERROR:
496 ab51127d 2021-08-04 op puts("error");
497 ab51127d 2021-08-04 op break;
498 ab51127d 2021-08-04 op case INCLUDE:
499 ab51127d 2021-08-04 op puts("include");
500 ab51127d 2021-08-04 op break;
501 ab51127d 2021-08-04 op case KEY:
502 ab51127d 2021-08-04 op puts("key");
503 ab51127d 2021-08-04 op break;
504 ab51127d 2021-08-04 op case LISTEN:
505 ab51127d 2021-08-04 op puts("listen");
506 ab51127d 2021-08-04 op break;
507 ab51127d 2021-08-04 op case NO:
508 ab51127d 2021-08-04 op puts("no");
509 ab51127d 2021-08-04 op break;
510 ab51127d 2021-08-04 op case ON:
511 ab51127d 2021-08-04 op puts("on");
512 ab51127d 2021-08-04 op break;
513 ab51127d 2021-08-04 op case PKI:
514 ab51127d 2021-08-04 op puts("pki");
515 ab51127d 2021-08-04 op break;
516 ab51127d 2021-08-04 op case PORT:
517 ab51127d 2021-08-04 op puts("port");
518 ab51127d 2021-08-04 op break;
519 ab51127d 2021-08-04 op case TABLE:
520 ab51127d 2021-08-04 op puts("table");
521 ab51127d 2021-08-04 op break;
522 ab51127d 2021-08-04 op case TLS:
523 ab51127d 2021-08-04 op puts("tls");
524 ab51127d 2021-08-04 op break;
525 ab51127d 2021-08-04 op case YES:
526 ab51127d 2021-08-04 op puts("yes");
527 ab51127d 2021-08-04 op break;
528 ab51127d 2021-08-04 op case STRING:
529 ab51127d 2021-08-04 op printf("string \"%s\"\n", yylval.v.string);
530 ab51127d 2021-08-04 op break;
531 ab51127d 2021-08-04 op case NUMBER:
532 ab51127d 2021-08-04 op printf("number %"PRIi64"\n", yylval.v.number);
533 ab51127d 2021-08-04 op default:
534 ab51127d 2021-08-04 op printf("character ");
535 ab51127d 2021-08-04 op if (x == '\n')
536 ab51127d 2021-08-04 op printf("\\n");
537 ab51127d 2021-08-04 op else
538 ab51127d 2021-08-04 op printf("%c", x);
539 ab51127d 2021-08-04 op printf(" [0x%x]", x);
540 ab51127d 2021-08-04 op printf("\n");
541 ab51127d 2021-08-04 op break;
542 ab51127d 2021-08-04 op }
543 ab51127d 2021-08-04 op
544 ab51127d 2021-08-04 op return x;
545 ab51127d 2021-08-04 op }
546 ab51127d 2021-08-04 op
547 ab51127d 2021-08-04 op int
548 ab51127d 2021-08-04 op my_yylex(void)
549 ab51127d 2021-08-04 op #else
550 ab51127d 2021-08-04 op int
551 ab51127d 2021-08-04 op yylex(void)
552 ab51127d 2021-08-04 op #endif
553 ab51127d 2021-08-04 op {
554 e63bf1fb 2021-11-30 op char buf[8096];
555 e63bf1fb 2021-11-30 op char *p, *val;
556 e63bf1fb 2021-11-30 op int quotec, next, c;
557 e63bf1fb 2021-11-30 op int token;
558 8d1b399b 2021-07-22 op
559 8d1b399b 2021-07-22 op top:
560 8d1b399b 2021-07-22 op p = buf;
561 8d1b399b 2021-07-22 op while ((c = lgetc(0)) == ' ' || c == '\t')
562 8d1b399b 2021-07-22 op ; /* nothing */
563 8d1b399b 2021-07-22 op
564 8d1b399b 2021-07-22 op yylval.lineno = file->lineno;
565 8d1b399b 2021-07-22 op if (c == '#')
566 8d1b399b 2021-07-22 op while ((c = lgetc(0)) != '\n' && c != EOF)
567 8d1b399b 2021-07-22 op ; /* nothing */
568 8d1b399b 2021-07-22 op if (c == '$' && !expanding) {
569 8d1b399b 2021-07-22 op while (1) {
570 8d1b399b 2021-07-22 op if ((c = lgetc(0)) == EOF)
571 8d1b399b 2021-07-22 op return 0;
572 8d1b399b 2021-07-22 op
573 8d1b399b 2021-07-22 op if (p + 1 >= buf + sizeof(buf) - 1) {
574 8d1b399b 2021-07-22 op yyerror("string too long");
575 8d1b399b 2021-07-22 op return findeol();
576 8d1b399b 2021-07-22 op }
577 8d1b399b 2021-07-22 op if (isalnum(c) || c == '_') {
578 8d1b399b 2021-07-22 op *p++ = c;
579 8d1b399b 2021-07-22 op continue;
580 8d1b399b 2021-07-22 op }
581 8d1b399b 2021-07-22 op *p = '\0';
582 8d1b399b 2021-07-22 op lungetc(c);
583 8d1b399b 2021-07-22 op break;
584 8d1b399b 2021-07-22 op }
585 8d1b399b 2021-07-22 op val = symget(buf);
586 8d1b399b 2021-07-22 op if (val == NULL) {
587 8d1b399b 2021-07-22 op yyerror("macro '%s' not defined", buf);
588 8d1b399b 2021-07-22 op return findeol();
589 8d1b399b 2021-07-22 op }
590 8d1b399b 2021-07-22 op p = val + strlen(val) - 1;
591 8d1b399b 2021-07-22 op lungetc(DONE_EXPAND);
592 8d1b399b 2021-07-22 op while (p >= val) {
593 e63bf1fb 2021-11-30 op lungetc((unsigned char)*p);
594 8d1b399b 2021-07-22 op p--;
595 8d1b399b 2021-07-22 op }
596 8d1b399b 2021-07-22 op lungetc(START_EXPAND);
597 8d1b399b 2021-07-22 op goto top;
598 8d1b399b 2021-07-22 op }
599 8d1b399b 2021-07-22 op
600 8d1b399b 2021-07-22 op switch (c) {
601 8d1b399b 2021-07-22 op case '\'':
602 8d1b399b 2021-07-22 op case '"':
603 8d1b399b 2021-07-22 op quotec = c;
604 8d1b399b 2021-07-22 op while (1) {
605 8d1b399b 2021-07-22 op if ((c = lgetc(quotec)) == EOF)
606 8d1b399b 2021-07-22 op return 0;
607 8d1b399b 2021-07-22 op if (c == '\n') {
608 8d1b399b 2021-07-22 op file->lineno++;
609 8d1b399b 2021-07-22 op continue;
610 8d1b399b 2021-07-22 op } else if (c == '\\') {
611 8d1b399b 2021-07-22 op if ((next = lgetc(quotec)) == EOF)
612 8d1b399b 2021-07-22 op return (0);
613 8d1b399b 2021-07-22 op if (next == quotec || next == ' ' ||
614 8d1b399b 2021-07-22 op next == '\t')
615 8d1b399b 2021-07-22 op c = next;
616 8d1b399b 2021-07-22 op else if (next == '\n') {
617 8d1b399b 2021-07-22 op file->lineno++;
618 8d1b399b 2021-07-22 op continue;
619 8d1b399b 2021-07-22 op } else
620 8d1b399b 2021-07-22 op lungetc(next);
621 8d1b399b 2021-07-22 op } else if (c == quotec) {
622 8d1b399b 2021-07-22 op *p = '\0';
623 8d1b399b 2021-07-22 op break;
624 8d1b399b 2021-07-22 op } else if (c == '\0') {
625 8d1b399b 2021-07-22 op yyerror("syntax error");
626 8d1b399b 2021-07-22 op return findeol();
627 8d1b399b 2021-07-22 op }
628 8d1b399b 2021-07-22 op if (p + 1 >= buf + sizeof(buf) - 1) {
629 8d1b399b 2021-07-22 op yyerror("string too long");
630 8d1b399b 2021-07-22 op return findeol();
631 8d1b399b 2021-07-22 op }
632 8d1b399b 2021-07-22 op *p++ = c;
633 8d1b399b 2021-07-22 op }
634 8d1b399b 2021-07-22 op yylval.v.string = strdup(buf);
635 8d1b399b 2021-07-22 op if (yylval.v.string == NULL)
636 8d1b399b 2021-07-22 op err(1, "yylex: strdup");
637 8d1b399b 2021-07-22 op return STRING;
638 8d1b399b 2021-07-22 op }
639 8d1b399b 2021-07-22 op
640 8d1b399b 2021-07-22 op #define allowed_to_end_number(x) \
641 8d1b399b 2021-07-22 op (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
642 8d1b399b 2021-07-22 op
643 8d1b399b 2021-07-22 op if (c == '-' || isdigit(c)) {
644 8d1b399b 2021-07-22 op do {
645 8d1b399b 2021-07-22 op *p++ = c;
646 8d1b399b 2021-07-22 op if ((size_t)(p-buf) >= sizeof(buf)) {
647 8d1b399b 2021-07-22 op yyerror("string too long");
648 8d1b399b 2021-07-22 op return findeol();
649 8d1b399b 2021-07-22 op }
650 8d1b399b 2021-07-22 op } while ((c = lgetc(0)) != EOF && isdigit(c));
651 8d1b399b 2021-07-22 op lungetc(c);
652 8d1b399b 2021-07-22 op if (p == buf + 1 && buf[0] == '-')
653 8d1b399b 2021-07-22 op goto nodigits;
654 8d1b399b 2021-07-22 op if (c == EOF || allowed_to_end_number(c)) {
655 8d1b399b 2021-07-22 op const char *errstr = NULL;
656 8d1b399b 2021-07-22 op
657 8d1b399b 2021-07-22 op *p = '\0';
658 8d1b399b 2021-07-22 op yylval.v.number = strtonum(buf, LLONG_MIN,
659 8d1b399b 2021-07-22 op LLONG_MAX, &errstr);
660 8d1b399b 2021-07-22 op if (errstr) {
661 8d1b399b 2021-07-22 op yyerror("\"%s\" invalid number: %s",
662 8d1b399b 2021-07-22 op buf, errstr);
663 8d1b399b 2021-07-22 op return findeol();
664 8d1b399b 2021-07-22 op }
665 8d1b399b 2021-07-22 op return NUMBER;
666 8d1b399b 2021-07-22 op } else {
667 8d1b399b 2021-07-22 op nodigits:
668 8d1b399b 2021-07-22 op while (p > buf + 1)
669 e63bf1fb 2021-11-30 op lungetc((unsigned char)*--p);
670 e63bf1fb 2021-11-30 op c = (unsigned char)*--p;
671 8d1b399b 2021-07-22 op if (c == '-')
672 8d1b399b 2021-07-22 op return c;
673 8d1b399b 2021-07-22 op }
674 8d1b399b 2021-07-22 op }
675 8d1b399b 2021-07-22 op
676 8d1b399b 2021-07-22 op #define allowed_in_string(x) \
677 8d1b399b 2021-07-22 op (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
678 8d1b399b 2021-07-22 op x != '{' && x != '}' && \
679 8d1b399b 2021-07-22 op x != '!' && x != '=' && x != '#' && \
680 afb31195 2021-08-04 op x != ',' && x != '>'))
681 8d1b399b 2021-07-22 op
682 8d1b399b 2021-07-22 op if (isalnum(c) || c == ':' || c == '_') {
683 8d1b399b 2021-07-22 op do {
684 8d1b399b 2021-07-22 op *p++ = c;
685 8d1b399b 2021-07-22 op if ((size_t)(p-buf) >= sizeof(buf)) {
686 8d1b399b 2021-07-22 op yyerror("string too long");
687 8d1b399b 2021-07-22 op return findeol();
688 8d1b399b 2021-07-22 op }
689 8d1b399b 2021-07-22 op } while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
690 8d1b399b 2021-07-22 op lungetc(c);
691 8d1b399b 2021-07-22 op *p = '\0';
692 8d1b399b 2021-07-22 op if ((token = lookup(buf)) == STRING)
693 8d1b399b 2021-07-22 op if ((yylval.v.string = strdup(buf)) == NULL)
694 8d1b399b 2021-07-22 op err(1, "yylex: strdup");
695 8d1b399b 2021-07-22 op return token;
696 8d1b399b 2021-07-22 op }
697 8d1b399b 2021-07-22 op if (c == '\n') {
698 8d1b399b 2021-07-22 op yylval.lineno = file->lineno;
699 8d1b399b 2021-07-22 op file->lineno++;
700 8d1b399b 2021-07-22 op }
701 8d1b399b 2021-07-22 op if (c == EOF)
702 8d1b399b 2021-07-22 op return 0;
703 8d1b399b 2021-07-22 op return c;
704 8d1b399b 2021-07-22 op }
705 8d1b399b 2021-07-22 op
706 8d1b399b 2021-07-22 op int
707 8d1b399b 2021-07-22 op check_file_secrecy(int fd, const char *fname)
708 8d1b399b 2021-07-22 op {
709 8d1b399b 2021-07-22 op struct stat st;
710 8d1b399b 2021-07-22 op
711 8d1b399b 2021-07-22 op if (fstat(fd, &st)) {
712 8d1b399b 2021-07-22 op log_warn("cannot stat %s", fname);
713 8d1b399b 2021-07-22 op return -1;
714 8d1b399b 2021-07-22 op }
715 8d1b399b 2021-07-22 op if (st.st_uid != 0 && st.st_uid != getuid()) {
716 8d1b399b 2021-07-22 op log_warnx("%s: owner not root or current user", fname);
717 8d1b399b 2021-07-22 op return -1;
718 8d1b399b 2021-07-22 op }
719 8d1b399b 2021-07-22 op if (st.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)) {
720 8d1b399b 2021-07-22 op log_warnx("%s: group writable or world read/writable", fname);
721 8d1b399b 2021-07-22 op return -1;
722 8d1b399b 2021-07-22 op }
723 8d1b399b 2021-07-22 op return 0;
724 8d1b399b 2021-07-22 op }
725 8d1b399b 2021-07-22 op
726 8d1b399b 2021-07-22 op struct file *
727 8d1b399b 2021-07-22 op pushfile(const char *name, int secret)
728 8d1b399b 2021-07-22 op {
729 8d1b399b 2021-07-22 op struct file *nfile;
730 8d1b399b 2021-07-22 op
731 8d1b399b 2021-07-22 op if ((nfile = calloc(1, sizeof(struct file))) == NULL) {
732 8d1b399b 2021-07-22 op log_warn("calloc");
733 8d1b399b 2021-07-22 op return NULL;
734 8d1b399b 2021-07-22 op }
735 8d1b399b 2021-07-22 op if ((nfile->name = strdup(name)) == NULL) {
736 8d1b399b 2021-07-22 op log_warn("strdup");
737 8d1b399b 2021-07-22 op free(nfile);
738 8d1b399b 2021-07-22 op return NULL;
739 8d1b399b 2021-07-22 op }
740 8d1b399b 2021-07-22 op if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
741 8d1b399b 2021-07-22 op log_warn("%s", nfile->name);
742 8d1b399b 2021-07-22 op free(nfile->name);
743 8d1b399b 2021-07-22 op free(nfile);
744 8d1b399b 2021-07-22 op return NULL;
745 8d1b399b 2021-07-22 op } else if (secret &&
746 8d1b399b 2021-07-22 op check_file_secrecy(fileno(nfile->stream), nfile->name)) {
747 8d1b399b 2021-07-22 op fclose(nfile->stream);
748 8d1b399b 2021-07-22 op free(nfile->name);
749 8d1b399b 2021-07-22 op free(nfile);
750 8d1b399b 2021-07-22 op return NULL;
751 8d1b399b 2021-07-22 op }
752 8d1b399b 2021-07-22 op nfile->lineno = TAILQ_EMPTY(&files) ? 1 : 0;
753 8d1b399b 2021-07-22 op nfile->ungetsize = 16;
754 8d1b399b 2021-07-22 op nfile->ungetbuf = malloc(nfile->ungetsize);
755 8d1b399b 2021-07-22 op if (nfile->ungetbuf == NULL) {
756 8d1b399b 2021-07-22 op log_warn("malloc");
757 8d1b399b 2021-07-22 op fclose(nfile->stream);
758 8d1b399b 2021-07-22 op free(nfile->name);
759 8d1b399b 2021-07-22 op free(nfile);
760 8d1b399b 2021-07-22 op return NULL;
761 8d1b399b 2021-07-22 op }
762 8d1b399b 2021-07-22 op TAILQ_INSERT_TAIL(&files, nfile, entry);
763 8d1b399b 2021-07-22 op return nfile;
764 8d1b399b 2021-07-22 op }
765 8d1b399b 2021-07-22 op
766 8d1b399b 2021-07-22 op int
767 8d1b399b 2021-07-22 op popfile(void)
768 8d1b399b 2021-07-22 op {
769 8d1b399b 2021-07-22 op struct file *prev;
770 8d1b399b 2021-07-22 op
771 8d1b399b 2021-07-22 op if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
772 8d1b399b 2021-07-22 op prev->errors += file->errors;
773 8d1b399b 2021-07-22 op
774 8d1b399b 2021-07-22 op TAILQ_REMOVE(&files, file, entry);
775 8d1b399b 2021-07-22 op fclose(file->stream);
776 8d1b399b 2021-07-22 op free(file->name);
777 8d1b399b 2021-07-22 op free(file->ungetbuf);
778 8d1b399b 2021-07-22 op free(file);
779 8d1b399b 2021-07-22 op file = prev;
780 8d1b399b 2021-07-22 op return file ? 0 : EOF;
781 8d1b399b 2021-07-22 op }
782 8d1b399b 2021-07-22 op
783 8d1b399b 2021-07-22 op struct kd_conf *
784 8d1b399b 2021-07-22 op parse_config(const char *filename)
785 8d1b399b 2021-07-22 op {
786 8d1b399b 2021-07-22 op struct sym *sym, *next;
787 8d1b399b 2021-07-22 op
788 8d1b399b 2021-07-22 op counter = 0;
789 8d1b399b 2021-07-22 op conf = config_new_empty();
790 8d1b399b 2021-07-22 op
791 8d1b399b 2021-07-22 op file = pushfile(filename, 0);
792 8d1b399b 2021-07-22 op if (file == NULL) {
793 8d1b399b 2021-07-22 op free(conf);
794 8d1b399b 2021-07-22 op return NULL;
795 8d1b399b 2021-07-22 op }
796 8d1b399b 2021-07-22 op topfile = file;
797 8d1b399b 2021-07-22 op
798 8d1b399b 2021-07-22 op yyparse();
799 8d1b399b 2021-07-22 op errors = file->errors;
800 8d1b399b 2021-07-22 op popfile();
801 8d1b399b 2021-07-22 op
802 8d1b399b 2021-07-22 op /* Free macros and check which have not been used. */
803 8d1b399b 2021-07-22 op TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) {
804 8d1b399b 2021-07-22 op if (verbose && !sym->used)
805 8d1b399b 2021-07-22 op fprintf(stderr, "warning: macro '%s' not used\n",
806 8d1b399b 2021-07-22 op sym->nam);
807 8d1b399b 2021-07-22 op if (!sym->persist) {
808 8d1b399b 2021-07-22 op free(sym->nam);
809 8d1b399b 2021-07-22 op free(sym->val);
810 8d1b399b 2021-07-22 op TAILQ_REMOVE(&symhead, sym, entry);
811 8d1b399b 2021-07-22 op free(sym);
812 8d1b399b 2021-07-22 op }
813 8d1b399b 2021-07-22 op }
814 8d1b399b 2021-07-22 op
815 8d1b399b 2021-07-22 op if (errors) {
816 8d1b399b 2021-07-22 op clear_config(conf);
817 8d1b399b 2021-07-22 op return NULL;
818 8d1b399b 2021-07-22 op }
819 8d1b399b 2021-07-22 op
820 8d1b399b 2021-07-22 op return conf;
821 8d1b399b 2021-07-22 op }
822 8d1b399b 2021-07-22 op
823 8d1b399b 2021-07-22 op int
824 8d1b399b 2021-07-22 op symset(const char *nam, const char *val, int persist)
825 8d1b399b 2021-07-22 op {
826 8d1b399b 2021-07-22 op struct sym *sym;
827 8d1b399b 2021-07-22 op
828 8d1b399b 2021-07-22 op TAILQ_FOREACH(sym, &symhead, entry) {
829 8d1b399b 2021-07-22 op if (strcmp(nam, sym->nam) == 0)
830 8d1b399b 2021-07-22 op break;
831 8d1b399b 2021-07-22 op }
832 8d1b399b 2021-07-22 op
833 8d1b399b 2021-07-22 op if (sym != NULL) {
834 8d1b399b 2021-07-22 op if (sym->persist == 1)
835 8d1b399b 2021-07-22 op return 0;
836 8d1b399b 2021-07-22 op else {
837 8d1b399b 2021-07-22 op free(sym->nam);
838 8d1b399b 2021-07-22 op free(sym->val);
839 8d1b399b 2021-07-22 op TAILQ_REMOVE(&symhead, sym, entry);
840 8d1b399b 2021-07-22 op free(sym);
841 8d1b399b 2021-07-22 op }
842 8d1b399b 2021-07-22 op }
843 8d1b399b 2021-07-22 op if ((sym = calloc(1, sizeof(*sym))) == NULL)
844 8d1b399b 2021-07-22 op return -1;
845 8d1b399b 2021-07-22 op
846 8d1b399b 2021-07-22 op sym->nam = strdup(nam);
847 8d1b399b 2021-07-22 op if (sym->nam == NULL) {
848 8d1b399b 2021-07-22 op free(sym);
849 8d1b399b 2021-07-22 op return -1;
850 8d1b399b 2021-07-22 op }
851 8d1b399b 2021-07-22 op sym->val = strdup(val);
852 8d1b399b 2021-07-22 op if (sym->val == NULL) {
853 8d1b399b 2021-07-22 op free(sym->nam);
854 8d1b399b 2021-07-22 op free(sym);
855 8d1b399b 2021-07-22 op return -1;
856 8d1b399b 2021-07-22 op }
857 8d1b399b 2021-07-22 op sym->used = 0;
858 8d1b399b 2021-07-22 op sym->persist = persist;
859 8d1b399b 2021-07-22 op TAILQ_INSERT_TAIL(&symhead, sym, entry);
860 8d1b399b 2021-07-22 op return 0;
861 8d1b399b 2021-07-22 op }
862 8d1b399b 2021-07-22 op
863 8d1b399b 2021-07-22 op int
864 8d1b399b 2021-07-22 op cmdline_symset(char *s)
865 8d1b399b 2021-07-22 op {
866 8d1b399b 2021-07-22 op char *sym, *val;
867 8d1b399b 2021-07-22 op int ret;
868 8d1b399b 2021-07-22 op
869 8d1b399b 2021-07-22 op if ((val = strrchr(s, '=')) == NULL)
870 8d1b399b 2021-07-22 op return -1;
871 8d1b399b 2021-07-22 op sym = strndup(s, val - s);
872 8d1b399b 2021-07-22 op if (sym == NULL)
873 8d1b399b 2021-07-22 op errx(1, "%s: strndup", __func__);
874 8d1b399b 2021-07-22 op ret = symset(sym, val + 1, 1);
875 8d1b399b 2021-07-22 op free(sym);
876 8d1b399b 2021-07-22 op
877 8d1b399b 2021-07-22 op return ret;
878 8d1b399b 2021-07-22 op }
879 8d1b399b 2021-07-22 op
880 8d1b399b 2021-07-22 op char *
881 8d1b399b 2021-07-22 op symget(const char *nam)
882 8d1b399b 2021-07-22 op {
883 8d1b399b 2021-07-22 op struct sym *sym;
884 8d1b399b 2021-07-22 op
885 8d1b399b 2021-07-22 op TAILQ_FOREACH(sym, &symhead, entry) {
886 8d1b399b 2021-07-22 op if (strcmp(nam, sym->nam) == 0) {
887 8d1b399b 2021-07-22 op sym->used = 1;
888 8d1b399b 2021-07-22 op return sym->val;
889 8d1b399b 2021-07-22 op }
890 8d1b399b 2021-07-22 op }
891 8d1b399b 2021-07-22 op return NULL;
892 8d1b399b 2021-07-22 op }
893 8d1b399b 2021-07-22 op
894 8d1b399b 2021-07-22 op void
895 8d1b399b 2021-07-22 op clear_config(struct kd_conf *xconf)
896 8d1b399b 2021-07-22 op {
897 8d1b399b 2021-07-22 op /* free stuff? */
898 8d1b399b 2021-07-22 op
899 8d1b399b 2021-07-22 op free(xconf);
900 8d1b399b 2021-07-22 op }
901 8d1b399b 2021-07-22 op
902 8d1b399b 2021-07-22 op static void
903 8d1b399b 2021-07-22 op add_table(const char *name, const char *type, const char *path)
904 8d1b399b 2021-07-22 op {
905 8d1b399b 2021-07-22 op if (table_open(conf, name, type, path) == -1)
906 8d1b399b 2021-07-22 op yyerror("can't initialize table %s", name);
907 c25feded 2021-07-26 op table = STAILQ_FIRST(&conf->table_head)->table;
908 8d1b399b 2021-07-22 op }
909 8d1b399b 2021-07-22 op
910 8d1b399b 2021-07-22 op static struct table *
911 8d1b399b 2021-07-22 op findtable(const char *name)
912 8d1b399b 2021-07-22 op {
913 8d1b399b 2021-07-22 op struct kd_tables_conf *i;
914 8d1b399b 2021-07-22 op
915 c25feded 2021-07-26 op STAILQ_FOREACH(i, &conf->table_head, entry) {
916 8d1b399b 2021-07-22 op if (!strcmp(i->table->t_name, name))
917 8d1b399b 2021-07-22 op return i->table;
918 8d1b399b 2021-07-22 op }
919 8d1b399b 2021-07-22 op
920 8d1b399b 2021-07-22 op yyerror("unknown table %s", name);
921 8d1b399b 2021-07-22 op return NULL;
922 8d1b399b 2021-07-22 op }
923 8d1b399b 2021-07-22 op
924 8d1b399b 2021-07-22 op static void
925 8d1b399b 2021-07-22 op add_cert(const char *name, const char *path)
926 8d1b399b 2021-07-22 op {
927 8d1b399b 2021-07-22 op struct kd_pki_conf *pki;
928 8d1b399b 2021-07-22 op
929 c25feded 2021-07-26 op STAILQ_FOREACH(pki, &conf->pki_head, entry) {
930 8d1b399b 2021-07-22 op if (strcmp(name, pki->name) != 0)
931 8d1b399b 2021-07-22 op continue;
932 8d1b399b 2021-07-22 op
933 8d1b399b 2021-07-22 op if (pki->cert != NULL) {
934 8d1b399b 2021-07-22 op yyerror("duplicate `pki %s cert'", name);
935 8d1b399b 2021-07-22 op return;
936 8d1b399b 2021-07-22 op }
937 8d1b399b 2021-07-22 op
938 8d1b399b 2021-07-22 op goto set;
939 8d1b399b 2021-07-22 op }
940 8d1b399b 2021-07-22 op
941 8d1b399b 2021-07-22 op pki = xcalloc(1, sizeof(*pki));
942 8d1b399b 2021-07-22 op strlcpy(pki->name, name, sizeof(pki->name));
943 c25feded 2021-07-26 op STAILQ_INSERT_HEAD(&conf->pki_head, pki, entry);
944 8d1b399b 2021-07-22 op
945 8d1b399b 2021-07-22 op set:
946 8d1b399b 2021-07-22 op if ((pki->cert = tls_load_file(path, &pki->certlen, NULL)) == NULL)
947 8d1b399b 2021-07-22 op fatal(NULL);
948 8d1b399b 2021-07-22 op }
949 8d1b399b 2021-07-22 op
950 8d1b399b 2021-07-22 op static void
951 8d1b399b 2021-07-22 op add_key(const char *name, const char *path)
952 8d1b399b 2021-07-22 op {
953 8d1b399b 2021-07-22 op struct kd_pki_conf *pki;
954 8d1b399b 2021-07-22 op
955 c25feded 2021-07-26 op STAILQ_FOREACH(pki, &conf->pki_head, entry) {
956 8d1b399b 2021-07-22 op if (strcmp(name, pki->name) != 0)
957 8d1b399b 2021-07-22 op continue;
958 8d1b399b 2021-07-22 op
959 8d1b399b 2021-07-22 op if (pki->key != NULL) {
960 8d1b399b 2021-07-22 op yyerror("duplicate `pki %s key'", name);
961 8d1b399b 2021-07-22 op return;
962 8d1b399b 2021-07-22 op }
963 8d1b399b 2021-07-22 op
964 8d1b399b 2021-07-22 op goto set;
965 8d1b399b 2021-07-22 op }
966 8d1b399b 2021-07-22 op
967 8d1b399b 2021-07-22 op pki = xcalloc(1, sizeof(*pki));
968 8d1b399b 2021-07-22 op strlcpy(pki->name, name, sizeof(pki->name));
969 c25feded 2021-07-26 op STAILQ_INSERT_HEAD(&conf->pki_head, pki, entry);
970 8d1b399b 2021-07-22 op
971 8d1b399b 2021-07-22 op set:
972 8d1b399b 2021-07-22 op if ((pki->key = tls_load_file(path, &pki->keylen, NULL)) == NULL)
973 8d1b399b 2021-07-22 op fatal(NULL);
974 8d1b399b 2021-07-22 op }
975 8d1b399b 2021-07-22 op
976 d82b9f6d 2021-07-22 op static struct kd_listen_conf *
977 d82b9f6d 2021-07-22 op listen_new(void)
978 8d1b399b 2021-07-22 op {
979 8d1b399b 2021-07-22 op struct kd_listen_conf *l;
980 8d1b399b 2021-07-22 op
981 8d1b399b 2021-07-22 op l = xcalloc(1, sizeof(*l));
982 8d1b399b 2021-07-22 op l->id = counter++;
983 8d1b399b 2021-07-22 op l->fd = -1;
984 8d1b399b 2021-07-22 op
985 c25feded 2021-07-26 op STAILQ_INSERT_HEAD(&conf->listen_head, l, entry);
986 d82b9f6d 2021-07-22 op return l;
987 8d1b399b 2021-07-22 op }