GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/acme-client/parse.c Lines: 0 236 0.0 %
Date: 2017-11-07 Branches: 0 225 0.0 %

Line Branch Exec Source
1
#include <stdlib.h>
2
#include <string.h>
3
#define YYBYACC 1
4
#define YYMAJOR 1
5
#define YYMINOR 9
6
#define YYLEX yylex()
7
#define YYEMPTY -1
8
#define yyclearin (yychar=(YYEMPTY))
9
#define yyerrok (yyerrflag=0)
10
#define YYRECOVERING() (yyerrflag!=0)
11
#define YYPREFIX "yy"
12
#line 27 "parse.y"
13
#include <sys/types.h>
14
#include <sys/queue.h>
15
#include <sys/stat.h>
16
#include <ctype.h>
17
#include <err.h>
18
#include <limits.h>
19
#include <stdarg.h>
20
#include <stdio.h>
21
#include <stdlib.h>
22
#include <string.h>
23
#include <unistd.h>
24
25
#include "parse.h"
26
27
TAILQ_HEAD(files, file)		 files = TAILQ_HEAD_INITIALIZER(files);
28
static struct file {
29
	TAILQ_ENTRY(file)	 entry;
30
	FILE			*stream;
31
	char			*name;
32
	int			 lineno;
33
	int			 errors;
34
} *file, *topfile;
35
struct file	*pushfile(const char *);
36
int		 popfile(void);
37
int		 yyparse(void);
38
int		 yylex(void);
39
int		 yyerror(const char *, ...)
40
    __attribute__((__format__ (printf, 1, 2)))
41
    __attribute__((__nonnull__ (1)));
42
int		 kw_cmp(const void *, const void *);
43
int		 lookup(char *);
44
int		 lgetc(int);
45
int		 lungetc(int);
46
int		 findeol(void);
47
48
struct authority_c	*conf_new_authority(struct acme_conf *, char *);
49
struct domain_c		*conf_new_domain(struct acme_conf *, char *);
50
struct keyfile		*conf_new_keyfile(struct acme_conf *, char *);
51
void			 clear_config(struct acme_conf *);
52
void			 print_config(struct acme_conf *);
53
int			 conf_check_file(char *, int);
54
55
TAILQ_HEAD(symhead, sym)	 symhead = TAILQ_HEAD_INITIALIZER(symhead);
56
struct sym {
57
	TAILQ_ENTRY(sym)	 entry;
58
	int			 used;
59
	int			 persist;
60
	char			*nam;
61
	char			*val;
62
};
63
int		 symset(const char *, const char *, int);
64
char		*symget(const char *);
65
66
static struct acme_conf		*conf;
67
static struct authority_c	*auth;
68
static struct domain_c		*domain;
69
static int			 errors = 0;
70
71
typedef struct {
72
	union {
73
		int64_t		 number;
74
		char		*string;
75
	} v;
76
	int lineno;
77
} YYSTYPE;
78
79
#line 80 "parse.c"
80
#define AUTHORITY 257
81
#define AGREEMENT 258
82
#define URL 259
83
#define API 260
84
#define ACCOUNT 261
85
#define DOMAIN 262
86
#define ALTERNATIVE 263
87
#define NAMES 264
88
#define CERT 265
89
#define FULL 266
90
#define CHAIN 267
91
#define KEY 268
92
#define SIGN 269
93
#define WITH 270
94
#define CHALLENGEDIR 271
95
#define YES 272
96
#define NO 273
97
#define INCLUDE 274
98
#define ERROR 275
99
#define STRING 276
100
#define NUMBER 277
101
#define YYERRCODE 256
102
const short yylhs[] =
103
	{                                        -1,
104
    0,    0,    0,    0,    0,    0,    0,    2,    1,    1,
105
    3,    6,    6,    7,    8,    8,    9,    4,   10,   10,
106
   11,   11,   11,   12,    5,   13,   13,   14,   14,   14,
107
   14,   14,   14,   14,   15,   15,   16,
108
};
109
const short yylen[] =
110
	{                                         2,
111
    0,    3,    3,    2,    3,    3,    3,    2,    2,    1,
112
    3,    2,    0,    2,    1,    0,    0,    7,    3,    2,
113
    3,    3,    3,    0,    7,    3,    2,    5,    3,    3,
114
    4,    5,    3,    2,    3,    1,    1,
115
};
116
const short yydefred[] =
117
	{                                      1,
118
    0,    0,    0,    0,    0,    0,    4,    0,    0,    0,
119
    0,    7,   17,   24,    8,    0,    2,    3,    5,    6,
120
    0,    0,   10,    0,    0,    0,    9,    0,    0,    0,
121
   12,    0,    0,    0,    0,    0,    0,    0,    0,    0,
122
    0,    0,    0,    0,    0,   18,    0,   20,    0,    0,
123
    0,    0,    0,    0,   34,   25,    0,   27,   21,   22,
124
   23,    0,   19,   30,    0,    0,   29,    0,   33,   26,
125
   14,    0,   31,   37,    0,    0,   32,   28,   15,    0,
126
   35,
127
};
128
const short yydgoto[] =
129
	{                                       1,
130
   24,    8,    9,   10,   11,   29,   63,   80,   21,   35,
131
   36,   22,   41,   42,   75,   76,
132
};
133
const short yysindex[] =
134
	{                                      0,
135
  -10,   -7, -269, -266, -265,  -43,    0,   22,   25,   26,
136
   27,    0,    0,    0,    0, -238,    0,    0,    0,    0,
137
  -84,  -82,    0, -234,   33,   33,    0,   33, -231, -254,
138
    0, -215, -214, -222, -103,   33, -242, -217, -221, -228,
139
 -120,   33, -226, -225, -224,    0,   43,    0, -220, -213,
140
 -210, -219,  -65, -216,    0,    0,   43,    0,    0,    0,
141
    0,   33,    0,    0, -206, -212,    0, -211,    0,    0,
142
    0, -209,    0,    0,  -64,   18,    0,    0,    0, -211,
143
    0,};
144
const short yyrindex[] =
145
	{                                      0,
146
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
147
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
148
    0,    0,    0,   53, -227, -250,    0, -123,    0,    0,
149
    0,    0,    0,    0,    0,  -97,    0,    0,    0,    0,
150
    0, -109,    0,    0,    0,    0,    0,    0,    0,    0,
151
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
152
    0, -123,    0,    0,    0,    0,    0,    0,    0,    0,
153
    0,    0,    0,    0,    0, -124,    0,    0,    0,    0,
154
    0,};
155
const short yygindex[] =
156
	{                                      0,
157
    0,    0,    0,    0,    0,  -22,    9,    0,    0,    0,
158
   34,    0,    0,   29,  -12,    0,
159
};
160
#define YYTABLESIZE 266
161
const short yytable[] =
162
	{                                       7,
163
   36,   13,   12,   30,   56,   31,   13,   37,   38,   14,
164
   15,   13,   13,   48,   39,   13,   40,   16,   13,   58,
165
   13,   46,   49,   50,   51,   52,   32,   13,   33,   34,
166
   13,   17,   13,   13,   18,   19,   20,   23,   25,   71,
167
   26,   27,   28,   43,   44,   45,   53,   55,   54,   59,
168
   60,   61,   62,   65,   66,   64,   67,   68,   72,   69,
169
   78,   79,   11,   73,   74,   70,   77,   81,   47,   57,
170
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
171
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
172
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
173
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
174
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
175
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
176
    0,    0,    0,    0,   13,    0,   13,   13,   13,   13,
177
    0,   37,   38,    0,    0,   13,    0,   13,   39,    0,
178
   40,   16,   13,   13,   32,    0,   33,   34,    0,   13,
179
   13,   13,   13,   13,    0,    0,    0,    0,    0,    0,
180
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
181
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
182
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
183
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
184
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
185
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
186
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
187
    0,    0,    0,    0,    0,    2,    3,    0,    0,    0,
188
    0,    4,    0,    0,    0,    0,    0,    0,    0,    0,
189
    0,    0,    0,    5,    0,    6,
190
};
191
const short yycheck[] =
192
	{                                      10,
193
  125,  125,   10,   26,  125,   28,  276,  262,  263,  276,
194
  276,  262,  263,   36,  269,  125,  271,   61,  269,   42,
195
  271,  125,  265,  266,  267,  268,  258,  125,  260,  261,
196
  258,   10,  260,  261,   10,   10,   10,  276,  123,   62,
197
  123,  276,   10,  259,  259,  268,  264,  276,  270,  276,
198
  276,  276,   10,  267,  265,  276,  276,  123,  265,  276,
199
  125,   44,   10,  276,  276,   57,  276,   80,   35,   41,
200
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
201
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
202
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
203
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
204
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
205
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
206
   -1,   -1,   -1,   -1,  258,   -1,  260,  261,  262,  263,
207
   -1,  262,  263,   -1,   -1,  269,   -1,  271,  269,   -1,
208
  271,  276,  262,  263,  258,   -1,  260,  261,   -1,  269,
209
  258,  271,  260,  261,   -1,   -1,   -1,   -1,   -1,   -1,
210
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
211
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
212
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
213
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
214
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
215
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
216
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
217
   -1,   -1,   -1,   -1,   -1,  256,  257,   -1,   -1,   -1,
218
   -1,  262,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
219
   -1,   -1,   -1,  274,   -1,  276,
220
};
221
#define YYFINAL 1
222
#ifndef YYDEBUG
223
#define YYDEBUG 0
224
#endif
225
#define YYMAXTOKEN 277
226
#if YYDEBUG
227
const char * const yyname[] =
228
	{
229
"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
230
0,0,0,0,0,0,0,0,0,0,0,0,0,"','",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'='",0,0,0,0,0,
231
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
232
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
233
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
234
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
235
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"AUTHORITY",
236
"AGREEMENT","URL","API","ACCOUNT","DOMAIN","ALTERNATIVE","NAMES","CERT","FULL",
237
"CHAIN","KEY","SIGN","WITH","CHALLENGEDIR","YES","NO","INCLUDE","ERROR",
238
"STRING","NUMBER",
239
};
240
const char * const yyrule[] =
241
	{"$accept : grammar",
242
"grammar :",
243
"grammar : grammar include '\\n'",
244
"grammar : grammar varset '\\n'",
245
"grammar : grammar '\\n'",
246
"grammar : grammar authority '\\n'",
247
"grammar : grammar domain '\\n'",
248
"grammar : grammar error '\\n'",
249
"include : INCLUDE STRING",
250
"string : string STRING",
251
"string : STRING",
252
"varset : STRING '=' string",
253
"optnl : '\\n' optnl",
254
"optnl :",
255
"nl : '\\n' optnl",
256
"comma : ','",
257
"comma :",
258
"$$1 :",
259
"authority : AUTHORITY STRING $$1 '{' optnl authorityopts_l '}'",
260
"authorityopts_l : authorityopts_l authorityoptsl nl",
261
"authorityopts_l : authorityoptsl optnl",
262
"authorityoptsl : AGREEMENT URL STRING",
263
"authorityoptsl : API URL STRING",
264
"authorityoptsl : ACCOUNT KEY STRING",
265
"$$2 :",
266
"domain : DOMAIN STRING $$2 '{' optnl domainopts_l '}'",
267
"domainopts_l : domainopts_l domainoptsl nl",
268
"domainopts_l : domainoptsl optnl",
269
"domainoptsl : ALTERNATIVE NAMES '{' altname_l '}'",
270
"domainoptsl : DOMAIN KEY STRING",
271
"domainoptsl : DOMAIN CERT STRING",
272
"domainoptsl : DOMAIN CHAIN CERT STRING",
273
"domainoptsl : DOMAIN FULL CHAIN CERT STRING",
274
"domainoptsl : SIGN WITH STRING",
275
"domainoptsl : CHALLENGEDIR STRING",
276
"altname_l : altname comma altname_l",
277
"altname_l : altname",
278
"altname : STRING",
279
};
280
#endif
281
#ifdef YYSTACKSIZE
282
#undef YYMAXDEPTH
283
#define YYMAXDEPTH YYSTACKSIZE
284
#else
285
#ifdef YYMAXDEPTH
286
#define YYSTACKSIZE YYMAXDEPTH
287
#else
288
#define YYSTACKSIZE 10000
289
#define YYMAXDEPTH 10000
290
#endif
291
#endif
292
#define YYINITSTACKSIZE 200
293
/* LINTUSED */
294
int yydebug;
295
int yynerrs;
296
int yyerrflag;
297
int yychar;
298
short *yyssp;
299
YYSTYPE *yyvsp;
300
YYSTYPE yyval;
301
YYSTYPE yylval;
302
short *yyss;
303
short *yysslim;
304
YYSTYPE *yyvs;
305
unsigned int yystacksize;
306
int yyparse(void);
307
#line 382 "parse.y"
308
309
struct keywords {
310
	const char	*k_name;
311
	int		 k_val;
312
};
313
314
int
315
yyerror(const char *fmt, ...)
316
{
317
	va_list		 ap;
318
	char		*msg;
319
320
	file->errors++;
321
	va_start(ap, fmt);
322
	if (vasprintf(&msg, fmt, ap) == -1)
323
		err(EXIT_FAILURE, "yyerror vasprintf");
324
	va_end(ap);
325
	fprintf(stderr, "%s:%d: %s\n", file->name, yylval.lineno, msg);
326
	free(msg);
327
	return (0);
328
}
329
330
int
331
kw_cmp(const void *k, const void *e)
332
{
333
	return (strcmp(k, ((const struct keywords *)e)->k_name));
334
}
335
336
int
337
lookup(char *s)
338
{
339
	/* this has to be sorted always */
340
	static const struct keywords keywords[] = {
341
		{"account",		ACCOUNT},
342
		{"agreement",		AGREEMENT},
343
		{"alternative",		ALTERNATIVE},
344
		{"api",			API},
345
		{"authority",		AUTHORITY},
346
		{"certificate",		CERT},
347
		{"chain",		CHAIN},
348
		{"challengedir",	CHALLENGEDIR},
349
		{"domain",		DOMAIN},
350
		{"full",		FULL},
351
		{"include",		INCLUDE},
352
		{"key",			KEY},
353
		{"names",		NAMES},
354
		{"sign",		SIGN},
355
		{"url",			URL},
356
		{"with",		WITH},
357
	};
358
	const struct keywords	*p;
359
360
	p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
361
	    sizeof(keywords[0]), kw_cmp);
362
363
	if (p)
364
		return (p->k_val);
365
	else
366
		return (STRING);
367
}
368
369
#define MAXPUSHBACK	128
370
371
u_char	*parsebuf;
372
int	 parseindex;
373
u_char	 pushback_buffer[MAXPUSHBACK];
374
int	 pushback_index = 0;
375
376
int
377
lgetc(int quotec)
378
{
379
	int		c, next;
380
381
	if (parsebuf) {
382
		/* Read character from the parsebuffer instead of input. */
383
		if (parseindex >= 0) {
384
			c = parsebuf[parseindex++];
385
			if (c != '\0')
386
				return (c);
387
			parsebuf = NULL;
388
		} else
389
			parseindex++;
390
	}
391
392
	if (pushback_index)
393
		return (pushback_buffer[--pushback_index]);
394
395
	if (quotec) {
396
		if ((c = getc(file->stream)) == EOF) {
397
			yyerror("reached end of file while parsing "
398
			    "quoted string");
399
			if (file == topfile || popfile() == EOF)
400
				return (EOF);
401
			return (quotec);
402
		}
403
		return (c);
404
	}
405
406
	while ((c = getc(file->stream)) == '\\') {
407
		next = getc(file->stream);
408
		if (next != '\n') {
409
			c = next;
410
			break;
411
		}
412
		yylval.lineno = file->lineno;
413
		file->lineno++;
414
	}
415
416
	while (c == EOF) {
417
		if (file == topfile || popfile() == EOF)
418
			return (EOF);
419
		c = getc(file->stream);
420
	}
421
	return (c);
422
}
423
424
int
425
lungetc(int c)
426
{
427
	if (c == EOF)
428
		return (EOF);
429
	if (parsebuf) {
430
		parseindex--;
431
		if (parseindex >= 0)
432
			return (c);
433
	}
434
	if (pushback_index < MAXPUSHBACK-1)
435
		return (pushback_buffer[pushback_index++] = c);
436
	else
437
		return (EOF);
438
}
439
440
int
441
findeol(void)
442
{
443
	int	c;
444
445
	parsebuf = NULL;
446
447
	/* skip to either EOF or the first real EOL */
448
	while (1) {
449
		if (pushback_index)
450
			c = pushback_buffer[--pushback_index];
451
		else
452
			c = lgetc(0);
453
		if (c == '\n') {
454
			file->lineno++;
455
			break;
456
		}
457
		if (c == EOF)
458
			break;
459
	}
460
	return (ERROR);
461
}
462
463
int
464
yylex(void)
465
{
466
	u_char	 buf[8096];
467
	u_char	*p, *val;
468
	int	 quotec, next, c;
469
	int	 token;
470
471
top:
472
	p = buf;
473
	while ((c = lgetc(0)) == ' ' || c == '\t')
474
		; /* nothing */
475
476
	yylval.lineno = file->lineno;
477
	if (c == '#')
478
		while ((c = lgetc(0)) != '\n' && c != EOF)
479
			; /* nothing */
480
	if (c == '$' && parsebuf == NULL) {
481
		while (1) {
482
			if ((c = lgetc(0)) == EOF)
483
				return (0);
484
485
			if (p + 1 >= buf + sizeof(buf) - 1) {
486
				yyerror("string too long");
487
				return (findeol());
488
			}
489
			if (isalnum(c) || c == '_') {
490
				*p++ = c;
491
				continue;
492
			}
493
			*p = '\0';
494
			lungetc(c);
495
			break;
496
		}
497
		val = symget(buf);
498
		if (val == NULL) {
499
			yyerror("macro '%s' not defined", buf);
500
			return (findeol());
501
		}
502
		parsebuf = val;
503
		parseindex = 0;
504
		goto top;
505
	}
506
507
	switch (c) {
508
	case '\'':
509
	case '"':
510
		quotec = c;
511
		while (1) {
512
			if ((c = lgetc(quotec)) == EOF)
513
				return (0);
514
			if (c == '\n') {
515
				file->lineno++;
516
				continue;
517
			} else if (c == '\\') {
518
				if ((next = lgetc(quotec)) == EOF)
519
					return (0);
520
				if (next == quotec || c == ' ' || c == '\t')
521
					c = next;
522
				else if (next == '\n') {
523
					file->lineno++;
524
					continue;
525
				} else
526
					lungetc(next);
527
			} else if (c == quotec) {
528
				*p = '\0';
529
				break;
530
			} else if (c == '\0') {
531
				yyerror("syntax error");
532
				return (findeol());
533
			}
534
			if (p + 1 >= buf + sizeof(buf) - 1) {
535
				yyerror("string too long");
536
				return (findeol());
537
			}
538
			*p++ = c;
539
		}
540
		yylval.v.string = strdup(buf);
541
		if (yylval.v.string == NULL)
542
			err(EXIT_FAILURE, "yylex: strdup");
543
		return (STRING);
544
	}
545
546
#define allowed_to_end_number(x) \
547
	(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
548
549
	if (c == '-' || isdigit(c)) {
550
		do {
551
			*p++ = c;
552
			if ((unsigned)(p-buf) >= sizeof(buf)) {
553
				yyerror("string too long");
554
				return (findeol());
555
			}
556
		} while ((c = lgetc(0)) != EOF && isdigit(c));
557
		lungetc(c);
558
		if (p == buf + 1 && buf[0] == '-')
559
			goto nodigits;
560
		if (c == EOF || allowed_to_end_number(c)) {
561
			const char *errstr = NULL;
562
563
			*p = '\0';
564
			yylval.v.number = strtonum(buf, LLONG_MIN,
565
			    LLONG_MAX, &errstr);
566
			if (errstr) {
567
				yyerror("\"%s\" invalid number: %s",
568
				    buf, errstr);
569
				return (findeol());
570
			}
571
			return (NUMBER);
572
		} else {
573
nodigits:
574
			while (p > buf + 1)
575
				lungetc(*--p);
576
			c = *--p;
577
			if (c == '-')
578
				return (c);
579
		}
580
	}
581
582
#define allowed_in_string(x) \
583
	(isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
584
	x != '{' && x != '}' && \
585
	x != '!' && x != '=' && x != '#' && \
586
	x != ','))
587
588
	if (isalnum(c) || c == ':' || c == '_') {
589
		do {
590
			*p++ = c;
591
			if ((unsigned)(p-buf) >= sizeof(buf)) {
592
				yyerror("string too long");
593
				return (findeol());
594
			}
595
		} while ((c = lgetc(0)) != EOF && (allowed_in_string(c)));
596
		lungetc(c);
597
		*p = '\0';
598
		if ((token = lookup(buf)) == STRING) {
599
			if ((yylval.v.string = strdup(buf)) == NULL)
600
				err(EXIT_FAILURE, "yylex: strdup");
601
		}
602
		return (token);
603
	}
604
	if (c == '\n') {
605
		yylval.lineno = file->lineno;
606
		file->lineno++;
607
	}
608
	if (c == EOF)
609
		return (0);
610
	return (c);
611
}
612
613
struct file *
614
pushfile(const char *name)
615
{
616
	struct file	*nfile;
617
618
	if ((nfile = calloc(1, sizeof(struct file))) == NULL) {
619
		warn("malloc");
620
		return (NULL);
621
	}
622
	if ((nfile->name = strdup(name)) == NULL) {
623
		warn("strdup");
624
		free(nfile);
625
		return (NULL);
626
	}
627
	if ((nfile->stream = fopen(nfile->name, "r")) == NULL) {
628
		warn("%s", nfile->name);
629
		free(nfile->name);
630
		free(nfile);
631
		return (NULL);
632
	}
633
	nfile->lineno = 1;
634
	TAILQ_INSERT_TAIL(&files, nfile, entry);
635
	return (nfile);
636
}
637
638
int
639
popfile(void)
640
{
641
	struct file	*prev;
642
643
	if ((prev = TAILQ_PREV(file, files, entry)) != NULL)
644
		prev->errors += file->errors;
645
646
	TAILQ_REMOVE(&files, file, entry);
647
	fclose(file->stream);
648
	free(file->name);
649
	free(file);
650
	file = prev;
651
	return (file ? 0 : EOF);
652
}
653
654
struct acme_conf *
655
parse_config(const char *filename, int opts)
656
{
657
	struct sym	*sym, *next;
658
659
	if ((conf = calloc(1, sizeof(struct acme_conf))) == NULL)
660
		err(EXIT_FAILURE, "parse_config");
661
	conf->opts = opts;
662
663
	if ((file = pushfile(filename)) == NULL) {
664
		free(conf);
665
		return (NULL);
666
	}
667
	topfile = file;
668
669
	TAILQ_INIT(&conf->authority_list);
670
	TAILQ_INIT(&conf->domain_list);
671
672
	yyparse();
673
	errors = file->errors;
674
	popfile();
675
676
	/* Free macros and check which have not been used. */
677
	TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) {
678
		if ((conf->opts & ACME_OPT_VERBOSE) && !sym->used)
679
			fprintf(stderr, "warning: macro '%s' not "
680
			    "used\n", sym->nam);
681
		if (!sym->persist) {
682
			free(sym->nam);
683
			free(sym->val);
684
			TAILQ_REMOVE(&symhead, sym, entry);
685
			free(sym);
686
		}
687
	}
688
689
	if (errors) {
690
		clear_config(conf);
691
		return (NULL);
692
	}
693
694
	if (opts & ACME_OPT_CHECK)
695
		print_config(conf);
696
697
	return (conf);
698
}
699
700
int
701
symset(const char *nam, const char *val, int persist)
702
{
703
	struct sym	*sym;
704
705
	TAILQ_FOREACH(sym, &symhead, entry) {
706
		if (strcmp(nam, sym->nam) == 0)
707
			break;
708
	}
709
710
	if (sym != NULL) {
711
		if (sym->persist == 1)
712
			return (0);
713
		else {
714
			free(sym->nam);
715
			free(sym->val);
716
			TAILQ_REMOVE(&symhead, sym, entry);
717
			free(sym);
718
		}
719
	}
720
	if ((sym = calloc(1, sizeof(*sym))) == NULL)
721
		return (-1);
722
723
	sym->nam = strdup(nam);
724
	if (sym->nam == NULL) {
725
		free(sym);
726
		return (-1);
727
	}
728
	sym->val = strdup(val);
729
	if (sym->val == NULL) {
730
		free(sym->nam);
731
		free(sym);
732
		return (-1);
733
	}
734
	sym->used = 0;
735
	sym->persist = persist;
736
	TAILQ_INSERT_TAIL(&symhead, sym, entry);
737
	return (0);
738
}
739
740
int
741
cmdline_symset(char *s)
742
{
743
	char	*sym, *val;
744
	int	ret;
745
	size_t	len;
746
747
	if ((val = strrchr(s, '=')) == NULL)
748
		return (-1);
749
750
	len = strlen(s) - strlen(val) + 1;
751
	if ((sym = malloc(len)) == NULL)
752
		errx(EXIT_FAILURE, "cmdline_symset: malloc");
753
754
	strlcpy(sym, s, len);
755
756
	ret = symset(sym, val + 1, 1);
757
	free(sym);
758
759
	return (ret);
760
}
761
762
char *
763
symget(const char *nam)
764
{
765
	struct sym	*sym;
766
767
	TAILQ_FOREACH(sym, &symhead, entry) {
768
		if (strcmp(nam, sym->nam) == 0) {
769
			sym->used = 1;
770
			return (sym->val);
771
		}
772
	}
773
	return (NULL);
774
}
775
776
struct authority_c *
777
conf_new_authority(struct acme_conf *c, char *s)
778
{
779
	struct authority_c *a;
780
781
	a = authority_find(c, s);
782
	if (a)
783
		return (NULL);
784
	if ((a = calloc(1, sizeof(struct authority_c))) == NULL)
785
		err(EXIT_FAILURE, "calloc");
786
	TAILQ_INSERT_TAIL(&c->authority_list, a, entry);
787
788
	a->name = s;
789
	return (a);
790
}
791
792
struct authority_c *
793
authority_find(struct acme_conf *c, char *s)
794
{
795
	struct authority_c	*a;
796
797
	TAILQ_FOREACH(a, &c->authority_list, entry) {
798
		if (strncmp(a->name, s, AUTH_MAXLEN) == 0) {
799
			return (a);
800
		}
801
	}
802
	return (NULL);
803
}
804
805
struct authority_c *
806
authority_find0(struct acme_conf *c)
807
{
808
	return (TAILQ_FIRST(&c->authority_list));
809
}
810
811
struct domain_c *
812
conf_new_domain(struct acme_conf *c, char *s)
813
{
814
	struct domain_c *d;
815
816
	d = domain_find(c, s);
817
	if (d)
818
		return (NULL);
819
	if ((d = calloc(1, sizeof(struct domain_c))) == NULL)
820
		err(EXIT_FAILURE, "calloc");
821
	TAILQ_INSERT_TAIL(&c->domain_list, d, entry);
822
823
	d->domain = s;
824
	TAILQ_INIT(&d->altname_list);
825
826
	return (d);
827
}
828
829
struct domain_c *
830
domain_find(struct acme_conf *c, char *s)
831
{
832
	struct domain_c	*d;
833
834
	TAILQ_FOREACH(d, &c->domain_list, entry) {
835
		if (strncmp(d->domain, s, DOMAIN_MAXLEN) == 0) {
836
			return (d);
837
		}
838
	}
839
	return (NULL);
840
}
841
842
struct keyfile *
843
conf_new_keyfile(struct acme_conf *c, char *s)
844
{
845
	struct keyfile *k;
846
847
	LIST_FOREACH(k, &c->used_key_list, entry) {
848
		if (strncmp(k->name, s, PATH_MAX) == 0) {
849
			return (NULL);
850
		}
851
	}
852
853
	if ((k = calloc(1, sizeof(struct keyfile))) == NULL)
854
		err(EXIT_FAILURE, "calloc");
855
	LIST_INSERT_HEAD(&c->used_key_list, k, entry);
856
857
	k->name = s;
858
	return (k);
859
}
860
861
void
862
clear_config(struct acme_conf *xconf)
863
{
864
	struct authority_c	*a;
865
	struct domain_c		*d;
866
	struct altname_c	*ac;
867
868
	while ((a = TAILQ_FIRST(&xconf->authority_list)) != NULL) {
869
		TAILQ_REMOVE(&xconf->authority_list, a, entry);
870
		free(a);
871
	}
872
	while ((d = TAILQ_FIRST(&xconf->domain_list)) != NULL) {
873
		while ((ac = TAILQ_FIRST(&d->altname_list)) != NULL) {
874
			TAILQ_REMOVE(&d->altname_list, ac, entry);
875
			free(ac);
876
		}
877
		TAILQ_REMOVE(&xconf->domain_list, d, entry);
878
		free(d);
879
	}
880
	free(xconf);
881
}
882
883
void
884
print_config(struct acme_conf *xconf)
885
{
886
	struct authority_c	*a;
887
	struct domain_c		*d;
888
	struct altname_c	*ac;
889
	int			 f;
890
891
	TAILQ_FOREACH(a, &xconf->authority_list, entry) {
892
		printf("authority %s {\n", a->name);
893
		if (a->agreement != NULL)
894
			printf("\tagreement url \"%s\"\n", a->agreement);
895
		if (a->api != NULL)
896
			printf("\tapi url \"%s\"\n", a->api);
897
		if (a->account != NULL)
898
			printf("\taccount key \"%s\"\n", a->account);
899
		printf("}\n\n");
900
	}
901
	TAILQ_FOREACH(d, &xconf->domain_list, entry) {
902
		f = 0;
903
		printf("domain %s {\n", d->domain);
904
		TAILQ_FOREACH(ac, &d->altname_list, entry) {
905
			if (!f)
906
				printf("\talternative names { ");
907
			if (ac->domain != NULL) {
908
				printf("%s%s", f ? ", " : " ", ac->domain);
909
				f = 1;
910
			}
911
		}
912
		if (f)
913
			printf("}\n");
914
		if (d->key != NULL)
915
			printf("\tdomain key \"%s\"\n", d->key);
916
		if (d->cert != NULL)
917
			printf("\tdomain certificate \"%s\"\n", d->cert);
918
		if (d->chain != NULL)
919
			printf("\tdomain chain certificate \"%s\"\n", d->chain);
920
		if (d->fullchain != NULL)
921
			printf("\tdomain full chain certificate \"%s\"\n",
922
			    d->fullchain);
923
		if (d->auth != NULL)
924
			printf("\tsign with \"%s\"\n", d->auth);
925
		if (d->challengedir != NULL)
926
			printf("\tchallengedir \"%s\"\n", d->challengedir);
927
		printf("}\n\n");
928
	}
929
}
930
931
/*
932
 * This isn't RFC1035 compliant, but does the bare minimum in making
933
 * sure that we don't get bogus domain names on the command line, which
934
 * might otherwise screw up our directory structure.
935
 * Returns zero on failure, non-zero on success.
936
 */
937
int
938
domain_valid(const char *cp)
939
{
940
941
	for ( ; *cp != '\0'; cp++)
942
		if (!(*cp == '.' || *cp == '-' ||
943
		    *cp == '_' || isalnum((int)*cp)))
944
			return (0);
945
	return (1);
946
}
947
948
int
949
conf_check_file(char *s, int dontstat)
950
{
951
	struct stat st;
952
953
	if (s[0] != '/') {
954
		warnx("%s: not an absolute path", s);
955
		return (0);
956
	}
957
	if (dontstat)
958
		return (1);
959
	if (stat(s, &st)) {
960
		warn("cannot stat %s", s);
961
		return (0);
962
	}
963
	if (st.st_mode & (S_IRWXG | S_IRWXO)) {
964
		warnx("%s: group read/writable or world read/writable", s);
965
		return (0);
966
	}
967
	return (1);
968
}
969
#line 962 "parse.c"
970
/* allocate initial stack or double stack size, up to YYMAXDEPTH */
971
static int yygrowstack(void)
972
{
973
    unsigned int newsize;
974
    long sslen;
975
    short *newss;
976
    YYSTYPE *newvs;
977
978
    if ((newsize = yystacksize) == 0)
979
        newsize = YYINITSTACKSIZE;
980
    else if (newsize >= YYMAXDEPTH)
981
        return -1;
982
    else if ((newsize *= 2) > YYMAXDEPTH)
983
        newsize = YYMAXDEPTH;
984
    sslen = yyssp - yyss;
985
#ifdef SIZE_MAX
986
#define YY_SIZE_MAX SIZE_MAX
987
#else
988
#define YY_SIZE_MAX 0xffffffffU
989
#endif
990
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)
991
        goto bail;
992
    newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
993
      (short *)malloc(newsize * sizeof *newss); /* overflow check above */
994
    if (newss == NULL)
995
        goto bail;
996
    yyss = newss;
997
    yyssp = newss + sslen;
998
    if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)
999
        goto bail;
1000
    newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
1001
      (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
1002
    if (newvs == NULL)
1003
        goto bail;
1004
    yyvs = newvs;
1005
    yyvsp = newvs + sslen;
1006
    yystacksize = newsize;
1007
    yysslim = yyss + newsize - 1;
1008
    return 0;
1009
bail:
1010
    if (yyss)
1011
            free(yyss);
1012
    if (yyvs)
1013
            free(yyvs);
1014
    yyss = yyssp = NULL;
1015
    yyvs = yyvsp = NULL;
1016
    yystacksize = 0;
1017
    return -1;
1018
}
1019
1020
#define YYABORT goto yyabort
1021
#define YYREJECT goto yyabort
1022
#define YYACCEPT goto yyaccept
1023
#define YYERROR goto yyerrlab
1024
int
1025
yyparse(void)
1026
{
1027
    int yym, yyn, yystate;
1028
#if YYDEBUG
1029
    const char *yys;
1030
1031
    if ((yys = getenv("YYDEBUG")))
1032
    {
1033
        yyn = *yys;
1034
        if (yyn >= '0' && yyn <= '9')
1035
            yydebug = yyn - '0';
1036
    }
1037
#endif /* YYDEBUG */
1038
1039
    yynerrs = 0;
1040
    yyerrflag = 0;
1041
    yychar = (-1);
1042
1043
    if (yyss == NULL && yygrowstack()) goto yyoverflow;
1044
    yyssp = yyss;
1045
    yyvsp = yyvs;
1046
    *yyssp = yystate = 0;
1047
1048
yyloop:
1049
    if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
1050
    if (yychar < 0)
1051
    {
1052
        if ((yychar = yylex()) < 0) yychar = 0;
1053
#if YYDEBUG
1054
        if (yydebug)
1055
        {
1056
            yys = 0;
1057
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1058
            if (!yys) yys = "illegal-symbol";
1059
            printf("%sdebug: state %d, reading %d (%s)\n",
1060
                    YYPREFIX, yystate, yychar, yys);
1061
        }
1062
#endif
1063
    }
1064
    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
1065
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1066
    {
1067
#if YYDEBUG
1068
        if (yydebug)
1069
            printf("%sdebug: state %d, shifting to state %d\n",
1070
                    YYPREFIX, yystate, yytable[yyn]);
1071
#endif
1072
        if (yyssp >= yysslim && yygrowstack())
1073
        {
1074
            goto yyoverflow;
1075
        }
1076
        *++yyssp = yystate = yytable[yyn];
1077
        *++yyvsp = yylval;
1078
        yychar = (-1);
1079
        if (yyerrflag > 0)  --yyerrflag;
1080
        goto yyloop;
1081
    }
1082
    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
1083
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1084
    {
1085
        yyn = yytable[yyn];
1086
        goto yyreduce;
1087
    }
1088
    if (yyerrflag) goto yyinrecovery;
1089
#if defined(__GNUC__)
1090
    goto yynewerror;
1091
#endif
1092
yynewerror:
1093
    yyerror("syntax error");
1094
#if defined(__GNUC__)
1095
    goto yyerrlab;
1096
#endif
1097
yyerrlab:
1098
    ++yynerrs;
1099
yyinrecovery:
1100
    if (yyerrflag < 3)
1101
    {
1102
        yyerrflag = 3;
1103
        for (;;)
1104
        {
1105
            if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
1106
                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
1107
            {
1108
#if YYDEBUG
1109
                if (yydebug)
1110
                    printf("%sdebug: state %d, error recovery shifting\
1111
 to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
1112
#endif
1113
                if (yyssp >= yysslim && yygrowstack())
1114
                {
1115
                    goto yyoverflow;
1116
                }
1117
                *++yyssp = yystate = yytable[yyn];
1118
                *++yyvsp = yylval;
1119
                goto yyloop;
1120
            }
1121
            else
1122
            {
1123
#if YYDEBUG
1124
                if (yydebug)
1125
                    printf("%sdebug: error recovery discarding state %d\n",
1126
                            YYPREFIX, *yyssp);
1127
#endif
1128
                if (yyssp <= yyss) goto yyabort;
1129
                --yyssp;
1130
                --yyvsp;
1131
            }
1132
        }
1133
    }
1134
    else
1135
    {
1136
        if (yychar == 0) goto yyabort;
1137
#if YYDEBUG
1138
        if (yydebug)
1139
        {
1140
            yys = 0;
1141
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1142
            if (!yys) yys = "illegal-symbol";
1143
            printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1144
                    YYPREFIX, yystate, yychar, yys);
1145
        }
1146
#endif
1147
        yychar = (-1);
1148
        goto yyloop;
1149
    }
1150
yyreduce:
1151
#if YYDEBUG
1152
    if (yydebug)
1153
        printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1154
                YYPREFIX, yystate, yyn, yyrule[yyn]);
1155
#endif
1156
    yym = yylen[yyn];
1157
    if (yym)
1158
        yyval = yyvsp[1-yym];
1159
    else
1160
        memset(&yyval, 0, sizeof yyval);
1161
    switch (yyn)
1162
    {
1163
case 7:
1164
#line 112 "parse.y"
1165
{ file->errors++; }
1166
break;
1167
case 8:
1168
#line 115 "parse.y"
1169
{
1170
			struct file	*nfile;
1171
1172
			if ((nfile = pushfile(yyvsp[0].v.string)) == NULL) {
1173
				yyerror("failed to include file %s", yyvsp[0].v.string);
1174
				free(yyvsp[0].v.string);
1175
				YYERROR;
1176
			}
1177
			free(yyvsp[0].v.string);
1178
1179
			file = nfile;
1180
			lungetc('\n');
1181
		}
1182
break;
1183
case 9:
1184
#line 130 "parse.y"
1185
{
1186
			if (asprintf(&yyval.v.string, "%s %s", yyvsp[-1].v.string, yyvsp[0].v.string) == -1) {
1187
				free(yyvsp[-1].v.string);
1188
				free(yyvsp[0].v.string);
1189
				yyerror("string: asprintf");
1190
				YYERROR;
1191
			}
1192
			free(yyvsp[-1].v.string);
1193
			free(yyvsp[0].v.string);
1194
		}
1195
break;
1196
case 11:
1197
#line 143 "parse.y"
1198
{
1199
			char *s = yyvsp[-2].v.string;
1200
			if (conf->opts & ACME_OPT_VERBOSE)
1201
				printf("%s = \"%s\"\n", yyvsp[-2].v.string, yyvsp[0].v.string);
1202
			while (*s++) {
1203
				if (isspace((unsigned char)*s)) {
1204
					yyerror("macro name cannot contain "
1205
					    "whitespace");
1206
					YYERROR;
1207
				}
1208
			}
1209
			if (symset(yyvsp[-2].v.string, yyvsp[0].v.string, 0) == -1)
1210
				errx(EXIT_FAILURE, "cannot store variable");
1211
			free(yyvsp[-2].v.string);
1212
			free(yyvsp[0].v.string);
1213
		}
1214
break;
1215
case 17:
1216
#line 172 "parse.y"
1217
{
1218
			char *s;
1219
			if ((s = strdup(yyvsp[0].v.string)) == NULL)
1220
				err(EXIT_FAILURE, "strdup");
1221
			if ((auth = conf_new_authority(conf, s)) == NULL) {
1222
				free(s);
1223
				yyerror("authority already defined");
1224
				YYERROR;
1225
			}
1226
		}
1227
break;
1228
case 18:
1229
#line 181 "parse.y"
1230
{
1231
			/* XXX enforce minimum config here */
1232
			auth = NULL;
1233
		}
1234
break;
1235
case 21:
1236
#line 191 "parse.y"
1237
{
1238
			char *s;
1239
			if (auth->agreement != NULL) {
1240
				yyerror("duplicate agreement");
1241
				YYERROR;
1242
			}
1243
			if ((s = strdup(yyvsp[0].v.string)) == NULL)
1244
				err(EXIT_FAILURE, "strdup");
1245
			auth->agreement = s;
1246
		}
1247
break;
1248
case 22:
1249
#line 201 "parse.y"
1250
{
1251
			char *s;
1252
			if (auth->api != NULL) {
1253
				yyerror("duplicate api");
1254
				YYERROR;
1255
			}
1256
			if ((s = strdup(yyvsp[0].v.string)) == NULL)
1257
				err(EXIT_FAILURE, "strdup");
1258
			auth->api = s;
1259
		}
1260
break;
1261
case 23:
1262
#line 211 "parse.y"
1263
{
1264
			char *s;
1265
			if (auth->account != NULL) {
1266
				yyerror("duplicate account");
1267
				YYERROR;
1268
			}
1269
			if ((s = strdup(yyvsp[0].v.string)) == NULL)
1270
				err(EXIT_FAILURE, "strdup");
1271
			auth->account = s;
1272
		}
1273
break;
1274
case 24:
1275
#line 223 "parse.y"
1276
{
1277
			char *s;
1278
			if ((s = strdup(yyvsp[0].v.string)) == NULL)
1279
				err(EXIT_FAILURE, "strdup");
1280
			if (!domain_valid(s)) {
1281
				free(s);
1282
				yyerror("%s: bad domain syntax", s);
1283
				YYERROR;
1284
			}
1285
			if ((domain = conf_new_domain(conf, s)) == NULL) {
1286
				free(s);
1287
				yyerror("domain already defined");
1288
				YYERROR;
1289
			}
1290
		}
1291
break;
1292
case 25:
1293
#line 237 "parse.y"
1294
{
1295
			/* enforce minimum config here */
1296
			if (domain->key == NULL) {
1297
				yyerror("no domain key file specified for "
1298
				    "domain %s", domain->domain);
1299
				YYERROR;
1300
			}
1301
			if (domain->cert == NULL && domain->fullchain == NULL) {
1302
				yyerror("at least certificate file or full "
1303
				    "certificate chain file must be specified "
1304
				    "for domain %s", domain->domain);
1305
				YYERROR;
1306
			}
1307
			domain = NULL;
1308
		}
1309
break;
1310
case 29:
1311
#line 259 "parse.y"
1312
{
1313
			char *s;
1314
			if (domain->key != NULL) {
1315
				yyerror("duplicate key");
1316
				YYERROR;
1317
			}
1318
			if ((s = strdup(yyvsp[0].v.string)) == NULL)
1319
				err(EXIT_FAILURE, "strdup");
1320
			if (!conf_check_file(s,
1321
			    (conf->opts & ACME_OPT_NEWDKEY))) {
1322
				free(s);
1323
				YYERROR;
1324
			}
1325
			if ((conf_new_keyfile(conf, s)) == NULL) {
1326
				free(s);
1327
				yyerror("domain key file already used");
1328
				YYERROR;
1329
			}
1330
			domain->key = s;
1331
		}
1332
break;
1333
case 30:
1334
#line 279 "parse.y"
1335
{
1336
			char *s;
1337
			if (domain->cert != NULL) {
1338
				yyerror("duplicate cert");
1339
				YYERROR;
1340
			}
1341
			if ((s = strdup(yyvsp[0].v.string)) == NULL)
1342
				err(EXIT_FAILURE, "strdup");
1343
			if (s[0] != '/') {
1344
				free(s);
1345
				yyerror("not an absolute path");
1346
				YYERROR;
1347
			}
1348
			if ((conf_new_keyfile(conf, s)) == NULL) {
1349
				free(s);
1350
				yyerror("domain cert file already used");
1351
				YYERROR;
1352
			}
1353
			domain->cert = s;
1354
		}
1355
break;
1356
case 31:
1357
#line 299 "parse.y"
1358
{
1359
			char *s;
1360
			if (domain->chain != NULL) {
1361
				yyerror("duplicate chain");
1362
				YYERROR;
1363
			}
1364
			if ((s = strdup(yyvsp[0].v.string)) == NULL)
1365
				err(EXIT_FAILURE, "strdup");
1366
			if ((conf_new_keyfile(conf, s)) == NULL) {
1367
				free(s);
1368
				yyerror("domain chain file already used");
1369
				YYERROR;
1370
			}
1371
			domain->chain = s;
1372
		}
1373
break;
1374
case 32:
1375
#line 314 "parse.y"
1376
{
1377
			char *s;
1378
			if (domain->fullchain != NULL) {
1379
				yyerror("duplicate chain");
1380
				YYERROR;
1381
			}
1382
			if ((s = strdup(yyvsp[0].v.string)) == NULL)
1383
				err(EXIT_FAILURE, "strdup");
1384
			if ((conf_new_keyfile(conf, s)) == NULL) {
1385
				free(s);
1386
				yyerror("domain full chain file already used");
1387
				YYERROR;
1388
			}
1389
			domain->fullchain = s;
1390
		}
1391
break;
1392
case 33:
1393
#line 329 "parse.y"
1394
{
1395
			char *s;
1396
			if (domain->auth != NULL) {
1397
				yyerror("duplicate use");
1398
				YYERROR;
1399
			}
1400
			if ((s = strdup(yyvsp[0].v.string)) == NULL)
1401
				err(EXIT_FAILURE, "strdup");
1402
			if (authority_find(conf, s) == NULL) {
1403
				yyerror("use: unknown authority");
1404
				YYERROR;
1405
			}
1406
			domain->auth = s;
1407
		}
1408
break;
1409
case 34:
1410
#line 343 "parse.y"
1411
{
1412
			char *s;
1413
			if (domain->challengedir != NULL) {
1414
				yyerror("duplicate challengedir");
1415
				YYERROR;
1416
			}
1417
			if ((s = strdup(yyvsp[0].v.string)) == NULL)
1418
				err(EXIT_FAILURE, "strdup");
1419
			domain->challengedir = s;
1420
		}
1421
break;
1422
case 37:
1423
#line 359 "parse.y"
1424
{
1425
			char			*s;
1426
			struct altname_c	*ac;
1427
			if (!domain_valid(yyvsp[0].v.string)) {
1428
				yyerror("bad domain syntax");
1429
				YYERROR;
1430
			}
1431
			if ((ac = calloc(1, sizeof(struct altname_c))) == NULL)
1432
				err(EXIT_FAILURE, "calloc");
1433
			if ((s = strdup(yyvsp[0].v.string)) == NULL) {
1434
				free(ac);
1435
				err(EXIT_FAILURE, "strdup");
1436
			}
1437
			ac->domain = s;
1438
			TAILQ_INSERT_TAIL(&domain->altname_list, ac, entry);
1439
			domain->altname_count++;
1440
			/*
1441
			 * XXX we could check if altname is duplicate
1442
			 * or identical to domain->domain
1443
			*/
1444
		}
1445
break;
1446
#line 1439 "parse.c"
1447
    }
1448
    yyssp -= yym;
1449
    yystate = *yyssp;
1450
    yyvsp -= yym;
1451
    yym = yylhs[yyn];
1452
    if (yystate == 0 && yym == 0)
1453
    {
1454
#if YYDEBUG
1455
        if (yydebug)
1456
            printf("%sdebug: after reduction, shifting from state 0 to\
1457
 state %d\n", YYPREFIX, YYFINAL);
1458
#endif
1459
        yystate = YYFINAL;
1460
        *++yyssp = YYFINAL;
1461
        *++yyvsp = yyval;
1462
        if (yychar < 0)
1463
        {
1464
            if ((yychar = yylex()) < 0) yychar = 0;
1465
#if YYDEBUG
1466
            if (yydebug)
1467
            {
1468
                yys = 0;
1469
                if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1470
                if (!yys) yys = "illegal-symbol";
1471
                printf("%sdebug: state %d, reading %d (%s)\n",
1472
                        YYPREFIX, YYFINAL, yychar, yys);
1473
            }
1474
#endif
1475
        }
1476
        if (yychar == 0) goto yyaccept;
1477
        goto yyloop;
1478
    }
1479
    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
1480
            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
1481
        yystate = yytable[yyn];
1482
    else
1483
        yystate = yydgoto[yym];
1484
#if YYDEBUG
1485
    if (yydebug)
1486
        printf("%sdebug: after reduction, shifting from state %d \
1487
to state %d\n", YYPREFIX, *yyssp, yystate);
1488
#endif
1489
    if (yyssp >= yysslim && yygrowstack())
1490
    {
1491
        goto yyoverflow;
1492
    }
1493
    *++yyssp = yystate;
1494
    *++yyvsp = yyval;
1495
    goto yyloop;
1496
yyoverflow:
1497
    yyerror("yacc stack overflow");
1498
yyabort:
1499
    if (yyss)
1500
            free(yyss);
1501
    if (yyvs)
1502
            free(yyvs);
1503
    yyss = yyssp = NULL;
1504
    yyvs = yyvsp = NULL;
1505
    yystacksize = 0;
1506
    return (1);
1507
yyaccept:
1508
    if (yyss)
1509
            free(yyss);
1510
    if (yyvs)
1511
            free(yyvs);
1512
    yyss = yyssp = NULL;
1513
    yyvs = yyvsp = NULL;
1514
    yystacksize = 0;
1515
    return (0);
1516
}