1 /* $OpenBSD: parse.y,v 1.128 2022/02/27 20:30:30 bluhm Exp $ */ 2 3 /* 4 * Copyright (c) 2020 Matthias Pressfreund <mpfr@fn.de> 5 * Copyright (c) 2007 - 2015 Reyk Floeter <reyk@openbsd.org> 6 * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org> 7 * Copyright (c) 2006 Pierre-Yves Ritschard <pyr@openbsd.org> 8 * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org> 9 * Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org> 10 * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org> 11 * Copyright (c) 2001 Markus Friedl. All rights reserved. 12 * Copyright (c) 2001 Daniel Hartmeier. All rights reserved. 13 * Copyright (c) 2001 Theo de Raadt. All rights reserved. 14 * 15 * Permission to use, copy, modify, and distribute this software for any 16 * purpose with or without fee is hereby granted, provided that the above 17 * copyright notice and this permission notice appear in all copies. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 20 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 22 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 23 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 24 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 25 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 26 */ 27 28 %{ 29 #include <sys/types.h> 30 #include <sys/socket.h> 31 #include <sys/un.h> 32 #include <sys/stat.h> 33 #include <sys/queue.h> 34 #include <sys/tree.h> 35 #include <sys/ioctl.h> 36 #include <sys/sockio.h> 37 #include <sys/time.h> 38 39 #include <net/if.h> 40 #include <netinet/in.h> 41 #include <arpa/inet.h> 42 43 #include <ctype.h> 44 #include <unistd.h> 45 #include <err.h> 46 #include <errno.h> 47 #include <limits.h> 48 #include <stdint.h> 49 #include <stdarg.h> 50 #include <stdio.h> 51 #include <netdb.h> 52 #include <string.h> 53 #include <ifaddrs.h> 54 #include <syslog.h> 55 56 #include "httpd.h" 57 #include "http.h" 58 59 TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files); 60 static struct file { 61 TAILQ_ENTRY(file) entry; 62 FILE *stream; 63 char *name; 64 size_t ungetpos; 65 size_t ungetsize; 66 u_char *ungetbuf; 67 int eof_reached; 68 int lineno; 69 int errors; 70 } *file, *topfile; 71 struct file *pushfile(const char *, int); 72 int popfile(void); 73 int check_file_secrecy(int, const char *); 74 int yyparse(void); 75 int yylex(void); 76 int yyerror(const char *, ...) 77 __attribute__((__format__ (printf, 1, 2))) 78 __attribute__((__nonnull__ (1))); 79 int kw_cmp(const void *, const void *); 80 int lookup(char *); 81 int igetc(void); 82 int lgetc(int); 83 void lungetc(int); 84 int findeol(void); 85 86 TAILQ_HEAD(symhead, sym) symhead = TAILQ_HEAD_INITIALIZER(symhead); 87 struct sym { 88 TAILQ_ENTRY(sym) entry; 89 int used; 90 int persist; 91 char *nam; 92 char *val; 93 }; 94 int symset(const char *, const char *, int); 95 char *symget(const char *); 96 97 struct httpd *conf = NULL; 98 static int errors = 0; 99 static int loadcfg = 0; 100 uint32_t last_server_id = 0; 101 uint32_t last_auth_id = 0; 102 103 static struct server *srv = NULL, *parentsrv = NULL; 104 static struct server_config *srv_conf = NULL; 105 struct serverlist servers; 106 struct media_type media; 107 108 struct address *host_v4(const char *); 109 struct address *host_v6(const char *); 110 int host_dns(const char *, struct addresslist *, 111 int, struct portrange *, const char *, int); 112 int host_if(const char *, struct addresslist *, 113 int, struct portrange *, const char *, int); 114 int host(const char *, struct addresslist *, 115 int, struct portrange *, const char *, int); 116 struct server *server_inherit(struct server *, struct server_config *, 117 struct server_config *); 118 int listen_on(const char *, int, struct portrange *); 119 int getservice(char *); 120 int is_if_in_group(const char *, const char *); 121 int get_fastcgi_dest(struct server_config *, const char *, char *); 122 void remove_locations(struct server_config *); 123 124 typedef struct { 125 union { 126 int64_t number; 127 char *string; 128 struct timeval tv; 129 struct portrange port; 130 struct auth auth; 131 } v; 132 int lineno; 133 } YYSTYPE; 134 135 %} 136 137 %token ACCESS ALIAS AUTO BACKLOG BODY BUFFER CERTIFICATE CHROOT CIPHERS COMMON 138 %token COMBINED CONNECTION DHE DIRECTORY ECDHE ERR FCGI INDEX IP KEY LIFETIME 139 %token LISTEN LOCATION LOG LOGDIR MATCH MAXIMUM NO NODELAY OCSP ON PORT PREFORK 140 %token PROTOCOLS REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG TCP TICKET 141 %token TIMEOUT TLS TYPE TYPES HSTS MAXAGE SUBDOMAINS DEFAULT PRELOAD REQUEST 142 %token ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS REWRITE 143 %token CA CLIENT CRL OPTIONAL PARAM FORWARDED FOUND NOT 144 %token ERRDOCS GZIPSTATIC 145 %token <v.string> STRING 146 %token <v.number> NUMBER 147 %type <v.port> port 148 %type <v.string> fcgiport 149 %type <v.number> opttls optmatch optfound 150 %type <v.tv> timeout 151 %type <v.string> numberstring optstring 152 %type <v.auth> authopts 153 154 %% 155 156 grammar : /* empty */ 157 | grammar include '\n' 158 | grammar '\n' 159 | grammar varset '\n' 160 | grammar main '\n' 161 | grammar server '\n' 162 | grammar types '\n' 163 | grammar error '\n' { file->errors++; } 164 ; 165 166 include : INCLUDE STRING { 167 struct file *nfile; 168 169 if ((nfile = pushfile($2, 0)) == NULL) { 170 yyerror("failed to include file %s", $2); 171 free($2); 172 YYERROR; 173 } 174 free($2); 175 176 file = nfile; 177 lungetc('\n'); 178 } 179 ; 180 181 varset : STRING '=' STRING { 182 char *s = $1; 183 while (*s++) { 184 if (isspace((unsigned char)*s)) { 185 yyerror("macro name cannot contain " 186 "whitespace"); 187 free($1); 188 free($3); 189 YYERROR; 190 } 191 } 192 if (symset($1, $3, 0) == -1) 193 fatal("cannot store variable"); 194 free($1); 195 free($3); 196 } 197 ; 198 199 opttls : /*empty*/ { $$ = 0; } 200 | TLS { $$ = 1; } 201 ; 202 203 main : PREFORK NUMBER { 204 if (loadcfg) 205 break; 206 if ($2 <= 0 || $2 > PROC_MAX_INSTANCES) { 207 yyerror("invalid number of preforked " 208 "servers: %lld", $2); 209 YYERROR; 210 } 211 conf->sc_prefork_server = $2; 212 } 213 | CHROOT STRING { 214 conf->sc_chroot = $2; 215 } 216 | ERRDOCS STRING { 217 if ($2 != NULL && strlcpy(conf->sc_errdocroot, $2, 218 sizeof(conf->sc_errdocroot)) >= 219 sizeof(conf->sc_errdocroot)) { 220 yyerror("errdoc root path too long"); 221 free($2); 222 YYERROR; 223 } 224 free($2); 225 conf->sc_custom_errdocs = 1; 226 } 227 | LOGDIR STRING { 228 conf->sc_logdir = $2; 229 } 230 | DEFAULT TYPE mediastring { 231 memcpy(&conf->sc_default_type, &media, 232 sizeof(struct media_type)); 233 } 234 ; 235 236 server : SERVER optmatch STRING { 237 struct server *s; 238 struct sockaddr_un *sun; 239 240 if (!loadcfg) { 241 free($3); 242 YYACCEPT; 243 } 244 245 if ((s = calloc(1, sizeof (*s))) == NULL) 246 fatal("out of memory"); 247 248 if (strlcpy(s->srv_conf.name, $3, 249 sizeof(s->srv_conf.name)) >= 250 sizeof(s->srv_conf.name)) { 251 yyerror("server name truncated"); 252 free($3); 253 free(s); 254 YYERROR; 255 } 256 free($3); 257 258 strlcpy(s->srv_conf.root, HTTPD_DOCROOT, 259 sizeof(s->srv_conf.root)); 260 strlcpy(s->srv_conf.index, HTTPD_INDEX, 261 sizeof(s->srv_conf.index)); 262 strlcpy(s->srv_conf.accesslog, HTTPD_ACCESS_LOG, 263 sizeof(s->srv_conf.accesslog)); 264 strlcpy(s->srv_conf.errorlog, HTTPD_ERROR_LOG, 265 sizeof(s->srv_conf.errorlog)); 266 s->srv_conf.id = ++last_server_id; 267 s->srv_conf.parent_id = s->srv_conf.id; 268 s->srv_s = -1; 269 s->srv_conf.timeout.tv_sec = SERVER_TIMEOUT; 270 s->srv_conf.requesttimeout.tv_sec = 271 SERVER_REQUESTTIMEOUT; 272 s->srv_conf.maxrequests = SERVER_MAXREQUESTS; 273 s->srv_conf.maxrequestbody = SERVER_MAXREQUESTBODY; 274 s->srv_conf.flags = SRVFLAG_LOG; 275 if ($2) 276 s->srv_conf.flags |= SRVFLAG_SERVER_MATCH; 277 s->srv_conf.logformat = LOG_FORMAT_COMMON; 278 s->srv_conf.tls_protocols = TLS_PROTOCOLS_DEFAULT; 279 if ((s->srv_conf.tls_cert_file = 280 strdup(HTTPD_TLS_CERT)) == NULL) 281 fatal("out of memory"); 282 if ((s->srv_conf.tls_key_file = 283 strdup(HTTPD_TLS_KEY)) == NULL) 284 fatal("out of memory"); 285 strlcpy(s->srv_conf.tls_ciphers, 286 HTTPD_TLS_CIPHERS, 287 sizeof(s->srv_conf.tls_ciphers)); 288 strlcpy(s->srv_conf.tls_dhe_params, 289 HTTPD_TLS_DHE_PARAMS, 290 sizeof(s->srv_conf.tls_dhe_params)); 291 strlcpy(s->srv_conf.tls_ecdhe_curves, 292 HTTPD_TLS_ECDHE_CURVES, 293 sizeof(s->srv_conf.tls_ecdhe_curves)); 294 295 sun = (struct sockaddr_un *)&s->srv_conf.fastcgi_ss; 296 sun->sun_family = AF_UNIX; 297 (void)strlcpy(sun->sun_path, HTTPD_FCGI_SOCKET, 298 sizeof(sun->sun_path)); 299 sun->sun_len = sizeof(struct sockaddr_un); 300 301 s->srv_conf.hsts_max_age = SERVER_HSTS_DEFAULT_AGE; 302 303 (void)strlcpy(s->srv_conf.errdocroot, 304 conf->sc_errdocroot, 305 sizeof(s->srv_conf.errdocroot)); 306 if (conf->sc_custom_errdocs) 307 s->srv_conf.flags |= SRVFLAG_ERRDOCS; 308 309 if (last_server_id == INT_MAX) { 310 yyerror("too many servers defined"); 311 free(s); 312 YYERROR; 313 } 314 srv = s; 315 srv_conf = &srv->srv_conf; 316 317 SPLAY_INIT(&srv->srv_clients); 318 TAILQ_INIT(&srv->srv_hosts); 319 TAILQ_INIT(&srv_conf->fcgiparams); 320 321 TAILQ_INSERT_TAIL(&srv->srv_hosts, srv_conf, entry); 322 } '{' optnl serveropts_l '}' { 323 struct server *s, *sn; 324 struct server_config *a, *b; 325 326 srv_conf = &srv->srv_conf; 327 328 /* Check if the new server already exists. */ 329 if (server_match(srv, 1) != NULL) { 330 yyerror("server \"%s\" defined twice", 331 srv->srv_conf.name); 332 serverconfig_free(srv_conf); 333 free(srv); 334 YYABORT; 335 } 336 337 if (srv->srv_conf.ss.ss_family == AF_UNSPEC) { 338 yyerror("listen address not specified"); 339 serverconfig_free(srv_conf); 340 free(srv); 341 YYERROR; 342 } 343 344 if ((s = server_match(srv, 0)) != NULL) { 345 if ((s->srv_conf.flags & SRVFLAG_TLS) != 346 (srv->srv_conf.flags & SRVFLAG_TLS)) { 347 yyerror("server \"%s\": tls and " 348 "non-tls on same address/port", 349 srv->srv_conf.name); 350 serverconfig_free(srv_conf); 351 free(srv); 352 YYERROR; 353 } 354 if (srv->srv_conf.flags & SRVFLAG_TLS && 355 server_tls_cmp(s, srv) != 0) { 356 yyerror("server \"%s\": tls " 357 "configuration mismatch on same " 358 "address/port", 359 srv->srv_conf.name); 360 serverconfig_free(srv_conf); 361 free(srv); 362 YYERROR; 363 } 364 } 365 366 if ((srv->srv_conf.flags & SRVFLAG_TLS) && 367 srv->srv_conf.tls_protocols == 0) { 368 yyerror("server \"%s\": no tls protocols", 369 srv->srv_conf.name); 370 serverconfig_free(srv_conf); 371 free(srv); 372 YYERROR; 373 } 374 375 if (server_tls_load_keypair(srv) == -1) { 376 /* Soft fail as there may be no certificate. */ 377 log_warnx("%s:%d: server \"%s\": failed to " 378 "load public/private keys", file->name, 379 yylval.lineno, srv->srv_conf.name); 380 381 remove_locations(srv_conf); 382 serverconfig_free(srv_conf); 383 srv_conf = NULL; 384 free(srv); 385 srv = NULL; 386 break; 387 } 388 389 if (server_tls_load_ca(srv) == -1) { 390 yyerror("server \"%s\": failed to load " 391 "ca cert(s)", srv->srv_conf.name); 392 serverconfig_free(srv_conf); 393 free(srv); 394 YYERROR; 395 } 396 397 if (server_tls_load_crl(srv) == -1) { 398 yyerror("server \"%s\": failed to load crl(s)", 399 srv->srv_conf.name); 400 serverconfig_free(srv_conf); 401 free(srv); 402 YYERROR; 403 } 404 405 if (server_tls_load_ocsp(srv) == -1) { 406 yyerror("server \"%s\": failed to load " 407 "ocsp staple", srv->srv_conf.name); 408 serverconfig_free(srv_conf); 409 free(srv); 410 YYERROR; 411 } 412 413 DPRINTF("adding server \"%s[%u]\"", 414 srv->srv_conf.name, srv->srv_conf.id); 415 416 TAILQ_INSERT_TAIL(conf->sc_servers, srv, srv_entry); 417 418 /* 419 * Add aliases and additional listen addresses as 420 * individual servers. 421 */ 422 TAILQ_FOREACH(a, &srv->srv_hosts, entry) { 423 /* listen address */ 424 if (a->ss.ss_family == AF_UNSPEC) 425 continue; 426 TAILQ_FOREACH(b, &srv->srv_hosts, entry) { 427 /* alias name */ 428 if (*b->name == '\0' || 429 (b == &srv->srv_conf && b == a)) 430 continue; 431 432 if ((sn = server_inherit(srv, 433 b, a)) == NULL) { 434 serverconfig_free(srv_conf); 435 free(srv); 436 YYABORT; 437 } 438 439 DPRINTF("adding server \"%s[%u]\"", 440 sn->srv_conf.name, sn->srv_conf.id); 441 442 TAILQ_INSERT_TAIL(conf->sc_servers, 443 sn, srv_entry); 444 } 445 } 446 447 /* Remove temporary aliases */ 448 TAILQ_FOREACH_SAFE(a, &srv->srv_hosts, entry, b) { 449 TAILQ_REMOVE(&srv->srv_hosts, a, entry); 450 if (a == &srv->srv_conf) 451 continue; 452 serverconfig_free(a); 453 free(a); 454 } 455 456 srv = NULL; 457 srv_conf = NULL; 458 } 459 ; 460 461 serveropts_l : serveropts_l serveroptsl nl 462 | serveroptsl optnl 463 ; 464 465 serveroptsl : LISTEN ON STRING opttls port { 466 if (listen_on($3, $4, &$5) == -1) { 467 free($3); 468 YYERROR; 469 } 470 free($3); 471 } 472 | ALIAS optmatch STRING { 473 struct server_config *alias; 474 475 if (parentsrv != NULL) { 476 yyerror("alias inside location"); 477 free($3); 478 YYERROR; 479 } 480 481 if ((alias = calloc(1, sizeof(*alias))) == NULL) 482 fatal("out of memory"); 483 484 if (strlcpy(alias->name, $3, sizeof(alias->name)) >= 485 sizeof(alias->name)) { 486 yyerror("server alias truncated"); 487 free($3); 488 free(alias); 489 YYERROR; 490 } 491 free($3); 492 493 if ($2) 494 alias->flags |= SRVFLAG_SERVER_MATCH; 495 496 TAILQ_INSERT_TAIL(&srv->srv_hosts, alias, entry); 497 } 498 | ERRDOCS STRING { 499 if (parentsrv != NULL) { 500 yyerror("errdocs inside location"); 501 YYERROR; 502 } 503 if ($2 != NULL && strlcpy(srv->srv_conf.errdocroot, $2, 504 sizeof(srv->srv_conf.errdocroot)) >= 505 sizeof(srv->srv_conf.errdocroot)) { 506 yyerror("errdoc root path too long"); 507 free($2); 508 YYERROR; 509 } 510 free($2); 511 srv->srv_conf.flags |= SRVFLAG_ERRDOCS; 512 } 513 | NO ERRDOCS { 514 if (parentsrv != NULL) { 515 yyerror("errdocs inside location"); 516 YYERROR; 517 } 518 srv->srv_conf.flags &= ~SRVFLAG_ERRDOCS; 519 } 520 | tcpip { 521 if (parentsrv != NULL) { 522 yyerror("tcp flags inside location"); 523 YYERROR; 524 } 525 } 526 | connection { 527 if (parentsrv != NULL) { 528 yyerror("connection options inside location"); 529 YYERROR; 530 } 531 } 532 | tls { 533 struct server_config *sc; 534 int tls_flag = 0; 535 536 if (parentsrv != NULL) { 537 yyerror("tls configuration inside location"); 538 YYERROR; 539 } 540 541 /* Ensure that at least one server has TLS enabled. */ 542 TAILQ_FOREACH(sc, &srv->srv_hosts, entry) { 543 tls_flag |= (sc->flags & SRVFLAG_TLS); 544 } 545 if (tls_flag == 0) { 546 yyerror("tls options without tls listener"); 547 YYERROR; 548 } 549 } 550 | request 551 | root 552 | directory 553 | logformat 554 | fastcgi 555 | authenticate 556 | gzip_static 557 | filter 558 | LOCATION optfound optmatch STRING { 559 struct server *s; 560 struct sockaddr_un *sun; 561 562 if (srv->srv_conf.ss.ss_family == AF_UNSPEC) { 563 yyerror("listen address not specified"); 564 free($4); 565 YYERROR; 566 } 567 568 if (parentsrv != NULL) { 569 yyerror("location %s inside location", $4); 570 free($4); 571 YYERROR; 572 } 573 574 if (!loadcfg) { 575 free($4); 576 YYACCEPT; 577 } 578 579 if ((s = calloc(1, sizeof (*s))) == NULL) 580 fatal("out of memory"); 581 582 if (strlcpy(s->srv_conf.location, $4, 583 sizeof(s->srv_conf.location)) >= 584 sizeof(s->srv_conf.location)) { 585 yyerror("server location truncated"); 586 free($4); 587 free(s); 588 YYERROR; 589 } 590 free($4); 591 592 if (strlcpy(s->srv_conf.name, srv->srv_conf.name, 593 sizeof(s->srv_conf.name)) >= 594 sizeof(s->srv_conf.name)) { 595 yyerror("server name truncated"); 596 free(s); 597 YYERROR; 598 } 599 600 sun = (struct sockaddr_un *)&s->srv_conf.fastcgi_ss; 601 sun->sun_family = AF_UNIX; 602 (void)strlcpy(sun->sun_path, HTTPD_FCGI_SOCKET, 603 sizeof(sun->sun_path)); 604 sun->sun_len = sizeof(struct sockaddr_un); 605 606 s->srv_conf.id = ++last_server_id; 607 /* A location entry uses the parent id */ 608 s->srv_conf.parent_id = srv->srv_conf.id; 609 s->srv_conf.flags = SRVFLAG_LOCATION; 610 if ($2 == 1) { 611 s->srv_conf.flags &= 612 ~SRVFLAG_LOCATION_NOT_FOUND; 613 s->srv_conf.flags |= 614 SRVFLAG_LOCATION_FOUND; 615 } else if ($2 == -1) { 616 s->srv_conf.flags &= 617 ~SRVFLAG_LOCATION_FOUND; 618 s->srv_conf.flags |= 619 SRVFLAG_LOCATION_NOT_FOUND; 620 } 621 if ($3) 622 s->srv_conf.flags |= SRVFLAG_LOCATION_MATCH; 623 s->srv_s = -1; 624 memcpy(&s->srv_conf.ss, &srv->srv_conf.ss, 625 sizeof(s->srv_conf.ss)); 626 s->srv_conf.port = srv->srv_conf.port; 627 s->srv_conf.prefixlen = srv->srv_conf.prefixlen; 628 s->srv_conf.tls_flags = srv->srv_conf.tls_flags; 629 630 if (last_server_id == INT_MAX) { 631 yyerror("too many servers/locations defined"); 632 free(s); 633 YYERROR; 634 } 635 parentsrv = srv; 636 srv = s; 637 srv_conf = &srv->srv_conf; 638 SPLAY_INIT(&srv->srv_clients); 639 } '{' optnl serveropts_l '}' { 640 struct server *s = NULL; 641 uint32_t f; 642 643 f = SRVFLAG_LOCATION_FOUND | 644 SRVFLAG_LOCATION_NOT_FOUND; 645 646 TAILQ_FOREACH(s, conf->sc_servers, srv_entry) { 647 /* Compare locations of same parent server */ 648 if ((s->srv_conf.flags & SRVFLAG_LOCATION) && 649 s->srv_conf.parent_id == 650 srv_conf->parent_id && 651 (s->srv_conf.flags & f) == 652 (srv_conf->flags & f) && 653 strcmp(s->srv_conf.location, 654 srv_conf->location) == 0) 655 break; 656 } 657 if (s != NULL) { 658 yyerror("location \"%s\" defined twice", 659 srv->srv_conf.location); 660 serverconfig_free(srv_conf); 661 free(srv); 662 YYABORT; 663 } 664 665 DPRINTF("adding location \"%s\" for \"%s[%u]\"", 666 srv->srv_conf.location, 667 srv->srv_conf.name, srv->srv_conf.id); 668 669 TAILQ_INSERT_TAIL(conf->sc_servers, srv, srv_entry); 670 671 srv = parentsrv; 672 srv_conf = &parentsrv->srv_conf; 673 parentsrv = NULL; 674 } 675 | DEFAULT TYPE mediastring { 676 srv_conf->flags |= SRVFLAG_DEFAULT_TYPE; 677 memcpy(&srv_conf->default_type, &media, 678 sizeof(struct media_type)); 679 } 680 | include 681 | hsts { 682 if (parentsrv != NULL) { 683 yyerror("hsts inside location"); 684 YYERROR; 685 } 686 srv->srv_conf.flags |= SRVFLAG_SERVER_HSTS; 687 } 688 ; 689 690 optfound : /* empty */ { $$ = 0; } 691 | FOUND { $$ = 1; } 692 | NOT FOUND { $$ = -1; } 693 ; 694 695 hsts : HSTS '{' optnl hstsflags_l '}' 696 | HSTS hstsflags 697 | HSTS 698 ; 699 700 hstsflags_l : hstsflags optcommanl hstsflags_l 701 | hstsflags optnl 702 ; 703 704 hstsflags : MAXAGE NUMBER { 705 if ($2 < 0 || $2 > INT_MAX) { 706 yyerror("invalid number of seconds: %lld", $2); 707 YYERROR; 708 } 709 srv_conf->hsts_max_age = $2; 710 } 711 | SUBDOMAINS { 712 srv->srv_conf.hsts_flags |= HSTSFLAG_SUBDOMAINS; 713 } 714 | PRELOAD { 715 srv->srv_conf.hsts_flags |= HSTSFLAG_PRELOAD; 716 } 717 ; 718 719 fastcgi : NO FCGI { 720 srv_conf->flags &= ~SRVFLAG_FCGI; 721 srv_conf->flags |= SRVFLAG_NO_FCGI; 722 } 723 | FCGI { 724 srv_conf->flags &= ~SRVFLAG_NO_FCGI; 725 srv_conf->flags |= SRVFLAG_FCGI; 726 } 727 | FCGI { 728 srv_conf->flags &= ~SRVFLAG_NO_FCGI; 729 srv_conf->flags |= SRVFLAG_FCGI; 730 } '{' optnl fcgiflags_l '}' 731 | FCGI { 732 srv_conf->flags &= ~SRVFLAG_NO_FCGI; 733 srv_conf->flags |= SRVFLAG_FCGI; 734 } fcgiflags 735 ; 736 737 fcgiflags_l : fcgiflags optcommanl fcgiflags_l 738 | fcgiflags optnl 739 ; 740 741 fcgiflags : SOCKET STRING { 742 struct sockaddr_un *sun; 743 sun = (struct sockaddr_un *)&srv_conf->fastcgi_ss; 744 memset(sun, 0, sizeof(*sun)); 745 sun->sun_family = AF_UNIX; 746 if (strlcpy(sun->sun_path, $2, sizeof(sun->sun_path)) 747 >= sizeof(sun->sun_path)) { 748 yyerror("socket path too long"); 749 free($2); 750 YYERROR; 751 } 752 srv_conf->fastcgi_ss.ss_len = 753 sizeof(struct sockaddr_un); 754 free($2); 755 } 756 | SOCKET TCP STRING { 757 if (get_fastcgi_dest(srv_conf, $3, FCGI_DEFAULT_PORT) 758 == -1) { 759 free($3); 760 YYERROR; 761 } 762 free($3); 763 } 764 | SOCKET TCP STRING fcgiport { 765 if (get_fastcgi_dest(srv_conf, $3, $4) == -1) { 766 free($3); 767 free($4); 768 YYERROR; 769 } 770 free($3); 771 free($4); 772 } 773 | PARAM STRING STRING { 774 struct fastcgi_param *param; 775 776 if ((param = calloc(1, sizeof(*param))) == NULL) 777 fatal("out of memory"); 778 779 if (strlcpy(param->name, $2, sizeof(param->name)) >= 780 sizeof(param->name)) { 781 yyerror("fastcgi_param name truncated"); 782 free($2); 783 free($3); 784 free(param); 785 YYERROR; 786 } 787 if (strlcpy(param->value, $3, sizeof(param->value)) >= 788 sizeof(param->value)) { 789 yyerror("fastcgi_param value truncated"); 790 free($2); 791 free($3); 792 free(param); 793 YYERROR; 794 } 795 free($2); 796 free($3); 797 798 DPRINTF("[%s,%s,%d]: adding param \"%s\" value \"%s\"", 799 srv_conf->location, srv_conf->name, srv_conf->id, 800 param->name, param->value); 801 TAILQ_INSERT_HEAD(&srv_conf->fcgiparams, param, entry); 802 } 803 | STRIP NUMBER { 804 if ($2 < 0 || $2 > INT_MAX) { 805 yyerror("invalid fastcgi strip number"); 806 YYERROR; 807 } 808 srv_conf->fcgistrip = $2; 809 } 810 ; 811 812 connection : CONNECTION '{' optnl conflags_l '}' 813 | CONNECTION conflags 814 ; 815 816 conflags_l : conflags optcommanl conflags_l 817 | conflags optnl 818 ; 819 820 conflags : TIMEOUT timeout { 821 memcpy(&srv_conf->timeout, &$2, 822 sizeof(struct timeval)); 823 } 824 | REQUEST TIMEOUT timeout { 825 memcpy(&srv_conf->requesttimeout, &$3, 826 sizeof(struct timeval)); 827 } 828 | MAXIMUM REQUESTS NUMBER { 829 srv_conf->maxrequests = $3; 830 } 831 | MAXIMUM REQUEST BODY NUMBER { 832 srv_conf->maxrequestbody = $4; 833 } 834 ; 835 836 tls : TLS '{' optnl tlsopts_l '}' 837 | TLS tlsopts 838 ; 839 840 tlsopts_l : tlsopts optcommanl tlsopts_l 841 | tlsopts optnl 842 ; 843 844 tlsopts : CERTIFICATE STRING { 845 free(srv_conf->tls_cert_file); 846 if ((srv_conf->tls_cert_file = strdup($2)) == NULL) 847 fatal("out of memory"); 848 free($2); 849 } 850 | KEY STRING { 851 free(srv_conf->tls_key_file); 852 if ((srv_conf->tls_key_file = strdup($2)) == NULL) 853 fatal("out of memory"); 854 free($2); 855 } 856 | OCSP STRING { 857 free(srv_conf->tls_ocsp_staple_file); 858 if ((srv_conf->tls_ocsp_staple_file = strdup($2)) 859 == NULL) 860 fatal("out of memory"); 861 free($2); 862 } 863 | CIPHERS STRING { 864 if (strlcpy(srv_conf->tls_ciphers, $2, 865 sizeof(srv_conf->tls_ciphers)) >= 866 sizeof(srv_conf->tls_ciphers)) { 867 yyerror("ciphers too long"); 868 free($2); 869 YYERROR; 870 } 871 free($2); 872 } 873 | CLIENT CA STRING tlsclientopt { 874 srv_conf->tls_flags |= TLSFLAG_CA; 875 free(srv_conf->tls_ca_file); 876 if ((srv_conf->tls_ca_file = strdup($3)) == NULL) 877 fatal("out of memory"); 878 free($3); 879 } 880 | DHE STRING { 881 if (strlcpy(srv_conf->tls_dhe_params, $2, 882 sizeof(srv_conf->tls_dhe_params)) >= 883 sizeof(srv_conf->tls_dhe_params)) { 884 yyerror("dhe too long"); 885 free($2); 886 YYERROR; 887 } 888 free($2); 889 } 890 | ECDHE STRING { 891 if (strlcpy(srv_conf->tls_ecdhe_curves, $2, 892 sizeof(srv_conf->tls_ecdhe_curves)) >= 893 sizeof(srv_conf->tls_ecdhe_curves)) { 894 yyerror("ecdhe too long"); 895 free($2); 896 YYERROR; 897 } 898 free($2); 899 } 900 | PROTOCOLS STRING { 901 if (tls_config_parse_protocols( 902 &srv_conf->tls_protocols, $2) != 0) { 903 yyerror("invalid tls protocols"); 904 free($2); 905 YYERROR; 906 } 907 free($2); 908 } 909 | TICKET LIFETIME DEFAULT { 910 srv_conf->tls_ticket_lifetime = SERVER_DEF_TLS_LIFETIME; 911 } 912 | TICKET LIFETIME NUMBER { 913 if ($3 != 0 && $3 < SERVER_MIN_TLS_LIFETIME) { 914 yyerror("ticket lifetime too small"); 915 YYERROR; 916 } 917 if ($3 > SERVER_MAX_TLS_LIFETIME) { 918 yyerror("ticket lifetime too large"); 919 YYERROR; 920 } 921 srv_conf->tls_ticket_lifetime = $3; 922 } 923 | NO TICKET { 924 srv_conf->tls_ticket_lifetime = 0; 925 } 926 ; 927 928 tlsclientopt : /* empty */ 929 | tlsclientopt CRL STRING { 930 srv_conf->tls_flags = TLSFLAG_CRL; 931 free(srv_conf->tls_crl_file); 932 if ((srv_conf->tls_crl_file = strdup($3)) == NULL) 933 fatal("out of memory"); 934 free($3); 935 } 936 | tlsclientopt OPTIONAL { 937 srv_conf->tls_flags |= TLSFLAG_OPTIONAL; 938 } 939 ; 940 root : ROOT rootflags 941 | ROOT '{' optnl rootflags_l '}' 942 ; 943 944 rootflags_l : rootflags optcommanl rootflags_l 945 | rootflags optnl 946 ; 947 948 rootflags : STRING { 949 if (strlcpy(srv->srv_conf.root, $1, 950 sizeof(srv->srv_conf.root)) >= 951 sizeof(srv->srv_conf.root)) { 952 yyerror("document root too long"); 953 free($1); 954 YYERROR; 955 } 956 free($1); 957 srv->srv_conf.flags |= SRVFLAG_ROOT; 958 } 959 ; 960 961 request : REQUEST requestflags 962 | REQUEST '{' optnl requestflags_l '}' 963 ; 964 965 requestflags_l : requestflags optcommanl requestflags_l 966 | requestflags optnl 967 ; 968 969 requestflags : REWRITE STRING { 970 if (strlcpy(srv->srv_conf.path, $2, 971 sizeof(srv->srv_conf.path)) >= 972 sizeof(srv->srv_conf.path)) { 973 yyerror("request path too long"); 974 free($2); 975 YYERROR; 976 } 977 free($2); 978 srv->srv_conf.flags |= SRVFLAG_PATH_REWRITE; 979 srv->srv_conf.flags &= ~SRVFLAG_NO_PATH_REWRITE; 980 } 981 | NO REWRITE { 982 srv->srv_conf.flags |= SRVFLAG_NO_PATH_REWRITE; 983 srv->srv_conf.flags &= ~SRVFLAG_PATH_REWRITE; 984 } 985 | STRIP NUMBER { 986 if ($2 < 0 || $2 > INT_MAX) { 987 yyerror("invalid strip number"); 988 YYERROR; 989 } 990 srv->srv_conf.strip = $2; 991 } 992 ; 993 994 authenticate : NO AUTHENTICATE { 995 srv->srv_conf.flags |= SRVFLAG_NO_AUTH; 996 } 997 | AUTHENTICATE authopts { 998 struct auth *auth; 999 1000 if ((auth = auth_add(conf->sc_auth, &$2)) == NULL) { 1001 yyerror("failed to add auth"); 1002 YYERROR; 1003 } 1004 1005 if (auth->auth_id == 0) { 1006 /* New htpasswd, get new Id */ 1007 auth->auth_id = ++last_auth_id; 1008 if (last_auth_id == INT_MAX) { 1009 yyerror("too many auth ids defined"); 1010 auth_free(conf->sc_auth, auth); 1011 YYERROR; 1012 } 1013 } 1014 1015 srv->srv_conf.auth_id = auth->auth_id; 1016 srv->srv_conf.flags |= SRVFLAG_AUTH; 1017 } 1018 ; 1019 1020 authopts : STRING WITH STRING { 1021 if (strlcpy(srv->srv_conf.auth_realm, $1, 1022 sizeof(srv->srv_conf.auth_realm)) >= 1023 sizeof(srv->srv_conf.auth_realm)) { 1024 yyerror("basic auth realm name too long"); 1025 free($1); 1026 YYERROR; 1027 } 1028 free($1); 1029 if (strlcpy($$.auth_htpasswd, $3, 1030 sizeof($$.auth_htpasswd)) >= 1031 sizeof($$.auth_htpasswd)) { 1032 yyerror("password file name too long"); 1033 free($3); 1034 YYERROR; 1035 } 1036 free($3); 1037 1038 } 1039 | WITH STRING { 1040 if (strlcpy($$.auth_htpasswd, $2, 1041 sizeof($$.auth_htpasswd)) >= 1042 sizeof($$.auth_htpasswd)) { 1043 yyerror("password file name too long"); 1044 free($2); 1045 YYERROR; 1046 } 1047 free($2); 1048 }; 1049 1050 directory : DIRECTORY dirflags 1051 | DIRECTORY '{' optnl dirflags_l '}' 1052 ; 1053 1054 dirflags_l : dirflags optcommanl dirflags_l 1055 | dirflags optnl 1056 ; 1057 1058 dirflags : INDEX STRING { 1059 if (strlcpy(srv_conf->index, $2, 1060 sizeof(srv_conf->index)) >= 1061 sizeof(srv_conf->index)) { 1062 yyerror("index file too long"); 1063 free($2); 1064 YYERROR; 1065 } 1066 srv_conf->flags &= ~SRVFLAG_NO_INDEX; 1067 srv_conf->flags |= SRVFLAG_INDEX; 1068 free($2); 1069 } 1070 | NO INDEX { 1071 srv_conf->flags &= ~SRVFLAG_INDEX; 1072 srv_conf->flags |= SRVFLAG_NO_INDEX; 1073 } 1074 | AUTO INDEX { 1075 srv_conf->flags &= ~SRVFLAG_NO_AUTO_INDEX; 1076 srv_conf->flags |= SRVFLAG_AUTO_INDEX; 1077 } 1078 | NO AUTO INDEX { 1079 srv_conf->flags &= ~SRVFLAG_AUTO_INDEX; 1080 srv_conf->flags |= SRVFLAG_NO_AUTO_INDEX; 1081 } 1082 ; 1083 1084 1085 logformat : LOG logflags 1086 | LOG '{' optnl logflags_l '}' 1087 | NO LOG { 1088 srv_conf->flags &= ~SRVFLAG_LOG; 1089 srv_conf->flags |= SRVFLAG_NO_LOG; 1090 } 1091 ; 1092 1093 logflags_l : logflags optcommanl logflags_l 1094 | logflags optnl 1095 ; 1096 1097 logflags : STYLE logstyle 1098 | SYSLOG { 1099 srv_conf->flags &= ~SRVFLAG_NO_SYSLOG; 1100 srv_conf->flags |= SRVFLAG_SYSLOG; 1101 } 1102 | NO SYSLOG { 1103 srv_conf->flags &= ~SRVFLAG_SYSLOG; 1104 srv_conf->flags |= SRVFLAG_NO_SYSLOG; 1105 } 1106 | ACCESS STRING { 1107 if (strlcpy(srv_conf->accesslog, $2, 1108 sizeof(srv_conf->accesslog)) >= 1109 sizeof(srv_conf->accesslog)) { 1110 yyerror("access log name too long"); 1111 free($2); 1112 YYERROR; 1113 } 1114 free($2); 1115 srv_conf->flags |= SRVFLAG_ACCESS_LOG; 1116 } 1117 | ERR STRING { 1118 if (strlcpy(srv_conf->errorlog, $2, 1119 sizeof(srv_conf->errorlog)) >= 1120 sizeof(srv_conf->errorlog)) { 1121 yyerror("error log name too long"); 1122 free($2); 1123 YYERROR; 1124 } 1125 free($2); 1126 srv_conf->flags |= SRVFLAG_ERROR_LOG; 1127 } 1128 ; 1129 1130 logstyle : COMMON { 1131 srv_conf->flags &= ~SRVFLAG_NO_LOG; 1132 srv_conf->flags |= SRVFLAG_LOG; 1133 srv_conf->logformat = LOG_FORMAT_COMMON; 1134 } 1135 | COMBINED { 1136 srv_conf->flags &= ~SRVFLAG_NO_LOG; 1137 srv_conf->flags |= SRVFLAG_LOG; 1138 srv_conf->logformat = LOG_FORMAT_COMBINED; 1139 } 1140 | CONNECTION { 1141 srv_conf->flags &= ~SRVFLAG_NO_LOG; 1142 srv_conf->flags |= SRVFLAG_LOG; 1143 srv_conf->logformat = LOG_FORMAT_CONNECTION; 1144 } 1145 | FORWARDED { 1146 srv_conf->flags &= ~SRVFLAG_NO_LOG; 1147 srv_conf->flags |= SRVFLAG_LOG; 1148 srv_conf->logformat = LOG_FORMAT_FORWARDED; 1149 } 1150 ; 1151 1152 filter : block RETURN NUMBER optstring { 1153 if ($3 <= 0 || server_httperror_byid($3) == NULL) { 1154 yyerror("invalid return code: %lld", $3); 1155 free($4); 1156 YYERROR; 1157 } 1158 srv_conf->return_code = $3; 1159 1160 if ($4 != NULL) { 1161 /* Only for 3xx redirection headers */ 1162 if ($3 < 300 || $3 > 399) { 1163 yyerror("invalid return code for " 1164 "location URI"); 1165 free($4); 1166 YYERROR; 1167 } 1168 srv_conf->return_uri = $4; 1169 srv_conf->return_uri_len = strlen($4) + 1; 1170 } 1171 } 1172 | block DROP { 1173 /* No return code, silently drop the connection */ 1174 srv_conf->return_code = 0; 1175 } 1176 | block { 1177 /* Forbidden */ 1178 srv_conf->return_code = 403; 1179 } 1180 | PASS { 1181 srv_conf->flags &= ~SRVFLAG_BLOCK; 1182 srv_conf->flags |= SRVFLAG_NO_BLOCK; 1183 } 1184 ; 1185 1186 block : BLOCK { 1187 srv_conf->flags &= ~SRVFLAG_NO_BLOCK; 1188 srv_conf->flags |= SRVFLAG_BLOCK; 1189 } 1190 ; 1191 1192 optmatch : /* empty */ { $$ = 0; } 1193 | MATCH { $$ = 1; } 1194 ; 1195 1196 optstring : /* empty */ { $$ = NULL; } 1197 | STRING { $$ = $1; } 1198 ; 1199 1200 fcgiport : NUMBER { 1201 if ($1 <= 0 || $1 > (int)USHRT_MAX) { 1202 yyerror("invalid port: %lld", $1); 1203 YYERROR; 1204 } 1205 if (asprintf(&$$, "%lld", $1) == -1) { 1206 yyerror("out of memory"); 1207 YYERROR; 1208 } 1209 } 1210 | STRING { 1211 if (getservice($1) <= 0) { 1212 yyerror("invalid port: %s", $1); 1213 free($1); 1214 YYERROR; 1215 } 1216 1217 $$ = $1; 1218 } 1219 ; 1220 1221 gzip_static : NO GZIPSTATIC { 1222 srv->srv_conf.flags &= ~SRVFLAG_GZIP_STATIC; 1223 } 1224 | GZIPSTATIC { 1225 srv->srv_conf.flags |= SRVFLAG_GZIP_STATIC; 1226 } 1227 ; 1228 1229 tcpip : TCP '{' optnl tcpflags_l '}' 1230 | TCP tcpflags 1231 ; 1232 1233 tcpflags_l : tcpflags optcommanl tcpflags_l 1234 | tcpflags optnl 1235 ; 1236 1237 tcpflags : SACK { srv_conf->tcpflags |= TCPFLAG_SACK; } 1238 | NO SACK { srv_conf->tcpflags |= TCPFLAG_NSACK; } 1239 | NODELAY { 1240 srv_conf->tcpflags |= TCPFLAG_NODELAY; 1241 } 1242 | NO NODELAY { 1243 srv_conf->tcpflags |= TCPFLAG_NNODELAY; 1244 } 1245 | BACKLOG NUMBER { 1246 if ($2 < 0 || $2 > SERVER_MAX_CLIENTS) { 1247 yyerror("invalid backlog: %lld", $2); 1248 YYERROR; 1249 } 1250 srv_conf->tcpbacklog = $2; 1251 } 1252 | SOCKET BUFFER NUMBER { 1253 srv_conf->tcpflags |= TCPFLAG_BUFSIZ; 1254 if ((srv_conf->tcpbufsiz = $3) < 0) { 1255 yyerror("invalid socket buffer size: %lld", $3); 1256 YYERROR; 1257 } 1258 } 1259 | IP STRING NUMBER { 1260 if ($3 < 0) { 1261 yyerror("invalid ttl: %lld", $3); 1262 free($2); 1263 YYERROR; 1264 } 1265 if (strcasecmp("ttl", $2) == 0) { 1266 srv_conf->tcpflags |= TCPFLAG_IPTTL; 1267 srv_conf->tcpipttl = $3; 1268 } else if (strcasecmp("minttl", $2) == 0) { 1269 srv_conf->tcpflags |= TCPFLAG_IPMINTTL; 1270 srv_conf->tcpipminttl = $3; 1271 } else { 1272 yyerror("invalid TCP/IP flag: %s", $2); 1273 free($2); 1274 YYERROR; 1275 } 1276 free($2); 1277 } 1278 ; 1279 1280 types : TYPES '{' optnl mediaopts_l '}' 1281 ; 1282 1283 mediaopts_l : mediaopts_l mediaoptsl nl 1284 | mediaoptsl nl 1285 ; 1286 1287 mediaoptsl : mediastring medianames_l optsemicolon 1288 | include 1289 ; 1290 1291 mediastring : STRING '/' STRING { 1292 if (strlcpy(media.media_type, $1, 1293 sizeof(media.media_type)) >= 1294 sizeof(media.media_type) || 1295 strlcpy(media.media_subtype, $3, 1296 sizeof(media.media_subtype)) >= 1297 sizeof(media.media_subtype)) { 1298 yyerror("media type too long"); 1299 free($1); 1300 free($3); 1301 YYERROR; 1302 } 1303 free($1); 1304 free($3); 1305 } 1306 ; 1307 1308 medianames_l : medianames_l medianamesl 1309 | medianamesl 1310 ; 1311 1312 medianamesl : numberstring { 1313 if (strlcpy(media.media_name, $1, 1314 sizeof(media.media_name)) >= 1315 sizeof(media.media_name)) { 1316 yyerror("media name too long"); 1317 free($1); 1318 YYERROR; 1319 } 1320 free($1); 1321 1322 if (!loadcfg) 1323 break; 1324 1325 if (media_add(conf->sc_mediatypes, &media) == NULL) { 1326 yyerror("failed to add media type"); 1327 YYERROR; 1328 } 1329 } 1330 ; 1331 1332 port : PORT NUMBER { 1333 if ($2 <= 0 || $2 > (int)USHRT_MAX) { 1334 yyerror("invalid port: %lld", $2); 1335 YYERROR; 1336 } 1337 $$.val[0] = htons($2); 1338 $$.op = 1; 1339 } 1340 | PORT STRING { 1341 int val; 1342 1343 if ((val = getservice($2)) == -1) { 1344 yyerror("invalid port: %s", $2); 1345 free($2); 1346 YYERROR; 1347 } 1348 free($2); 1349 1350 $$.val[0] = val; 1351 $$.op = 1; 1352 } 1353 ; 1354 1355 timeout : NUMBER 1356 { 1357 if ($1 < 0) { 1358 yyerror("invalid timeout: %lld", $1); 1359 YYERROR; 1360 } 1361 $$.tv_sec = $1; 1362 $$.tv_usec = 0; 1363 } 1364 ; 1365 1366 numberstring : NUMBER { 1367 char *s; 1368 if (asprintf(&s, "%lld", $1) == -1) { 1369 yyerror("asprintf: number"); 1370 YYERROR; 1371 } 1372 $$ = s; 1373 } 1374 | STRING 1375 ; 1376 1377 optsemicolon : ';' 1378 | 1379 ; 1380 1381 optnl : '\n' optnl 1382 | 1383 ; 1384 1385 optcommanl : ',' optnl 1386 | nl 1387 ; 1388 1389 nl : '\n' optnl 1390 ; 1391 1392 %% 1393 1394 struct keywords { 1395 const char *k_name; 1396 int k_val; 1397 }; 1398 1399 int 1400 yyerror(const char *fmt, ...) 1401 { 1402 va_list ap; 1403 char *msg; 1404 1405 file->errors++; 1406 va_start(ap, fmt); 1407 if (vasprintf(&msg, fmt, ap) == -1) 1408 fatalx("yyerror vasprintf"); 1409 va_end(ap); 1410 logit(LOG_CRIT, "%s:%d: %s", file->name, yylval.lineno, msg); 1411 free(msg); 1412 return (0); 1413 } 1414 1415 int 1416 kw_cmp(const void *k, const void *e) 1417 { 1418 return (strcmp(k, ((const struct keywords *)e)->k_name)); 1419 } 1420 1421 int 1422 lookup(char *s) 1423 { 1424 /* this has to be sorted always */ 1425 static const struct keywords keywords[] = { 1426 { "access", ACCESS }, 1427 { "alias", ALIAS }, 1428 { "authenticate", AUTHENTICATE}, 1429 { "auto", AUTO }, 1430 { "backlog", BACKLOG }, 1431 { "block", BLOCK }, 1432 { "body", BODY }, 1433 { "buffer", BUFFER }, 1434 { "ca", CA }, 1435 { "certificate", CERTIFICATE }, 1436 { "chroot", CHROOT }, 1437 { "ciphers", CIPHERS }, 1438 { "client", CLIENT }, 1439 { "combined", COMBINED }, 1440 { "common", COMMON }, 1441 { "connection", CONNECTION }, 1442 { "crl", CRL }, 1443 { "default", DEFAULT }, 1444 { "dhe", DHE }, 1445 { "directory", DIRECTORY }, 1446 { "drop", DROP }, 1447 { "ecdhe", ECDHE }, 1448 { "errdocs", ERRDOCS }, 1449 { "error", ERR }, 1450 { "fastcgi", FCGI }, 1451 { "forwarded", FORWARDED }, 1452 { "found", FOUND }, 1453 { "gzip-static", GZIPSTATIC }, 1454 { "hsts", HSTS }, 1455 { "include", INCLUDE }, 1456 { "index", INDEX }, 1457 { "ip", IP }, 1458 { "key", KEY }, 1459 { "lifetime", LIFETIME }, 1460 { "listen", LISTEN }, 1461 { "location", LOCATION }, 1462 { "log", LOG }, 1463 { "logdir", LOGDIR }, 1464 { "match", MATCH }, 1465 { "max", MAXIMUM }, 1466 { "max-age", MAXAGE }, 1467 { "no", NO }, 1468 { "nodelay", NODELAY }, 1469 { "not", NOT }, 1470 { "ocsp", OCSP }, 1471 { "on", ON }, 1472 { "optional", OPTIONAL }, 1473 { "param", PARAM }, 1474 { "pass", PASS }, 1475 { "port", PORT }, 1476 { "prefork", PREFORK }, 1477 { "preload", PRELOAD }, 1478 { "protocols", PROTOCOLS }, 1479 { "request", REQUEST }, 1480 { "requests", REQUESTS }, 1481 { "return", RETURN }, 1482 { "rewrite", REWRITE }, 1483 { "root", ROOT }, 1484 { "sack", SACK }, 1485 { "server", SERVER }, 1486 { "socket", SOCKET }, 1487 { "strip", STRIP }, 1488 { "style", STYLE }, 1489 { "subdomains", SUBDOMAINS }, 1490 { "syslog", SYSLOG }, 1491 { "tcp", TCP }, 1492 { "ticket", TICKET }, 1493 { "timeout", TIMEOUT }, 1494 { "tls", TLS }, 1495 { "type", TYPE }, 1496 { "types", TYPES }, 1497 { "with", WITH } 1498 }; 1499 const struct keywords *p; 1500 1501 p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]), 1502 sizeof(keywords[0]), kw_cmp); 1503 1504 if (p) 1505 return (p->k_val); 1506 else 1507 return (STRING); 1508 } 1509 1510 #define START_EXPAND 1 1511 #define DONE_EXPAND 2 1512 1513 static int expanding; 1514 1515 int 1516 igetc(void) 1517 { 1518 int c; 1519 1520 while (1) { 1521 if (file->ungetpos > 0) 1522 c = file->ungetbuf[--file->ungetpos]; 1523 else 1524 c = getc(file->stream); 1525 1526 if (c == START_EXPAND) 1527 expanding = 1; 1528 else if (c == DONE_EXPAND) 1529 expanding = 0; 1530 else 1531 break; 1532 } 1533 return (c); 1534 } 1535 1536 int 1537 lgetc(int quotec) 1538 { 1539 int c, next; 1540 1541 if (quotec) { 1542 if ((c = igetc()) == EOF) { 1543 yyerror("reached end of file while parsing " 1544 "quoted string"); 1545 if (file == topfile || popfile() == EOF) 1546 return (EOF); 1547 return (quotec); 1548 } 1549 return (c); 1550 } 1551 1552 while ((c = igetc()) == '\\') { 1553 next = igetc(); 1554 if (next != '\n') { 1555 c = next; 1556 break; 1557 } 1558 yylval.lineno = file->lineno; 1559 file->lineno++; 1560 } 1561 1562 if (c == EOF) { 1563 /* 1564 * Fake EOL when hit EOF for the first time. This gets line 1565 * count right if last line in included file is syntactically 1566 * invalid and has no newline. 1567 */ 1568 if (file->eof_reached == 0) { 1569 file->eof_reached = 1; 1570 return ('\n'); 1571 } 1572 while (c == EOF) { 1573 if (file == topfile || popfile() == EOF) 1574 return (EOF); 1575 c = igetc(); 1576 } 1577 } 1578 return (c); 1579 } 1580 1581 void 1582 lungetc(int c) 1583 { 1584 if (c == EOF) 1585 return; 1586 1587 if (file->ungetpos >= file->ungetsize) { 1588 void *p = reallocarray(file->ungetbuf, file->ungetsize, 2); 1589 if (p == NULL) 1590 err(1, "%s", __func__); 1591 file->ungetbuf = p; 1592 file->ungetsize *= 2; 1593 } 1594 file->ungetbuf[file->ungetpos++] = c; 1595 } 1596 1597 int 1598 findeol(void) 1599 { 1600 int c; 1601 1602 /* skip to either EOF or the first real EOL */ 1603 while (1) { 1604 c = lgetc(0); 1605 if (c == '\n') { 1606 file->lineno++; 1607 break; 1608 } 1609 if (c == EOF) 1610 break; 1611 } 1612 return (ERROR); 1613 } 1614 1615 int 1616 yylex(void) 1617 { 1618 char buf[8096]; 1619 char *p, *val; 1620 int quotec, next, c; 1621 int token; 1622 1623 top: 1624 p = buf; 1625 while ((c = lgetc(0)) == ' ' || c == '\t') 1626 ; /* nothing */ 1627 1628 yylval.lineno = file->lineno; 1629 if (c == '#') 1630 while ((c = lgetc(0)) != '\n' && c != EOF) 1631 ; /* nothing */ 1632 if (c == '$' && !expanding) { 1633 while (1) { 1634 if ((c = lgetc(0)) == EOF) 1635 return (0); 1636 1637 if (p + 1 >= buf + sizeof(buf) - 1) { 1638 yyerror("string too long"); 1639 return (findeol()); 1640 } 1641 if (isalnum(c) || c == '_') { 1642 *p++ = c; 1643 continue; 1644 } 1645 *p = '\0'; 1646 lungetc(c); 1647 break; 1648 } 1649 val = symget(buf); 1650 if (val == NULL) { 1651 yyerror("macro '%s' not defined", buf); 1652 return (findeol()); 1653 } 1654 p = val + strlen(val) - 1; 1655 lungetc(DONE_EXPAND); 1656 while (p >= val) { 1657 lungetc((unsigned char)*p); 1658 p--; 1659 } 1660 lungetc(START_EXPAND); 1661 goto top; 1662 } 1663 1664 switch (c) { 1665 case '\'': 1666 case '"': 1667 quotec = c; 1668 while (1) { 1669 if ((c = lgetc(quotec)) == EOF) 1670 return (0); 1671 if (c == '\n') { 1672 file->lineno++; 1673 continue; 1674 } else if (c == '\\') { 1675 if ((next = lgetc(quotec)) == EOF) 1676 return (0); 1677 if (next == quotec || next == ' ' || 1678 next == '\t') 1679 c = next; 1680 else if (next == '\n') { 1681 file->lineno++; 1682 continue; 1683 } else 1684 lungetc(next); 1685 } else if (c == quotec) { 1686 *p = '\0'; 1687 break; 1688 } else if (c == '\0') { 1689 yyerror("syntax error"); 1690 return (findeol()); 1691 } 1692 if (p + 1 >= buf + sizeof(buf) - 1) { 1693 yyerror("string too long"); 1694 return (findeol()); 1695 } 1696 *p++ = c; 1697 } 1698 yylval.v.string = strdup(buf); 1699 if (yylval.v.string == NULL) 1700 err(1, "%s", __func__); 1701 return (STRING); 1702 } 1703 1704 #define allowed_to_end_number(x) \ 1705 (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=') 1706 1707 if (c == '-' || isdigit(c)) { 1708 do { 1709 *p++ = c; 1710 if ((size_t)(p-buf) >= sizeof(buf)) { 1711 yyerror("string too long"); 1712 return (findeol()); 1713 } 1714 } while ((c = lgetc(0)) != EOF && isdigit(c)); 1715 lungetc(c); 1716 if (p == buf + 1 && buf[0] == '-') 1717 goto nodigits; 1718 if (c == EOF || allowed_to_end_number(c)) { 1719 const char *errstr = NULL; 1720 1721 *p = '\0'; 1722 yylval.v.number = strtonum(buf, LLONG_MIN, 1723 LLONG_MAX, &errstr); 1724 if (errstr) { 1725 yyerror("\"%s\" invalid number: %s", 1726 buf, errstr); 1727 return (findeol()); 1728 } 1729 return (NUMBER); 1730 } else { 1731 nodigits: 1732 while (p > buf + 1) 1733 lungetc((unsigned char)*--p); 1734 c = (unsigned char)*--p; 1735 if (c == '-') 1736 return (c); 1737 } 1738 } 1739 1740 #define allowed_in_string(x) \ 1741 (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \ 1742 x != '{' && x != '}' && x != '<' && x != '>' && \ 1743 x != '!' && x != '=' && x != '#' && \ 1744 x != ',' && x != ';' && x != '/')) 1745 1746 if (isalnum(c) || c == ':' || c == '_' || c == '*') { 1747 do { 1748 *p++ = c; 1749 if ((size_t)(p-buf) >= sizeof(buf)) { 1750 yyerror("string too long"); 1751 return (findeol()); 1752 } 1753 } while ((c = lgetc(0)) != EOF && (allowed_in_string(c))); 1754 lungetc(c); 1755 *p = '\0'; 1756 if ((token = lookup(buf)) == STRING) 1757 if ((yylval.v.string = strdup(buf)) == NULL) 1758 err(1, "%s", __func__); 1759 return (token); 1760 } 1761 if (c == '\n') { 1762 yylval.lineno = file->lineno; 1763 file->lineno++; 1764 } 1765 if (c == EOF) 1766 return (0); 1767 return (c); 1768 } 1769 1770 int 1771 check_file_secrecy(int fd, const char *fname) 1772 { 1773 struct stat st; 1774 1775 if (fstat(fd, &st)) { 1776 log_warn("cannot stat %s", fname); 1777 return (-1); 1778 } 1779 if (st.st_uid != 0 && st.st_uid != getuid()) { 1780 log_warnx("%s: owner not root or current user", fname); 1781 return (-1); 1782 } 1783 if (st.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)) { 1784 log_warnx("%s: group writable or world read/writable", fname); 1785 return (-1); 1786 } 1787 return (0); 1788 } 1789 1790 struct file * 1791 pushfile(const char *name, int secret) 1792 { 1793 struct file *nfile; 1794 1795 if ((nfile = calloc(1, sizeof(struct file))) == NULL) { 1796 log_warn("%s", __func__); 1797 return (NULL); 1798 } 1799 if ((nfile->name = strdup(name)) == NULL) { 1800 log_warn("%s", __func__); 1801 free(nfile); 1802 return (NULL); 1803 } 1804 if ((nfile->stream = fopen(nfile->name, "r")) == NULL) { 1805 log_warn("%s: %s", __func__, nfile->name); 1806 free(nfile->name); 1807 free(nfile); 1808 return (NULL); 1809 } else if (secret && 1810 check_file_secrecy(fileno(nfile->stream), nfile->name)) { 1811 fclose(nfile->stream); 1812 free(nfile->name); 1813 free(nfile); 1814 return (NULL); 1815 } 1816 nfile->lineno = TAILQ_EMPTY(&files) ? 1 : 0; 1817 nfile->ungetsize = 16; 1818 nfile->ungetbuf = malloc(nfile->ungetsize); 1819 if (nfile->ungetbuf == NULL) { 1820 log_warn("%s", __func__); 1821 fclose(nfile->stream); 1822 free(nfile->name); 1823 free(nfile); 1824 return (NULL); 1825 } 1826 TAILQ_INSERT_TAIL(&files, nfile, entry); 1827 return (nfile); 1828 } 1829 1830 int 1831 popfile(void) 1832 { 1833 struct file *prev; 1834 1835 if ((prev = TAILQ_PREV(file, files, entry)) != NULL) 1836 prev->errors += file->errors; 1837 1838 TAILQ_REMOVE(&files, file, entry); 1839 fclose(file->stream); 1840 free(file->name); 1841 free(file->ungetbuf); 1842 free(file); 1843 file = prev; 1844 return (file ? 0 : EOF); 1845 } 1846 1847 int 1848 parse_config(const char *filename, struct httpd *x_conf) 1849 { 1850 struct sym *sym, *next; 1851 struct media_type dflt = HTTPD_DEFAULT_TYPE; 1852 1853 conf = x_conf; 1854 if (config_init(conf) == -1) { 1855 log_warn("%s: cannot initialize configuration", __func__); 1856 return (-1); 1857 } 1858 1859 /* Set default media type */ 1860 memcpy(&conf->sc_default_type, &dflt, sizeof(struct media_type)); 1861 1862 errors = 0; 1863 1864 if ((file = pushfile(filename, 0)) == NULL) 1865 return (-1); 1866 1867 topfile = file; 1868 setservent(1); 1869 1870 yyparse(); 1871 errors = file->errors; 1872 while (popfile() != EOF) 1873 ; 1874 1875 endservent(); 1876 endprotoent(); 1877 1878 /* Free macros */ 1879 TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) { 1880 if (!sym->persist) { 1881 free(sym->nam); 1882 free(sym->val); 1883 TAILQ_REMOVE(&symhead, sym, entry); 1884 free(sym); 1885 } 1886 } 1887 1888 return (errors ? -1 : 0); 1889 } 1890 1891 int 1892 load_config(const char *filename, struct httpd *x_conf) 1893 { 1894 struct sym *sym, *next; 1895 struct http_mediatype mediatypes[] = MEDIA_TYPES; 1896 struct media_type m; 1897 int i; 1898 1899 conf = x_conf; 1900 conf->sc_flags = 0; 1901 1902 loadcfg = 1; 1903 errors = 0; 1904 last_server_id = 0; 1905 last_auth_id = 0; 1906 1907 srv = NULL; 1908 1909 if ((file = pushfile(filename, 0)) == NULL) 1910 return (-1); 1911 1912 topfile = file; 1913 setservent(1); 1914 1915 yyparse(); 1916 errors = file->errors; 1917 popfile(); 1918 1919 endservent(); 1920 endprotoent(); 1921 1922 /* Free macros and check which have not been used. */ 1923 for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) { 1924 next = TAILQ_NEXT(sym, entry); 1925 if ((conf->sc_opts & HTTPD_OPT_VERBOSE) && !sym->used) 1926 fprintf(stderr, "warning: macro '%s' not " 1927 "used\n", sym->nam); 1928 if (!sym->persist) { 1929 free(sym->nam); 1930 free(sym->val); 1931 TAILQ_REMOVE(&symhead, sym, entry); 1932 free(sym); 1933 } 1934 } 1935 1936 if (TAILQ_EMPTY(conf->sc_servers)) { 1937 log_warnx("no actions, nothing to do"); 1938 errors++; 1939 } 1940 1941 if (RB_EMPTY(conf->sc_mediatypes)) { 1942 /* Add default media types */ 1943 for (i = 0; mediatypes[i].media_name != NULL; i++) { 1944 (void)strlcpy(m.media_name, mediatypes[i].media_name, 1945 sizeof(m.media_name)); 1946 (void)strlcpy(m.media_type, mediatypes[i].media_type, 1947 sizeof(m.media_type)); 1948 (void)strlcpy(m.media_subtype, 1949 mediatypes[i].media_subtype, 1950 sizeof(m.media_subtype)); 1951 m.media_encoding = NULL; 1952 1953 if (media_add(conf->sc_mediatypes, &m) == NULL) { 1954 log_warnx("failed to add default media \"%s\"", 1955 m.media_name); 1956 errors++; 1957 } 1958 } 1959 } 1960 1961 return (errors ? -1 : 0); 1962 } 1963 1964 int 1965 symset(const char *nam, const char *val, int persist) 1966 { 1967 struct sym *sym; 1968 1969 TAILQ_FOREACH(sym, &symhead, entry) { 1970 if (strcmp(nam, sym->nam) == 0) 1971 break; 1972 } 1973 1974 if (sym != NULL) { 1975 if (sym->persist == 1) 1976 return (0); 1977 else { 1978 free(sym->nam); 1979 free(sym->val); 1980 TAILQ_REMOVE(&symhead, sym, entry); 1981 free(sym); 1982 } 1983 } 1984 if ((sym = calloc(1, sizeof(*sym))) == NULL) 1985 return (-1); 1986 1987 sym->nam = strdup(nam); 1988 if (sym->nam == NULL) { 1989 free(sym); 1990 return (-1); 1991 } 1992 sym->val = strdup(val); 1993 if (sym->val == NULL) { 1994 free(sym->nam); 1995 free(sym); 1996 return (-1); 1997 } 1998 sym->used = 0; 1999 sym->persist = persist; 2000 TAILQ_INSERT_TAIL(&symhead, sym, entry); 2001 return (0); 2002 } 2003 2004 int 2005 cmdline_symset(char *s) 2006 { 2007 char *sym, *val; 2008 int ret; 2009 2010 if ((val = strrchr(s, '=')) == NULL) 2011 return (-1); 2012 sym = strndup(s, val - s); 2013 if (sym == NULL) 2014 errx(1, "%s: strndup", __func__); 2015 ret = symset(sym, val + 1, 1); 2016 free(sym); 2017 2018 return (ret); 2019 } 2020 2021 char * 2022 symget(const char *nam) 2023 { 2024 struct sym *sym; 2025 2026 TAILQ_FOREACH(sym, &symhead, entry) { 2027 if (strcmp(nam, sym->nam) == 0) { 2028 sym->used = 1; 2029 return (sym->val); 2030 } 2031 } 2032 return (NULL); 2033 } 2034 2035 struct address * 2036 host_v4(const char *s) 2037 { 2038 struct in_addr ina; 2039 struct sockaddr_in *sain; 2040 struct address *h; 2041 2042 memset(&ina, 0, sizeof(ina)); 2043 if (inet_pton(AF_INET, s, &ina) != 1) 2044 return (NULL); 2045 2046 if ((h = calloc(1, sizeof(*h))) == NULL) 2047 fatal(__func__); 2048 sain = (struct sockaddr_in *)&h->ss; 2049 sain->sin_len = sizeof(struct sockaddr_in); 2050 sain->sin_family = AF_INET; 2051 sain->sin_addr.s_addr = ina.s_addr; 2052 if (sain->sin_addr.s_addr == INADDR_ANY) 2053 h->prefixlen = 0; /* 0.0.0.0 address */ 2054 else 2055 h->prefixlen = -1; /* host address */ 2056 return (h); 2057 } 2058 2059 struct address * 2060 host_v6(const char *s) 2061 { 2062 struct addrinfo hints, *res; 2063 struct sockaddr_in6 *sa_in6; 2064 struct address *h = NULL; 2065 2066 memset(&hints, 0, sizeof(hints)); 2067 hints.ai_family = AF_INET6; 2068 hints.ai_socktype = SOCK_DGRAM; /* dummy */ 2069 hints.ai_flags = AI_NUMERICHOST; 2070 if (getaddrinfo(s, "0", &hints, &res) == 0) { 2071 if ((h = calloc(1, sizeof(*h))) == NULL) 2072 fatal(__func__); 2073 sa_in6 = (struct sockaddr_in6 *)&h->ss; 2074 sa_in6->sin6_len = sizeof(struct sockaddr_in6); 2075 sa_in6->sin6_family = AF_INET6; 2076 memcpy(&sa_in6->sin6_addr, 2077 &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 2078 sizeof(sa_in6->sin6_addr)); 2079 sa_in6->sin6_scope_id = 2080 ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id; 2081 if (memcmp(&sa_in6->sin6_addr, &in6addr_any, 2082 sizeof(sa_in6->sin6_addr)) == 0) 2083 h->prefixlen = 0; /* any address */ 2084 else 2085 h->prefixlen = -1; /* host address */ 2086 freeaddrinfo(res); 2087 } 2088 2089 return (h); 2090 } 2091 2092 int 2093 host_dns(const char *s, struct addresslist *al, int max, 2094 struct portrange *port, const char *ifname, int ipproto) 2095 { 2096 struct addrinfo hints, *res0, *res; 2097 int error, cnt = 0; 2098 struct sockaddr_in *sain; 2099 struct sockaddr_in6 *sin6; 2100 struct address *h; 2101 2102 if ((cnt = host_if(s, al, max, port, ifname, ipproto)) != 0) 2103 return (cnt); 2104 2105 memset(&hints, 0, sizeof(hints)); 2106 hints.ai_family = PF_UNSPEC; 2107 hints.ai_socktype = SOCK_DGRAM; /* DUMMY */ 2108 hints.ai_flags = AI_ADDRCONFIG; 2109 error = getaddrinfo(s, NULL, &hints, &res0); 2110 if (error == EAI_AGAIN || error == EAI_NODATA || error == EAI_NONAME) 2111 return (0); 2112 if (error) { 2113 log_warnx("%s: could not parse \"%s\": %s", __func__, s, 2114 gai_strerror(error)); 2115 return (-1); 2116 } 2117 2118 for (res = res0; res && cnt < max; res = res->ai_next) { 2119 if (res->ai_family != AF_INET && 2120 res->ai_family != AF_INET6) 2121 continue; 2122 if ((h = calloc(1, sizeof(*h))) == NULL) 2123 fatal(__func__); 2124 2125 if (port != NULL) 2126 memcpy(&h->port, port, sizeof(h->port)); 2127 if (ifname != NULL) { 2128 if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >= 2129 sizeof(h->ifname)) 2130 log_warnx("%s: interface name truncated", 2131 __func__); 2132 freeaddrinfo(res0); 2133 free(h); 2134 return (-1); 2135 } 2136 if (ipproto != -1) 2137 h->ipproto = ipproto; 2138 h->ss.ss_family = res->ai_family; 2139 h->prefixlen = -1; /* host address */ 2140 2141 if (res->ai_family == AF_INET) { 2142 sain = (struct sockaddr_in *)&h->ss; 2143 sain->sin_len = sizeof(struct sockaddr_in); 2144 sain->sin_addr.s_addr = ((struct sockaddr_in *) 2145 res->ai_addr)->sin_addr.s_addr; 2146 } else { 2147 sin6 = (struct sockaddr_in6 *)&h->ss; 2148 sin6->sin6_len = sizeof(struct sockaddr_in6); 2149 memcpy(&sin6->sin6_addr, &((struct sockaddr_in6 *) 2150 res->ai_addr)->sin6_addr, sizeof(struct in6_addr)); 2151 } 2152 2153 TAILQ_INSERT_HEAD(al, h, entry); 2154 cnt++; 2155 } 2156 if (cnt == max && res) { 2157 log_warnx("%s: %s resolves to more than %d hosts", __func__, 2158 s, max); 2159 } 2160 freeaddrinfo(res0); 2161 return (cnt); 2162 } 2163 2164 int 2165 host_if(const char *s, struct addresslist *al, int max, 2166 struct portrange *port, const char *ifname, int ipproto) 2167 { 2168 struct ifaddrs *ifap, *p; 2169 struct sockaddr_in *sain; 2170 struct sockaddr_in6 *sin6; 2171 struct address *h; 2172 int cnt = 0, af; 2173 2174 if (getifaddrs(&ifap) == -1) 2175 fatal("getifaddrs"); 2176 2177 /* First search for IPv4 addresses */ 2178 af = AF_INET; 2179 2180 nextaf: 2181 for (p = ifap; p != NULL && cnt < max; p = p->ifa_next) { 2182 if (p->ifa_addr == NULL || 2183 p->ifa_addr->sa_family != af || 2184 (strcmp(s, p->ifa_name) != 0 && 2185 !is_if_in_group(p->ifa_name, s))) 2186 continue; 2187 if ((h = calloc(1, sizeof(*h))) == NULL) 2188 fatal("calloc"); 2189 2190 if (port != NULL) 2191 memcpy(&h->port, port, sizeof(h->port)); 2192 if (ifname != NULL) { 2193 if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >= 2194 sizeof(h->ifname)) 2195 log_warnx("%s: interface name truncated", 2196 __func__); 2197 freeifaddrs(ifap); 2198 free(h); 2199 return (-1); 2200 } 2201 if (ipproto != -1) 2202 h->ipproto = ipproto; 2203 h->ss.ss_family = af; 2204 h->prefixlen = -1; /* host address */ 2205 2206 if (af == AF_INET) { 2207 sain = (struct sockaddr_in *)&h->ss; 2208 sain->sin_len = sizeof(struct sockaddr_in); 2209 sain->sin_addr.s_addr = ((struct sockaddr_in *) 2210 p->ifa_addr)->sin_addr.s_addr; 2211 } else { 2212 sin6 = (struct sockaddr_in6 *)&h->ss; 2213 sin6->sin6_len = sizeof(struct sockaddr_in6); 2214 memcpy(&sin6->sin6_addr, &((struct sockaddr_in6 *) 2215 p->ifa_addr)->sin6_addr, sizeof(struct in6_addr)); 2216 sin6->sin6_scope_id = ((struct sockaddr_in6 *) 2217 p->ifa_addr)->sin6_scope_id; 2218 } 2219 2220 TAILQ_INSERT_HEAD(al, h, entry); 2221 cnt++; 2222 } 2223 if (af == AF_INET) { 2224 /* Next search for IPv6 addresses */ 2225 af = AF_INET6; 2226 goto nextaf; 2227 } 2228 2229 if (cnt > max) { 2230 log_warnx("%s: %s resolves to more than %d hosts", __func__, 2231 s, max); 2232 } 2233 freeifaddrs(ifap); 2234 return (cnt); 2235 } 2236 2237 int 2238 host(const char *s, struct addresslist *al, int max, 2239 struct portrange *port, const char *ifname, int ipproto) 2240 { 2241 struct address *h; 2242 2243 h = host_v4(s); 2244 2245 /* IPv6 address? */ 2246 if (h == NULL) 2247 h = host_v6(s); 2248 2249 if (h != NULL) { 2250 if (port != NULL) 2251 memcpy(&h->port, port, sizeof(h->port)); 2252 if (ifname != NULL) { 2253 if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >= 2254 sizeof(h->ifname)) { 2255 log_warnx("%s: interface name truncated", 2256 __func__); 2257 free(h); 2258 return (-1); 2259 } 2260 } 2261 if (ipproto != -1) 2262 h->ipproto = ipproto; 2263 2264 TAILQ_INSERT_HEAD(al, h, entry); 2265 return (1); 2266 } 2267 2268 return (host_dns(s, al, max, port, ifname, ipproto)); 2269 } 2270 2271 struct server * 2272 server_inherit(struct server *src, struct server_config *alias, 2273 struct server_config *addr) 2274 { 2275 struct server *dst, *s, *dstl; 2276 2277 if ((dst = calloc(1, sizeof(*dst))) == NULL) 2278 fatal("out of memory"); 2279 2280 /* Copy the source server and assign a new Id */ 2281 memcpy(&dst->srv_conf, &src->srv_conf, sizeof(dst->srv_conf)); 2282 if ((dst->srv_conf.tls_cert_file = 2283 strdup(src->srv_conf.tls_cert_file)) == NULL) 2284 fatal("out of memory"); 2285 if ((dst->srv_conf.tls_key_file = 2286 strdup(src->srv_conf.tls_key_file)) == NULL) 2287 fatal("out of memory"); 2288 if (src->srv_conf.tls_ocsp_staple_file != NULL) { 2289 if ((dst->srv_conf.tls_ocsp_staple_file = 2290 strdup(src->srv_conf.tls_ocsp_staple_file)) == NULL) 2291 fatal("out of memory"); 2292 } 2293 2294 if (src->srv_conf.return_uri != NULL && 2295 (dst->srv_conf.return_uri = 2296 strdup(src->srv_conf.return_uri)) == NULL) 2297 fatal("out of memory"); 2298 2299 dst->srv_conf.id = ++last_server_id; 2300 dst->srv_conf.parent_id = dst->srv_conf.id; 2301 dst->srv_s = -1; 2302 2303 if (last_server_id == INT_MAX) { 2304 yyerror("too many servers defined"); 2305 serverconfig_free(&dst->srv_conf); 2306 free(dst); 2307 return (NULL); 2308 } 2309 2310 /* Now set alias and listen address */ 2311 strlcpy(dst->srv_conf.name, alias->name, sizeof(dst->srv_conf.name)); 2312 memcpy(&dst->srv_conf.ss, &addr->ss, sizeof(dst->srv_conf.ss)); 2313 dst->srv_conf.port = addr->port; 2314 dst->srv_conf.prefixlen = addr->prefixlen; 2315 if (addr->flags & SRVFLAG_TLS) 2316 dst->srv_conf.flags |= SRVFLAG_TLS; 2317 else 2318 dst->srv_conf.flags &= ~SRVFLAG_TLS; 2319 2320 /* Don't inherit the "match" option, use it from the alias */ 2321 dst->srv_conf.flags &= ~SRVFLAG_SERVER_MATCH; 2322 dst->srv_conf.flags |= (alias->flags & SRVFLAG_SERVER_MATCH); 2323 2324 if (server_tls_load_keypair(dst) == -1) 2325 log_warnx("%s:%d: server \"%s\": failed to " 2326 "load public/private keys", file->name, 2327 yylval.lineno, dst->srv_conf.name); 2328 2329 if (server_tls_load_ca(dst) == -1) { 2330 yyerror("failed to load ca cert(s) for server %s", 2331 dst->srv_conf.name); 2332 serverconfig_free(&dst->srv_conf); 2333 return NULL; 2334 } 2335 2336 if (server_tls_load_crl(dst) == -1) { 2337 yyerror("failed to load crl(s) for server %s", 2338 dst->srv_conf.name); 2339 serverconfig_free(&dst->srv_conf); 2340 free(dst); 2341 return NULL; 2342 } 2343 2344 if (server_tls_load_ocsp(dst) == -1) { 2345 yyerror("failed to load ocsp staple " 2346 "for server %s", dst->srv_conf.name); 2347 serverconfig_free(&dst->srv_conf); 2348 free(dst); 2349 return (NULL); 2350 } 2351 2352 /* Check if the new server already exists */ 2353 if (server_match(dst, 1) != NULL) { 2354 yyerror("server \"%s\" defined twice", 2355 dst->srv_conf.name); 2356 serverconfig_free(&dst->srv_conf); 2357 free(dst); 2358 return (NULL); 2359 } 2360 2361 /* Copy all the locations of the source server */ 2362 TAILQ_FOREACH(s, conf->sc_servers, srv_entry) { 2363 if (!(s->srv_conf.flags & SRVFLAG_LOCATION && 2364 s->srv_conf.parent_id == src->srv_conf.parent_id)) 2365 continue; 2366 2367 if ((dstl = calloc(1, sizeof(*dstl))) == NULL) 2368 fatal("out of memory"); 2369 2370 memcpy(&dstl->srv_conf, &s->srv_conf, sizeof(dstl->srv_conf)); 2371 strlcpy(dstl->srv_conf.name, alias->name, 2372 sizeof(dstl->srv_conf.name)); 2373 2374 /* Copy the new Id and listen address */ 2375 dstl->srv_conf.id = ++last_server_id; 2376 dstl->srv_conf.parent_id = dst->srv_conf.id; 2377 memcpy(&dstl->srv_conf.ss, &addr->ss, 2378 sizeof(dstl->srv_conf.ss)); 2379 dstl->srv_conf.port = addr->port; 2380 dstl->srv_conf.prefixlen = addr->prefixlen; 2381 dstl->srv_s = -1; 2382 2383 DPRINTF("adding location \"%s\" for \"%s[%u]\"", 2384 dstl->srv_conf.location, 2385 dstl->srv_conf.name, dstl->srv_conf.id); 2386 2387 TAILQ_INSERT_TAIL(conf->sc_servers, dstl, srv_entry); 2388 } 2389 2390 return (dst); 2391 } 2392 2393 int 2394 listen_on(const char *addr, int tls, struct portrange *port) 2395 { 2396 struct addresslist al; 2397 struct address *h; 2398 struct server_config *s_conf, *alias = NULL; 2399 2400 if (parentsrv != NULL) { 2401 yyerror("listen %s inside location", addr); 2402 return (-1); 2403 } 2404 2405 TAILQ_INIT(&al); 2406 if (strcmp("*", addr) == 0) { 2407 if (host("0.0.0.0", &al, 1, port, NULL, -1) <= 0) { 2408 yyerror("invalid listen ip: %s", 2409 "0.0.0.0"); 2410 return (-1); 2411 } 2412 if (host("::", &al, 1, port, NULL, -1) <= 0) { 2413 yyerror("invalid listen ip: %s", "::"); 2414 return (-1); 2415 } 2416 } else { 2417 if (host(addr, &al, HTTPD_MAX_ALIAS_IP, port, NULL, 2418 -1) <= 0) { 2419 yyerror("invalid listen ip: %s", addr); 2420 return (-1); 2421 } 2422 } 2423 2424 while ((h = TAILQ_FIRST(&al)) != NULL) { 2425 if (srv->srv_conf.ss.ss_family != AF_UNSPEC) { 2426 if ((alias = calloc(1, 2427 sizeof(*alias))) == NULL) 2428 fatal("out of memory"); 2429 /* Add as an IP-based alias. */ 2430 s_conf = alias; 2431 } else 2432 s_conf = &srv->srv_conf; 2433 memcpy(&s_conf->ss, &h->ss, sizeof(s_conf->ss)); 2434 s_conf->prefixlen = h->prefixlen; 2435 /* Set the default port to 80 or 443 */ 2436 if (!h->port.op) 2437 s_conf->port = htons(tls ? 2438 HTTPS_PORT : HTTP_PORT); 2439 else 2440 s_conf->port = h->port.val[0]; 2441 2442 if (tls) 2443 s_conf->flags |= SRVFLAG_TLS; 2444 2445 if (alias != NULL) { 2446 /* 2447 * IP-based; use name match flags from 2448 * parent 2449 */ 2450 alias->flags &= ~SRVFLAG_SERVER_MATCH; 2451 alias->flags |= srv->srv_conf.flags & 2452 SRVFLAG_SERVER_MATCH; 2453 TAILQ_INSERT_TAIL(&srv->srv_hosts, 2454 alias, entry); 2455 } 2456 TAILQ_REMOVE(&al, h, entry); 2457 free(h); 2458 } 2459 2460 return (0); 2461 } 2462 2463 int 2464 getservice(char *n) 2465 { 2466 struct servent *s; 2467 const char *errstr; 2468 long long llval; 2469 2470 llval = strtonum(n, 0, UINT16_MAX, &errstr); 2471 if (errstr) { 2472 s = getservbyname(n, "tcp"); 2473 if (s == NULL) 2474 s = getservbyname(n, "udp"); 2475 if (s == NULL) 2476 return (-1); 2477 return (s->s_port); 2478 } 2479 2480 return (htons((unsigned short)llval)); 2481 } 2482 2483 int 2484 is_if_in_group(const char *ifname, const char *groupname) 2485 { 2486 unsigned int len; 2487 struct ifgroupreq ifgr; 2488 struct ifg_req *ifg; 2489 int s; 2490 int ret = 0; 2491 2492 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 2493 err(1, "socket"); 2494 2495 memset(&ifgr, 0, sizeof(ifgr)); 2496 if (strlcpy(ifgr.ifgr_name, ifname, IFNAMSIZ) >= IFNAMSIZ) 2497 err(1, "IFNAMSIZ"); 2498 if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) { 2499 if (errno == EINVAL || errno == ENOTTY) 2500 goto end; 2501 err(1, "SIOCGIFGROUP"); 2502 } 2503 2504 len = ifgr.ifgr_len; 2505 ifgr.ifgr_groups = calloc(len / sizeof(struct ifg_req), 2506 sizeof(struct ifg_req)); 2507 if (ifgr.ifgr_groups == NULL) 2508 err(1, "getifgroups"); 2509 if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) 2510 err(1, "SIOCGIFGROUP"); 2511 2512 ifg = ifgr.ifgr_groups; 2513 for (; ifg && len >= sizeof(struct ifg_req); ifg++) { 2514 len -= sizeof(struct ifg_req); 2515 if (strcmp(ifg->ifgrq_group, groupname) == 0) { 2516 ret = 1; 2517 break; 2518 } 2519 } 2520 free(ifgr.ifgr_groups); 2521 2522 end: 2523 close(s); 2524 return (ret); 2525 } 2526 2527 int 2528 get_fastcgi_dest(struct server_config *xsrv_conf, const char *node, char *port) 2529 { 2530 struct addrinfo hints, *res; 2531 int s; 2532 2533 memset(&hints, 0, sizeof(hints)); 2534 hints.ai_family = AF_UNSPEC; 2535 hints.ai_socktype = SOCK_STREAM; 2536 2537 if ((s = getaddrinfo(node, port, &hints, &res)) != 0) { 2538 yyerror("getaddrinfo: %s\n", gai_strerror(s)); 2539 return -1; 2540 } 2541 2542 memset(&(xsrv_conf)->fastcgi_ss, 0, sizeof(xsrv_conf->fastcgi_ss)); 2543 memcpy(&(xsrv_conf)->fastcgi_ss, res->ai_addr, res->ai_addrlen); 2544 2545 freeaddrinfo(res); 2546 2547 return (0); 2548 } 2549 2550 void 2551 remove_locations(struct server_config *xsrv_conf) 2552 { 2553 struct server *s, *next; 2554 2555 TAILQ_FOREACH_SAFE(s, conf->sc_servers, srv_entry, next) { 2556 if (!(s->srv_conf.flags & SRVFLAG_LOCATION && 2557 s->srv_conf.parent_id == xsrv_conf->parent_id)) 2558 continue; 2559 TAILQ_REMOVE(conf->sc_servers, s, srv_entry); 2560 serverconfig_free(&s->srv_conf); 2561 free(s); 2562 } 2563 } 2564