Bug Summary

File:src/usr.sbin/acme-client/obj/parse.c
Warning:line 1072, column 13
Attempt to free released memory

Annotated Source Code

Press '?' to see keyboard shortcuts

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