1 /* $OpenBSD: parse.y,v 1.127 2021/10/24 16:01:04 ian 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 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 | filter 557 | LOCATION optfound optmatch STRING { 558 struct server *s; 559 struct sockaddr_un *sun; 560 561 if (srv->srv_conf.ss.ss_family == AF_UNSPEC) { 562 yyerror("listen address not specified"); 563 free($4); 564 YYERROR; 565 } 566 567 if (parentsrv != NULL) { 568 yyerror("location %s inside location", $4); 569 free($4); 570 YYERROR; 571 } 572 573 if (!loadcfg) { 574 free($4); 575 YYACCEPT; 576 } 577 578 if ((s = calloc(1, sizeof (*s))) == NULL) 579 fatal("out of memory"); 580 581 if (strlcpy(s->srv_conf.location, $4, 582 sizeof(s->srv_conf.location)) >= 583 sizeof(s->srv_conf.location)) { 584 yyerror("server location truncated"); 585 free($4); 586 free(s); 587 YYERROR; 588 } 589 free($4); 590 591 if (strlcpy(s->srv_conf.name, srv->srv_conf.name, 592 sizeof(s->srv_conf.name)) >= 593 sizeof(s->srv_conf.name)) { 594 yyerror("server name truncated"); 595 free(s); 596 YYERROR; 597 } 598 599 sun = (struct sockaddr_un *)&s->srv_conf.fastcgi_ss; 600 sun->sun_family = AF_UNIX; 601 (void)strlcpy(sun->sun_path, HTTPD_FCGI_SOCKET, 602 sizeof(sun->sun_path)); 603 sun->sun_len = sizeof(struct sockaddr_un); 604 605 s->srv_conf.id = ++last_server_id; 606 /* A location entry uses the parent id */ 607 s->srv_conf.parent_id = srv->srv_conf.id; 608 s->srv_conf.flags = SRVFLAG_LOCATION; 609 if ($2 == 1) { 610 s->srv_conf.flags &= 611 ~SRVFLAG_LOCATION_NOT_FOUND; 612 s->srv_conf.flags |= 613 SRVFLAG_LOCATION_FOUND; 614 } else if ($2 == -1) { 615 s->srv_conf.flags &= 616 ~SRVFLAG_LOCATION_FOUND; 617 s->srv_conf.flags |= 618 SRVFLAG_LOCATION_NOT_FOUND; 619 } 620 if ($3) 621 s->srv_conf.flags |= SRVFLAG_LOCATION_MATCH; 622 s->srv_s = -1; 623 memcpy(&s->srv_conf.ss, &srv->srv_conf.ss, 624 sizeof(s->srv_conf.ss)); 625 s->srv_conf.port = srv->srv_conf.port; 626 s->srv_conf.prefixlen = srv->srv_conf.prefixlen; 627 s->srv_conf.tls_flags = srv->srv_conf.tls_flags; 628 629 if (last_server_id == INT_MAX) { 630 yyerror("too many servers/locations defined"); 631 free(s); 632 YYERROR; 633 } 634 parentsrv = srv; 635 srv = s; 636 srv_conf = &srv->srv_conf; 637 SPLAY_INIT(&srv->srv_clients); 638 } '{' optnl serveropts_l '}' { 639 struct server *s = NULL; 640 uint32_t f; 641 642 f = SRVFLAG_LOCATION_FOUND | 643 SRVFLAG_LOCATION_NOT_FOUND; 644 645 TAILQ_FOREACH(s, conf->sc_servers, srv_entry) { 646 /* Compare locations of same parent server */ 647 if ((s->srv_conf.flags & SRVFLAG_LOCATION) && 648 s->srv_conf.parent_id == 649 srv_conf->parent_id && 650 (s->srv_conf.flags & f) == 651 (srv_conf->flags & f) && 652 strcmp(s->srv_conf.location, 653 srv_conf->location) == 0) 654 break; 655 } 656 if (s != NULL) { 657 yyerror("location \"%s\" defined twice", 658 srv->srv_conf.location); 659 serverconfig_free(srv_conf); 660 free(srv); 661 YYABORT; 662 } 663 664 DPRINTF("adding location \"%s\" for \"%s[%u]\"", 665 srv->srv_conf.location, 666 srv->srv_conf.name, srv->srv_conf.id); 667 668 TAILQ_INSERT_TAIL(conf->sc_servers, srv, srv_entry); 669 670 srv = parentsrv; 671 srv_conf = &parentsrv->srv_conf; 672 parentsrv = NULL; 673 } 674 | DEFAULT TYPE mediastring { 675 srv_conf->flags |= SRVFLAG_DEFAULT_TYPE; 676 memcpy(&srv_conf->default_type, &media, 677 sizeof(struct media_type)); 678 } 679 | include 680 | hsts { 681 if (parentsrv != NULL) { 682 yyerror("hsts inside location"); 683 YYERROR; 684 } 685 srv->srv_conf.flags |= SRVFLAG_SERVER_HSTS; 686 } 687 ; 688 689 optfound : /* empty */ { $$ = 0; } 690 | FOUND { $$ = 1; } 691 | NOT FOUND { $$ = -1; } 692 ; 693 694 hsts : HSTS '{' optnl hstsflags_l '}' 695 | HSTS hstsflags 696 | HSTS 697 ; 698 699 hstsflags_l : hstsflags optcommanl hstsflags_l 700 | hstsflags optnl 701 ; 702 703 hstsflags : MAXAGE NUMBER { 704 if ($2 < 0 || $2 > INT_MAX) { 705 yyerror("invalid number of seconds: %lld", $2); 706 YYERROR; 707 } 708 srv_conf->hsts_max_age = $2; 709 } 710 | SUBDOMAINS { 711 srv->srv_conf.hsts_flags |= HSTSFLAG_SUBDOMAINS; 712 } 713 | PRELOAD { 714 srv->srv_conf.hsts_flags |= HSTSFLAG_PRELOAD; 715 } 716 ; 717 718 fastcgi : NO FCGI { 719 srv_conf->flags &= ~SRVFLAG_FCGI; 720 srv_conf->flags |= SRVFLAG_NO_FCGI; 721 } 722 | FCGI { 723 srv_conf->flags &= ~SRVFLAG_NO_FCGI; 724 srv_conf->flags |= SRVFLAG_FCGI; 725 } 726 | FCGI { 727 srv_conf->flags &= ~SRVFLAG_NO_FCGI; 728 srv_conf->flags |= SRVFLAG_FCGI; 729 } '{' optnl fcgiflags_l '}' 730 | FCGI { 731 srv_conf->flags &= ~SRVFLAG_NO_FCGI; 732 srv_conf->flags |= SRVFLAG_FCGI; 733 } fcgiflags 734 ; 735 736 fcgiflags_l : fcgiflags optcommanl fcgiflags_l 737 | fcgiflags optnl 738 ; 739 740 fcgiflags : SOCKET STRING { 741 struct sockaddr_un *sun; 742 sun = (struct sockaddr_un *)&srv_conf->fastcgi_ss; 743 memset(sun, 0, sizeof(*sun)); 744 sun->sun_family = AF_UNIX; 745 if (strlcpy(sun->sun_path, $2, sizeof(sun->sun_path)) 746 >= sizeof(sun->sun_path)) { 747 yyerror("socket path too long"); 748 free($2); 749 YYERROR; 750 } 751 srv_conf->fastcgi_ss.ss_len = 752 sizeof(struct sockaddr_un); 753 free($2); 754 } 755 | SOCKET TCP STRING { 756 if (get_fastcgi_dest(srv_conf, $3, FCGI_DEFAULT_PORT) 757 == -1) { 758 free($3); 759 YYERROR; 760 } 761 free($3); 762 } 763 | SOCKET TCP STRING fcgiport { 764 if (get_fastcgi_dest(srv_conf, $3, $4) == -1) { 765 free($3); 766 free($4); 767 YYERROR; 768 } 769 free($3); 770 free($4); 771 } 772 | PARAM STRING STRING { 773 struct fastcgi_param *param; 774 775 if ((param = calloc(1, sizeof(*param))) == NULL) 776 fatal("out of memory"); 777 778 if (strlcpy(param->name, $2, sizeof(param->name)) >= 779 sizeof(param->name)) { 780 yyerror("fastcgi_param name truncated"); 781 free($2); 782 free($3); 783 free(param); 784 YYERROR; 785 } 786 if (strlcpy(param->value, $3, sizeof(param->value)) >= 787 sizeof(param->value)) { 788 yyerror("fastcgi_param value truncated"); 789 free($2); 790 free($3); 791 free(param); 792 YYERROR; 793 } 794 free($2); 795 free($3); 796 797 DPRINTF("[%s,%s,%d]: adding param \"%s\" value \"%s\"", 798 srv_conf->location, srv_conf->name, srv_conf->id, 799 param->name, param->value); 800 TAILQ_INSERT_HEAD(&srv_conf->fcgiparams, param, entry); 801 } 802 | STRIP NUMBER { 803 if ($2 < 0 || $2 > INT_MAX) { 804 yyerror("invalid fastcgi strip number"); 805 YYERROR; 806 } 807 srv_conf->fcgistrip = $2; 808 } 809 ; 810 811 connection : CONNECTION '{' optnl conflags_l '}' 812 | CONNECTION conflags 813 ; 814 815 conflags_l : conflags optcommanl conflags_l 816 | conflags optnl 817 ; 818 819 conflags : TIMEOUT timeout { 820 memcpy(&srv_conf->timeout, &$2, 821 sizeof(struct timeval)); 822 } 823 | REQUEST TIMEOUT timeout { 824 memcpy(&srv_conf->requesttimeout, &$3, 825 sizeof(struct timeval)); 826 } 827 | MAXIMUM REQUESTS NUMBER { 828 srv_conf->maxrequests = $3; 829 } 830 | MAXIMUM REQUEST BODY NUMBER { 831 srv_conf->maxrequestbody = $4; 832 } 833 ; 834 835 tls : TLS '{' optnl tlsopts_l '}' 836 | TLS tlsopts 837 ; 838 839 tlsopts_l : tlsopts optcommanl tlsopts_l 840 | tlsopts optnl 841 ; 842 843 tlsopts : CERTIFICATE STRING { 844 free(srv_conf->tls_cert_file); 845 if ((srv_conf->tls_cert_file = strdup($2)) == NULL) 846 fatal("out of memory"); 847 free($2); 848 } 849 | KEY STRING { 850 free(srv_conf->tls_key_file); 851 if ((srv_conf->tls_key_file = strdup($2)) == NULL) 852 fatal("out of memory"); 853 free($2); 854 } 855 | OCSP STRING { 856 free(srv_conf->tls_ocsp_staple_file); 857 if ((srv_conf->tls_ocsp_staple_file = strdup($2)) 858 == NULL) 859 fatal("out of memory"); 860 free($2); 861 } 862 | CIPHERS STRING { 863 if (strlcpy(srv_conf->tls_ciphers, $2, 864 sizeof(srv_conf->tls_ciphers)) >= 865 sizeof(srv_conf->tls_ciphers)) { 866 yyerror("ciphers too long"); 867 free($2); 868 YYERROR; 869 } 870 free($2); 871 } 872 | CLIENT CA STRING tlsclientopt { 873 srv_conf->tls_flags |= TLSFLAG_CA; 874 free(srv_conf->tls_ca_file); 875 if ((srv_conf->tls_ca_file = strdup($3)) == NULL) 876 fatal("out of memory"); 877 free($3); 878 } 879 | DHE STRING { 880 if (strlcpy(srv_conf->tls_dhe_params, $2, 881 sizeof(srv_conf->tls_dhe_params)) >= 882 sizeof(srv_conf->tls_dhe_params)) { 883 yyerror("dhe too long"); 884 free($2); 885 YYERROR; 886 } 887 free($2); 888 } 889 | ECDHE STRING { 890 if (strlcpy(srv_conf->tls_ecdhe_curves, $2, 891 sizeof(srv_conf->tls_ecdhe_curves)) >= 892 sizeof(srv_conf->tls_ecdhe_curves)) { 893 yyerror("ecdhe too long"); 894 free($2); 895 YYERROR; 896 } 897 free($2); 898 } 899 | PROTOCOLS STRING { 900 if (tls_config_parse_protocols( 901 &srv_conf->tls_protocols, $2) != 0) { 902 yyerror("invalid tls protocols"); 903 free($2); 904 YYERROR; 905 } 906 free($2); 907 } 908 | TICKET LIFETIME DEFAULT { 909 srv_conf->tls_ticket_lifetime = SERVER_DEF_TLS_LIFETIME; 910 } 911 | TICKET LIFETIME NUMBER { 912 if ($3 != 0 && $3 < SERVER_MIN_TLS_LIFETIME) { 913 yyerror("ticket lifetime too small"); 914 YYERROR; 915 } 916 if ($3 > SERVER_MAX_TLS_LIFETIME) { 917 yyerror("ticket lifetime too large"); 918 YYERROR; 919 } 920 srv_conf->tls_ticket_lifetime = $3; 921 } 922 | NO TICKET { 923 srv_conf->tls_ticket_lifetime = 0; 924 } 925 ; 926 927 tlsclientopt : /* empty */ 928 | tlsclientopt CRL STRING { 929 srv_conf->tls_flags = TLSFLAG_CRL; 930 free(srv_conf->tls_crl_file); 931 if ((srv_conf->tls_crl_file = strdup($3)) == NULL) 932 fatal("out of memory"); 933 free($3); 934 } 935 | tlsclientopt OPTIONAL { 936 srv_conf->tls_flags |= TLSFLAG_OPTIONAL; 937 } 938 ; 939 root : ROOT rootflags 940 | ROOT '{' optnl rootflags_l '}' 941 ; 942 943 rootflags_l : rootflags optcommanl rootflags_l 944 | rootflags optnl 945 ; 946 947 rootflags : STRING { 948 if (strlcpy(srv->srv_conf.root, $1, 949 sizeof(srv->srv_conf.root)) >= 950 sizeof(srv->srv_conf.root)) { 951 yyerror("document root too long"); 952 free($1); 953 YYERROR; 954 } 955 free($1); 956 srv->srv_conf.flags |= SRVFLAG_ROOT; 957 } 958 ; 959 960 request : REQUEST requestflags 961 | REQUEST '{' optnl requestflags_l '}' 962 ; 963 964 requestflags_l : requestflags optcommanl requestflags_l 965 | requestflags optnl 966 ; 967 968 requestflags : REWRITE STRING { 969 if (strlcpy(srv->srv_conf.path, $2, 970 sizeof(srv->srv_conf.path)) >= 971 sizeof(srv->srv_conf.path)) { 972 yyerror("request path too long"); 973 free($2); 974 YYERROR; 975 } 976 free($2); 977 srv->srv_conf.flags |= SRVFLAG_PATH_REWRITE; 978 srv->srv_conf.flags &= ~SRVFLAG_NO_PATH_REWRITE; 979 } 980 | NO REWRITE { 981 srv->srv_conf.flags |= SRVFLAG_NO_PATH_REWRITE; 982 srv->srv_conf.flags &= ~SRVFLAG_PATH_REWRITE; 983 } 984 | STRIP NUMBER { 985 if ($2 < 0 || $2 > INT_MAX) { 986 yyerror("invalid strip number"); 987 YYERROR; 988 } 989 srv->srv_conf.strip = $2; 990 } 991 ; 992 993 authenticate : NO AUTHENTICATE { 994 srv->srv_conf.flags |= SRVFLAG_NO_AUTH; 995 } 996 | AUTHENTICATE authopts { 997 struct auth *auth; 998 999 if ((auth = auth_add(conf->sc_auth, &$2)) == NULL) { 1000 yyerror("failed to add auth"); 1001 YYERROR; 1002 } 1003 1004 if (auth->auth_id == 0) { 1005 /* New htpasswd, get new Id */ 1006 auth->auth_id = ++last_auth_id; 1007 if (last_auth_id == INT_MAX) { 1008 yyerror("too many auth ids defined"); 1009 auth_free(conf->sc_auth, auth); 1010 YYERROR; 1011 } 1012 } 1013 1014 srv->srv_conf.auth_id = auth->auth_id; 1015 srv->srv_conf.flags |= SRVFLAG_AUTH; 1016 } 1017 ; 1018 1019 authopts : STRING WITH STRING { 1020 if (strlcpy(srv->srv_conf.auth_realm, $1, 1021 sizeof(srv->srv_conf.auth_realm)) >= 1022 sizeof(srv->srv_conf.auth_realm)) { 1023 yyerror("basic auth realm name too long"); 1024 free($1); 1025 YYERROR; 1026 } 1027 free($1); 1028 if (strlcpy($$.auth_htpasswd, $3, 1029 sizeof($$.auth_htpasswd)) >= 1030 sizeof($$.auth_htpasswd)) { 1031 yyerror("password file name too long"); 1032 free($3); 1033 YYERROR; 1034 } 1035 free($3); 1036 1037 } 1038 | WITH STRING { 1039 if (strlcpy($$.auth_htpasswd, $2, 1040 sizeof($$.auth_htpasswd)) >= 1041 sizeof($$.auth_htpasswd)) { 1042 yyerror("password file name too long"); 1043 free($2); 1044 YYERROR; 1045 } 1046 free($2); 1047 }; 1048 1049 directory : DIRECTORY dirflags 1050 | DIRECTORY '{' optnl dirflags_l '}' 1051 ; 1052 1053 dirflags_l : dirflags optcommanl dirflags_l 1054 | dirflags optnl 1055 ; 1056 1057 dirflags : INDEX STRING { 1058 if (strlcpy(srv_conf->index, $2, 1059 sizeof(srv_conf->index)) >= 1060 sizeof(srv_conf->index)) { 1061 yyerror("index file too long"); 1062 free($2); 1063 YYERROR; 1064 } 1065 srv_conf->flags &= ~SRVFLAG_NO_INDEX; 1066 srv_conf->flags |= SRVFLAG_INDEX; 1067 free($2); 1068 } 1069 | NO INDEX { 1070 srv_conf->flags &= ~SRVFLAG_INDEX; 1071 srv_conf->flags |= SRVFLAG_NO_INDEX; 1072 } 1073 | AUTO INDEX { 1074 srv_conf->flags &= ~SRVFLAG_NO_AUTO_INDEX; 1075 srv_conf->flags |= SRVFLAG_AUTO_INDEX; 1076 } 1077 | NO AUTO INDEX { 1078 srv_conf->flags &= ~SRVFLAG_AUTO_INDEX; 1079 srv_conf->flags |= SRVFLAG_NO_AUTO_INDEX; 1080 } 1081 ; 1082 1083 1084 logformat : LOG logflags 1085 | LOG '{' optnl logflags_l '}' 1086 | NO LOG { 1087 srv_conf->flags &= ~SRVFLAG_LOG; 1088 srv_conf->flags |= SRVFLAG_NO_LOG; 1089 } 1090 ; 1091 1092 logflags_l : logflags optcommanl logflags_l 1093 | logflags optnl 1094 ; 1095 1096 logflags : STYLE logstyle 1097 | SYSLOG { 1098 srv_conf->flags &= ~SRVFLAG_NO_SYSLOG; 1099 srv_conf->flags |= SRVFLAG_SYSLOG; 1100 } 1101 | NO SYSLOG { 1102 srv_conf->flags &= ~SRVFLAG_SYSLOG; 1103 srv_conf->flags |= SRVFLAG_NO_SYSLOG; 1104 } 1105 | ACCESS STRING { 1106 if (strlcpy(srv_conf->accesslog, $2, 1107 sizeof(srv_conf->accesslog)) >= 1108 sizeof(srv_conf->accesslog)) { 1109 yyerror("access log name too long"); 1110 free($2); 1111 YYERROR; 1112 } 1113 free($2); 1114 srv_conf->flags |= SRVFLAG_ACCESS_LOG; 1115 } 1116 | ERR STRING { 1117 if (strlcpy(srv_conf->errorlog, $2, 1118 sizeof(srv_conf->errorlog)) >= 1119 sizeof(srv_conf->errorlog)) { 1120 yyerror("error log name too long"); 1121 free($2); 1122 YYERROR; 1123 } 1124 free($2); 1125 srv_conf->flags |= SRVFLAG_ERROR_LOG; 1126 } 1127 ; 1128 1129 logstyle : COMMON { 1130 srv_conf->flags &= ~SRVFLAG_NO_LOG; 1131 srv_conf->flags |= SRVFLAG_LOG; 1132 srv_conf->logformat = LOG_FORMAT_COMMON; 1133 } 1134 | COMBINED { 1135 srv_conf->flags &= ~SRVFLAG_NO_LOG; 1136 srv_conf->flags |= SRVFLAG_LOG; 1137 srv_conf->logformat = LOG_FORMAT_COMBINED; 1138 } 1139 | CONNECTION { 1140 srv_conf->flags &= ~SRVFLAG_NO_LOG; 1141 srv_conf->flags |= SRVFLAG_LOG; 1142 srv_conf->logformat = LOG_FORMAT_CONNECTION; 1143 } 1144 | FORWARDED { 1145 srv_conf->flags &= ~SRVFLAG_NO_LOG; 1146 srv_conf->flags |= SRVFLAG_LOG; 1147 srv_conf->logformat = LOG_FORMAT_FORWARDED; 1148 } 1149 ; 1150 1151 filter : block RETURN NUMBER optstring { 1152 if ($3 <= 0 || server_httperror_byid($3) == NULL) { 1153 yyerror("invalid return code: %lld", $3); 1154 free($4); 1155 YYERROR; 1156 } 1157 srv_conf->return_code = $3; 1158 1159 if ($4 != NULL) { 1160 /* Only for 3xx redirection headers */ 1161 if ($3 < 300 || $3 > 399) { 1162 yyerror("invalid return code for " 1163 "location URI"); 1164 free($4); 1165 YYERROR; 1166 } 1167 srv_conf->return_uri = $4; 1168 srv_conf->return_uri_len = strlen($4) + 1; 1169 } 1170 } 1171 | block DROP { 1172 /* No return code, silently drop the connection */ 1173 srv_conf->return_code = 0; 1174 } 1175 | block { 1176 /* Forbidden */ 1177 srv_conf->return_code = 403; 1178 } 1179 | PASS { 1180 srv_conf->flags &= ~SRVFLAG_BLOCK; 1181 srv_conf->flags |= SRVFLAG_NO_BLOCK; 1182 } 1183 ; 1184 1185 block : BLOCK { 1186 srv_conf->flags &= ~SRVFLAG_NO_BLOCK; 1187 srv_conf->flags |= SRVFLAG_BLOCK; 1188 } 1189 ; 1190 1191 optmatch : /* empty */ { $$ = 0; } 1192 | MATCH { $$ = 1; } 1193 ; 1194 1195 optstring : /* empty */ { $$ = NULL; } 1196 | STRING { $$ = $1; } 1197 ; 1198 1199 fcgiport : NUMBER { 1200 if ($1 <= 0 || $1 > (int)USHRT_MAX) { 1201 yyerror("invalid port: %lld", $1); 1202 YYERROR; 1203 } 1204 if (asprintf(&$$, "%lld", $1) == -1) { 1205 yyerror("out of memory"); 1206 YYERROR; 1207 } 1208 } 1209 | STRING { 1210 if (getservice($1) <= 0) { 1211 yyerror("invalid port: %s", $1); 1212 free($1); 1213 YYERROR; 1214 } 1215 1216 $$ = $1; 1217 } 1218 ; 1219 1220 tcpip : TCP '{' optnl tcpflags_l '}' 1221 | TCP tcpflags 1222 ; 1223 1224 tcpflags_l : tcpflags optcommanl tcpflags_l 1225 | tcpflags optnl 1226 ; 1227 1228 tcpflags : SACK { srv_conf->tcpflags |= TCPFLAG_SACK; } 1229 | NO SACK { srv_conf->tcpflags |= TCPFLAG_NSACK; } 1230 | NODELAY { 1231 srv_conf->tcpflags |= TCPFLAG_NODELAY; 1232 } 1233 | NO NODELAY { 1234 srv_conf->tcpflags |= TCPFLAG_NNODELAY; 1235 } 1236 | BACKLOG NUMBER { 1237 if ($2 < 0 || $2 > SERVER_MAX_CLIENTS) { 1238 yyerror("invalid backlog: %lld", $2); 1239 YYERROR; 1240 } 1241 srv_conf->tcpbacklog = $2; 1242 } 1243 | SOCKET BUFFER NUMBER { 1244 srv_conf->tcpflags |= TCPFLAG_BUFSIZ; 1245 if ((srv_conf->tcpbufsiz = $3) < 0) { 1246 yyerror("invalid socket buffer size: %lld", $3); 1247 YYERROR; 1248 } 1249 } 1250 | IP STRING NUMBER { 1251 if ($3 < 0) { 1252 yyerror("invalid ttl: %lld", $3); 1253 free($2); 1254 YYERROR; 1255 } 1256 if (strcasecmp("ttl", $2) == 0) { 1257 srv_conf->tcpflags |= TCPFLAG_IPTTL; 1258 srv_conf->tcpipttl = $3; 1259 } else if (strcasecmp("minttl", $2) == 0) { 1260 srv_conf->tcpflags |= TCPFLAG_IPMINTTL; 1261 srv_conf->tcpipminttl = $3; 1262 } else { 1263 yyerror("invalid TCP/IP flag: %s", $2); 1264 free($2); 1265 YYERROR; 1266 } 1267 free($2); 1268 } 1269 ; 1270 1271 types : TYPES '{' optnl mediaopts_l '}' 1272 ; 1273 1274 mediaopts_l : mediaopts_l mediaoptsl nl 1275 | mediaoptsl nl 1276 ; 1277 1278 mediaoptsl : mediastring medianames_l optsemicolon 1279 | include 1280 ; 1281 1282 mediastring : STRING '/' STRING { 1283 if (strlcpy(media.media_type, $1, 1284 sizeof(media.media_type)) >= 1285 sizeof(media.media_type) || 1286 strlcpy(media.media_subtype, $3, 1287 sizeof(media.media_subtype)) >= 1288 sizeof(media.media_subtype)) { 1289 yyerror("media type too long"); 1290 free($1); 1291 free($3); 1292 YYERROR; 1293 } 1294 free($1); 1295 free($3); 1296 } 1297 ; 1298 1299 medianames_l : medianames_l medianamesl 1300 | medianamesl 1301 ; 1302 1303 medianamesl : numberstring { 1304 if (strlcpy(media.media_name, $1, 1305 sizeof(media.media_name)) >= 1306 sizeof(media.media_name)) { 1307 yyerror("media name too long"); 1308 free($1); 1309 YYERROR; 1310 } 1311 free($1); 1312 1313 if (!loadcfg) 1314 break; 1315 1316 if (media_add(conf->sc_mediatypes, &media) == NULL) { 1317 yyerror("failed to add media type"); 1318 YYERROR; 1319 } 1320 } 1321 ; 1322 1323 port : PORT NUMBER { 1324 if ($2 <= 0 || $2 > (int)USHRT_MAX) { 1325 yyerror("invalid port: %lld", $2); 1326 YYERROR; 1327 } 1328 $$.val[0] = htons($2); 1329 $$.op = 1; 1330 } 1331 | PORT STRING { 1332 int val; 1333 1334 if ((val = getservice($2)) == -1) { 1335 yyerror("invalid port: %s", $2); 1336 free($2); 1337 YYERROR; 1338 } 1339 free($2); 1340 1341 $$.val[0] = val; 1342 $$.op = 1; 1343 } 1344 ; 1345 1346 timeout : NUMBER 1347 { 1348 if ($1 < 0) { 1349 yyerror("invalid timeout: %lld", $1); 1350 YYERROR; 1351 } 1352 $$.tv_sec = $1; 1353 $$.tv_usec = 0; 1354 } 1355 ; 1356 1357 numberstring : NUMBER { 1358 char *s; 1359 if (asprintf(&s, "%lld", $1) == -1) { 1360 yyerror("asprintf: number"); 1361 YYERROR; 1362 } 1363 $$ = s; 1364 } 1365 | STRING 1366 ; 1367 1368 optsemicolon : ';' 1369 | 1370 ; 1371 1372 optnl : '\n' optnl 1373 | 1374 ; 1375 1376 optcommanl : ',' optnl 1377 | nl 1378 ; 1379 1380 nl : '\n' optnl 1381 ; 1382 1383 %% 1384 1385 struct keywords { 1386 const char *k_name; 1387 int k_val; 1388 }; 1389 1390 int 1391 yyerror(const char *fmt, ...) 1392 { 1393 va_list ap; 1394 char *msg; 1395 1396 file->errors++; 1397 va_start(ap, fmt); 1398 if (vasprintf(&msg, fmt, ap) == -1) 1399 fatalx("yyerror vasprintf"); 1400 va_end(ap); 1401 logit(LOG_CRIT, "%s:%d: %s", file->name, yylval.lineno, msg); 1402 free(msg); 1403 return (0); 1404 } 1405 1406 int 1407 kw_cmp(const void *k, const void *e) 1408 { 1409 return (strcmp(k, ((const struct keywords *)e)->k_name)); 1410 } 1411 1412 int 1413 lookup(char *s) 1414 { 1415 /* this has to be sorted always */ 1416 static const struct keywords keywords[] = { 1417 { "access", ACCESS }, 1418 { "alias", ALIAS }, 1419 { "authenticate", AUTHENTICATE}, 1420 { "auto", AUTO }, 1421 { "backlog", BACKLOG }, 1422 { "block", BLOCK }, 1423 { "body", BODY }, 1424 { "buffer", BUFFER }, 1425 { "ca", CA }, 1426 { "certificate", CERTIFICATE }, 1427 { "chroot", CHROOT }, 1428 { "ciphers", CIPHERS }, 1429 { "client", CLIENT }, 1430 { "combined", COMBINED }, 1431 { "common", COMMON }, 1432 { "connection", CONNECTION }, 1433 { "crl", CRL }, 1434 { "default", DEFAULT }, 1435 { "dhe", DHE }, 1436 { "directory", DIRECTORY }, 1437 { "drop", DROP }, 1438 { "ecdhe", ECDHE }, 1439 { "errdocs", ERRDOCS }, 1440 { "error", ERR }, 1441 { "fastcgi", FCGI }, 1442 { "forwarded", FORWARDED }, 1443 { "found", FOUND }, 1444 { "hsts", HSTS }, 1445 { "include", INCLUDE }, 1446 { "index", INDEX }, 1447 { "ip", IP }, 1448 { "key", KEY }, 1449 { "lifetime", LIFETIME }, 1450 { "listen", LISTEN }, 1451 { "location", LOCATION }, 1452 { "log", LOG }, 1453 { "logdir", LOGDIR }, 1454 { "match", MATCH }, 1455 { "max", MAXIMUM }, 1456 { "max-age", MAXAGE }, 1457 { "no", NO }, 1458 { "nodelay", NODELAY }, 1459 { "not", NOT }, 1460 { "ocsp", OCSP }, 1461 { "on", ON }, 1462 { "optional", OPTIONAL }, 1463 { "param", PARAM }, 1464 { "pass", PASS }, 1465 { "port", PORT }, 1466 { "prefork", PREFORK }, 1467 { "preload", PRELOAD }, 1468 { "protocols", PROTOCOLS }, 1469 { "request", REQUEST }, 1470 { "requests", REQUESTS }, 1471 { "return", RETURN }, 1472 { "rewrite", REWRITE }, 1473 { "root", ROOT }, 1474 { "sack", SACK }, 1475 { "server", SERVER }, 1476 { "socket", SOCKET }, 1477 { "strip", STRIP }, 1478 { "style", STYLE }, 1479 { "subdomains", SUBDOMAINS }, 1480 { "syslog", SYSLOG }, 1481 { "tcp", TCP }, 1482 { "ticket", TICKET }, 1483 { "timeout", TIMEOUT }, 1484 { "tls", TLS }, 1485 { "type", TYPE }, 1486 { "types", TYPES }, 1487 { "with", WITH } 1488 }; 1489 const struct keywords *p; 1490 1491 p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]), 1492 sizeof(keywords[0]), kw_cmp); 1493 1494 if (p) 1495 return (p->k_val); 1496 else 1497 return (STRING); 1498 } 1499 1500 #define START_EXPAND 1 1501 #define DONE_EXPAND 2 1502 1503 static int expanding; 1504 1505 int 1506 igetc(void) 1507 { 1508 int c; 1509 1510 while (1) { 1511 if (file->ungetpos > 0) 1512 c = file->ungetbuf[--file->ungetpos]; 1513 else 1514 c = getc(file->stream); 1515 1516 if (c == START_EXPAND) 1517 expanding = 1; 1518 else if (c == DONE_EXPAND) 1519 expanding = 0; 1520 else 1521 break; 1522 } 1523 return (c); 1524 } 1525 1526 int 1527 lgetc(int quotec) 1528 { 1529 int c, next; 1530 1531 if (quotec) { 1532 if ((c = igetc()) == EOF) { 1533 yyerror("reached end of file while parsing " 1534 "quoted string"); 1535 if (file == topfile || popfile() == EOF) 1536 return (EOF); 1537 return (quotec); 1538 } 1539 return (c); 1540 } 1541 1542 while ((c = igetc()) == '\\') { 1543 next = igetc(); 1544 if (next != '\n') { 1545 c = next; 1546 break; 1547 } 1548 yylval.lineno = file->lineno; 1549 file->lineno++; 1550 } 1551 1552 if (c == EOF) { 1553 /* 1554 * Fake EOL when hit EOF for the first time. This gets line 1555 * count right if last line in included file is syntactically 1556 * invalid and has no newline. 1557 */ 1558 if (file->eof_reached == 0) { 1559 file->eof_reached = 1; 1560 return ('\n'); 1561 } 1562 while (c == EOF) { 1563 if (file == topfile || popfile() == EOF) 1564 return (EOF); 1565 c = igetc(); 1566 } 1567 } 1568 return (c); 1569 } 1570 1571 void 1572 lungetc(int c) 1573 { 1574 if (c == EOF) 1575 return; 1576 1577 if (file->ungetpos >= file->ungetsize) { 1578 void *p = reallocarray(file->ungetbuf, file->ungetsize, 2); 1579 if (p == NULL) 1580 err(1, "%s", __func__); 1581 file->ungetbuf = p; 1582 file->ungetsize *= 2; 1583 } 1584 file->ungetbuf[file->ungetpos++] = c; 1585 } 1586 1587 int 1588 findeol(void) 1589 { 1590 int c; 1591 1592 /* skip to either EOF or the first real EOL */ 1593 while (1) { 1594 c = lgetc(0); 1595 if (c == '\n') { 1596 file->lineno++; 1597 break; 1598 } 1599 if (c == EOF) 1600 break; 1601 } 1602 return (ERROR); 1603 } 1604 1605 int 1606 yylex(void) 1607 { 1608 char buf[8096]; 1609 char *p, *val; 1610 int quotec, next, c; 1611 int token; 1612 1613 top: 1614 p = buf; 1615 while ((c = lgetc(0)) == ' ' || c == '\t') 1616 ; /* nothing */ 1617 1618 yylval.lineno = file->lineno; 1619 if (c == '#') 1620 while ((c = lgetc(0)) != '\n' && c != EOF) 1621 ; /* nothing */ 1622 if (c == '$' && !expanding) { 1623 while (1) { 1624 if ((c = lgetc(0)) == EOF) 1625 return (0); 1626 1627 if (p + 1 >= buf + sizeof(buf) - 1) { 1628 yyerror("string too long"); 1629 return (findeol()); 1630 } 1631 if (isalnum(c) || c == '_') { 1632 *p++ = c; 1633 continue; 1634 } 1635 *p = '\0'; 1636 lungetc(c); 1637 break; 1638 } 1639 val = symget(buf); 1640 if (val == NULL) { 1641 yyerror("macro '%s' not defined", buf); 1642 return (findeol()); 1643 } 1644 p = val + strlen(val) - 1; 1645 lungetc(DONE_EXPAND); 1646 while (p >= val) { 1647 lungetc((unsigned char)*p); 1648 p--; 1649 } 1650 lungetc(START_EXPAND); 1651 goto top; 1652 } 1653 1654 switch (c) { 1655 case '\'': 1656 case '"': 1657 quotec = c; 1658 while (1) { 1659 if ((c = lgetc(quotec)) == EOF) 1660 return (0); 1661 if (c == '\n') { 1662 file->lineno++; 1663 continue; 1664 } else if (c == '\\') { 1665 if ((next = lgetc(quotec)) == EOF) 1666 return (0); 1667 if (next == quotec || next == ' ' || 1668 next == '\t') 1669 c = next; 1670 else if (next == '\n') { 1671 file->lineno++; 1672 continue; 1673 } else 1674 lungetc(next); 1675 } else if (c == quotec) { 1676 *p = '\0'; 1677 break; 1678 } else if (c == '\0') { 1679 yyerror("syntax error"); 1680 return (findeol()); 1681 } 1682 if (p + 1 >= buf + sizeof(buf) - 1) { 1683 yyerror("string too long"); 1684 return (findeol()); 1685 } 1686 *p++ = c; 1687 } 1688 yylval.v.string = strdup(buf); 1689 if (yylval.v.string == NULL) 1690 err(1, "%s", __func__); 1691 return (STRING); 1692 } 1693 1694 #define allowed_to_end_number(x) \ 1695 (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=') 1696 1697 if (c == '-' || isdigit(c)) { 1698 do { 1699 *p++ = c; 1700 if ((size_t)(p-buf) >= sizeof(buf)) { 1701 yyerror("string too long"); 1702 return (findeol()); 1703 } 1704 } while ((c = lgetc(0)) != EOF && isdigit(c)); 1705 lungetc(c); 1706 if (p == buf + 1 && buf[0] == '-') 1707 goto nodigits; 1708 if (c == EOF || allowed_to_end_number(c)) { 1709 const char *errstr = NULL; 1710 1711 *p = '\0'; 1712 yylval.v.number = strtonum(buf, LLONG_MIN, 1713 LLONG_MAX, &errstr); 1714 if (errstr) { 1715 yyerror("\"%s\" invalid number: %s", 1716 buf, errstr); 1717 return (findeol()); 1718 } 1719 return (NUMBER); 1720 } else { 1721 nodigits: 1722 while (p > buf + 1) 1723 lungetc((unsigned char)*--p); 1724 c = (unsigned char)*--p; 1725 if (c == '-') 1726 return (c); 1727 } 1728 } 1729 1730 #define allowed_in_string(x) \ 1731 (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \ 1732 x != '{' && x != '}' && x != '<' && x != '>' && \ 1733 x != '!' && x != '=' && x != '#' && \ 1734 x != ',' && x != ';' && x != '/')) 1735 1736 if (isalnum(c) || c == ':' || c == '_' || c == '*') { 1737 do { 1738 *p++ = c; 1739 if ((size_t)(p-buf) >= sizeof(buf)) { 1740 yyerror("string too long"); 1741 return (findeol()); 1742 } 1743 } while ((c = lgetc(0)) != EOF && (allowed_in_string(c))); 1744 lungetc(c); 1745 *p = '\0'; 1746 if ((token = lookup(buf)) == STRING) 1747 if ((yylval.v.string = strdup(buf)) == NULL) 1748 err(1, "%s", __func__); 1749 return (token); 1750 } 1751 if (c == '\n') { 1752 yylval.lineno = file->lineno; 1753 file->lineno++; 1754 } 1755 if (c == EOF) 1756 return (0); 1757 return (c); 1758 } 1759 1760 int 1761 check_file_secrecy(int fd, const char *fname) 1762 { 1763 struct stat st; 1764 1765 if (fstat(fd, &st)) { 1766 log_warn("cannot stat %s", fname); 1767 return (-1); 1768 } 1769 if (st.st_uid != 0 && st.st_uid != getuid()) { 1770 log_warnx("%s: owner not root or current user", fname); 1771 return (-1); 1772 } 1773 if (st.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)) { 1774 log_warnx("%s: group writable or world read/writable", fname); 1775 return (-1); 1776 } 1777 return (0); 1778 } 1779 1780 struct file * 1781 pushfile(const char *name, int secret) 1782 { 1783 struct file *nfile; 1784 1785 if ((nfile = calloc(1, sizeof(struct file))) == NULL) { 1786 log_warn("%s", __func__); 1787 return (NULL); 1788 } 1789 if ((nfile->name = strdup(name)) == NULL) { 1790 log_warn("%s", __func__); 1791 free(nfile); 1792 return (NULL); 1793 } 1794 if ((nfile->stream = fopen(nfile->name, "r")) == NULL) { 1795 log_warn("%s: %s", __func__, nfile->name); 1796 free(nfile->name); 1797 free(nfile); 1798 return (NULL); 1799 } else if (secret && 1800 check_file_secrecy(fileno(nfile->stream), nfile->name)) { 1801 fclose(nfile->stream); 1802 free(nfile->name); 1803 free(nfile); 1804 return (NULL); 1805 } 1806 nfile->lineno = TAILQ_EMPTY(&files) ? 1 : 0; 1807 nfile->ungetsize = 16; 1808 nfile->ungetbuf = malloc(nfile->ungetsize); 1809 if (nfile->ungetbuf == NULL) { 1810 log_warn("%s", __func__); 1811 fclose(nfile->stream); 1812 free(nfile->name); 1813 free(nfile); 1814 return (NULL); 1815 } 1816 TAILQ_INSERT_TAIL(&files, nfile, entry); 1817 return (nfile); 1818 } 1819 1820 int 1821 popfile(void) 1822 { 1823 struct file *prev; 1824 1825 if ((prev = TAILQ_PREV(file, files, entry)) != NULL) 1826 prev->errors += file->errors; 1827 1828 TAILQ_REMOVE(&files, file, entry); 1829 fclose(file->stream); 1830 free(file->name); 1831 free(file->ungetbuf); 1832 free(file); 1833 file = prev; 1834 return (file ? 0 : EOF); 1835 } 1836 1837 int 1838 parse_config(const char *filename, struct httpd *x_conf) 1839 { 1840 struct sym *sym, *next; 1841 struct media_type dflt = HTTPD_DEFAULT_TYPE; 1842 1843 conf = x_conf; 1844 if (config_init(conf) == -1) { 1845 log_warn("%s: cannot initialize configuration", __func__); 1846 return (-1); 1847 } 1848 1849 /* Set default media type */ 1850 memcpy(&conf->sc_default_type, &dflt, sizeof(struct media_type)); 1851 1852 errors = 0; 1853 1854 if ((file = pushfile(filename, 0)) == NULL) 1855 return (-1); 1856 1857 topfile = file; 1858 setservent(1); 1859 1860 yyparse(); 1861 errors = file->errors; 1862 while (popfile() != EOF) 1863 ; 1864 1865 endservent(); 1866 endprotoent(); 1867 1868 /* Free macros */ 1869 TAILQ_FOREACH_SAFE(sym, &symhead, entry, next) { 1870 if (!sym->persist) { 1871 free(sym->nam); 1872 free(sym->val); 1873 TAILQ_REMOVE(&symhead, sym, entry); 1874 free(sym); 1875 } 1876 } 1877 1878 return (errors ? -1 : 0); 1879 } 1880 1881 int 1882 load_config(const char *filename, struct httpd *x_conf) 1883 { 1884 struct sym *sym, *next; 1885 struct http_mediatype mediatypes[] = MEDIA_TYPES; 1886 struct media_type m; 1887 int i; 1888 1889 conf = x_conf; 1890 conf->sc_flags = 0; 1891 1892 loadcfg = 1; 1893 errors = 0; 1894 last_server_id = 0; 1895 last_auth_id = 0; 1896 1897 srv = NULL; 1898 1899 if ((file = pushfile(filename, 0)) == NULL) 1900 return (-1); 1901 1902 topfile = file; 1903 setservent(1); 1904 1905 yyparse(); 1906 errors = file->errors; 1907 popfile(); 1908 1909 endservent(); 1910 endprotoent(); 1911 1912 /* Free macros and check which have not been used. */ 1913 for (sym = TAILQ_FIRST(&symhead); sym != NULL; sym = next) { 1914 next = TAILQ_NEXT(sym, entry); 1915 if ((conf->sc_opts & HTTPD_OPT_VERBOSE) && !sym->used) 1916 fprintf(stderr, "warning: macro '%s' not " 1917 "used\n", sym->nam); 1918 if (!sym->persist) { 1919 free(sym->nam); 1920 free(sym->val); 1921 TAILQ_REMOVE(&symhead, sym, entry); 1922 free(sym); 1923 } 1924 } 1925 1926 if (TAILQ_EMPTY(conf->sc_servers)) { 1927 log_warnx("no actions, nothing to do"); 1928 errors++; 1929 } 1930 1931 if (RB_EMPTY(conf->sc_mediatypes)) { 1932 /* Add default media types */ 1933 for (i = 0; mediatypes[i].media_name != NULL; i++) { 1934 (void)strlcpy(m.media_name, mediatypes[i].media_name, 1935 sizeof(m.media_name)); 1936 (void)strlcpy(m.media_type, mediatypes[i].media_type, 1937 sizeof(m.media_type)); 1938 (void)strlcpy(m.media_subtype, 1939 mediatypes[i].media_subtype, 1940 sizeof(m.media_subtype)); 1941 m.media_encoding = NULL; 1942 1943 if (media_add(conf->sc_mediatypes, &m) == NULL) { 1944 log_warnx("failed to add default media \"%s\"", 1945 m.media_name); 1946 errors++; 1947 } 1948 } 1949 } 1950 1951 return (errors ? -1 : 0); 1952 } 1953 1954 int 1955 symset(const char *nam, const char *val, int persist) 1956 { 1957 struct sym *sym; 1958 1959 TAILQ_FOREACH(sym, &symhead, entry) { 1960 if (strcmp(nam, sym->nam) == 0) 1961 break; 1962 } 1963 1964 if (sym != NULL) { 1965 if (sym->persist == 1) 1966 return (0); 1967 else { 1968 free(sym->nam); 1969 free(sym->val); 1970 TAILQ_REMOVE(&symhead, sym, entry); 1971 free(sym); 1972 } 1973 } 1974 if ((sym = calloc(1, sizeof(*sym))) == NULL) 1975 return (-1); 1976 1977 sym->nam = strdup(nam); 1978 if (sym->nam == NULL) { 1979 free(sym); 1980 return (-1); 1981 } 1982 sym->val = strdup(val); 1983 if (sym->val == NULL) { 1984 free(sym->nam); 1985 free(sym); 1986 return (-1); 1987 } 1988 sym->used = 0; 1989 sym->persist = persist; 1990 TAILQ_INSERT_TAIL(&symhead, sym, entry); 1991 return (0); 1992 } 1993 1994 int 1995 cmdline_symset(char *s) 1996 { 1997 char *sym, *val; 1998 int ret; 1999 2000 if ((val = strrchr(s, '=')) == NULL) 2001 return (-1); 2002 sym = strndup(s, val - s); 2003 if (sym == NULL) 2004 errx(1, "%s: strndup", __func__); 2005 ret = symset(sym, val + 1, 1); 2006 free(sym); 2007 2008 return (ret); 2009 } 2010 2011 char * 2012 symget(const char *nam) 2013 { 2014 struct sym *sym; 2015 2016 TAILQ_FOREACH(sym, &symhead, entry) { 2017 if (strcmp(nam, sym->nam) == 0) { 2018 sym->used = 1; 2019 return (sym->val); 2020 } 2021 } 2022 return (NULL); 2023 } 2024 2025 struct address * 2026 host_v4(const char *s) 2027 { 2028 struct in_addr ina; 2029 struct sockaddr_in *sain; 2030 struct address *h; 2031 2032 memset(&ina, 0, sizeof(ina)); 2033 if (inet_pton(AF_INET, s, &ina) != 1) 2034 return (NULL); 2035 2036 if ((h = calloc(1, sizeof(*h))) == NULL) 2037 fatal(__func__); 2038 sain = (struct sockaddr_in *)&h->ss; 2039 sain->sin_len = sizeof(struct sockaddr_in); 2040 sain->sin_family = AF_INET; 2041 sain->sin_addr.s_addr = ina.s_addr; 2042 if (sain->sin_addr.s_addr == INADDR_ANY) 2043 h->prefixlen = 0; /* 0.0.0.0 address */ 2044 else 2045 h->prefixlen = -1; /* host address */ 2046 return (h); 2047 } 2048 2049 struct address * 2050 host_v6(const char *s) 2051 { 2052 struct addrinfo hints, *res; 2053 struct sockaddr_in6 *sa_in6; 2054 struct address *h = NULL; 2055 2056 memset(&hints, 0, sizeof(hints)); 2057 hints.ai_family = AF_INET6; 2058 hints.ai_socktype = SOCK_DGRAM; /* dummy */ 2059 hints.ai_flags = AI_NUMERICHOST; 2060 if (getaddrinfo(s, "0", &hints, &res) == 0) { 2061 if ((h = calloc(1, sizeof(*h))) == NULL) 2062 fatal(__func__); 2063 sa_in6 = (struct sockaddr_in6 *)&h->ss; 2064 sa_in6->sin6_len = sizeof(struct sockaddr_in6); 2065 sa_in6->sin6_family = AF_INET6; 2066 memcpy(&sa_in6->sin6_addr, 2067 &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 2068 sizeof(sa_in6->sin6_addr)); 2069 sa_in6->sin6_scope_id = 2070 ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id; 2071 if (memcmp(&sa_in6->sin6_addr, &in6addr_any, 2072 sizeof(sa_in6->sin6_addr)) == 0) 2073 h->prefixlen = 0; /* any address */ 2074 else 2075 h->prefixlen = -1; /* host address */ 2076 freeaddrinfo(res); 2077 } 2078 2079 return (h); 2080 } 2081 2082 int 2083 host_dns(const char *s, struct addresslist *al, int max, 2084 struct portrange *port, const char *ifname, int ipproto) 2085 { 2086 struct addrinfo hints, *res0, *res; 2087 int error, cnt = 0; 2088 struct sockaddr_in *sain; 2089 struct sockaddr_in6 *sin6; 2090 struct address *h; 2091 2092 if ((cnt = host_if(s, al, max, port, ifname, ipproto)) != 0) 2093 return (cnt); 2094 2095 memset(&hints, 0, sizeof(hints)); 2096 hints.ai_family = PF_UNSPEC; 2097 hints.ai_socktype = SOCK_DGRAM; /* DUMMY */ 2098 hints.ai_flags = AI_ADDRCONFIG; 2099 error = getaddrinfo(s, NULL, &hints, &res0); 2100 if (error == EAI_AGAIN || error == EAI_NODATA || error == EAI_NONAME) 2101 return (0); 2102 if (error) { 2103 log_warnx("%s: could not parse \"%s\": %s", __func__, s, 2104 gai_strerror(error)); 2105 return (-1); 2106 } 2107 2108 for (res = res0; res && cnt < max; res = res->ai_next) { 2109 if (res->ai_family != AF_INET && 2110 res->ai_family != AF_INET6) 2111 continue; 2112 if ((h = calloc(1, sizeof(*h))) == NULL) 2113 fatal(__func__); 2114 2115 if (port != NULL) 2116 memcpy(&h->port, port, sizeof(h->port)); 2117 if (ifname != NULL) { 2118 if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >= 2119 sizeof(h->ifname)) 2120 log_warnx("%s: interface name truncated", 2121 __func__); 2122 freeaddrinfo(res0); 2123 free(h); 2124 return (-1); 2125 } 2126 if (ipproto != -1) 2127 h->ipproto = ipproto; 2128 h->ss.ss_family = res->ai_family; 2129 h->prefixlen = -1; /* host address */ 2130 2131 if (res->ai_family == AF_INET) { 2132 sain = (struct sockaddr_in *)&h->ss; 2133 sain->sin_len = sizeof(struct sockaddr_in); 2134 sain->sin_addr.s_addr = ((struct sockaddr_in *) 2135 res->ai_addr)->sin_addr.s_addr; 2136 } else { 2137 sin6 = (struct sockaddr_in6 *)&h->ss; 2138 sin6->sin6_len = sizeof(struct sockaddr_in6); 2139 memcpy(&sin6->sin6_addr, &((struct sockaddr_in6 *) 2140 res->ai_addr)->sin6_addr, sizeof(struct in6_addr)); 2141 } 2142 2143 TAILQ_INSERT_HEAD(al, h, entry); 2144 cnt++; 2145 } 2146 if (cnt == max && res) { 2147 log_warnx("%s: %s resolves to more than %d hosts", __func__, 2148 s, max); 2149 } 2150 freeaddrinfo(res0); 2151 return (cnt); 2152 } 2153 2154 int 2155 host_if(const char *s, struct addresslist *al, int max, 2156 struct portrange *port, const char *ifname, int ipproto) 2157 { 2158 struct ifaddrs *ifap, *p; 2159 struct sockaddr_in *sain; 2160 struct sockaddr_in6 *sin6; 2161 struct address *h; 2162 int cnt = 0, af; 2163 2164 if (getifaddrs(&ifap) == -1) 2165 fatal("getifaddrs"); 2166 2167 /* First search for IPv4 addresses */ 2168 af = AF_INET; 2169 2170 nextaf: 2171 for (p = ifap; p != NULL && cnt < max; p = p->ifa_next) { 2172 if (p->ifa_addr == NULL || 2173 p->ifa_addr->sa_family != af || 2174 (strcmp(s, p->ifa_name) != 0 && 2175 !is_if_in_group(p->ifa_name, s))) 2176 continue; 2177 if ((h = calloc(1, sizeof(*h))) == NULL) 2178 fatal("calloc"); 2179 2180 if (port != NULL) 2181 memcpy(&h->port, port, sizeof(h->port)); 2182 if (ifname != NULL) { 2183 if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >= 2184 sizeof(h->ifname)) 2185 log_warnx("%s: interface name truncated", 2186 __func__); 2187 freeifaddrs(ifap); 2188 free(h); 2189 return (-1); 2190 } 2191 if (ipproto != -1) 2192 h->ipproto = ipproto; 2193 h->ss.ss_family = af; 2194 h->prefixlen = -1; /* host address */ 2195 2196 if (af == AF_INET) { 2197 sain = (struct sockaddr_in *)&h->ss; 2198 sain->sin_len = sizeof(struct sockaddr_in); 2199 sain->sin_addr.s_addr = ((struct sockaddr_in *) 2200 p->ifa_addr)->sin_addr.s_addr; 2201 } else { 2202 sin6 = (struct sockaddr_in6 *)&h->ss; 2203 sin6->sin6_len = sizeof(struct sockaddr_in6); 2204 memcpy(&sin6->sin6_addr, &((struct sockaddr_in6 *) 2205 p->ifa_addr)->sin6_addr, sizeof(struct in6_addr)); 2206 sin6->sin6_scope_id = ((struct sockaddr_in6 *) 2207 p->ifa_addr)->sin6_scope_id; 2208 } 2209 2210 TAILQ_INSERT_HEAD(al, h, entry); 2211 cnt++; 2212 } 2213 if (af == AF_INET) { 2214 /* Next search for IPv6 addresses */ 2215 af = AF_INET6; 2216 goto nextaf; 2217 } 2218 2219 if (cnt > max) { 2220 log_warnx("%s: %s resolves to more than %d hosts", __func__, 2221 s, max); 2222 } 2223 freeifaddrs(ifap); 2224 return (cnt); 2225 } 2226 2227 int 2228 host(const char *s, struct addresslist *al, int max, 2229 struct portrange *port, const char *ifname, int ipproto) 2230 { 2231 struct address *h; 2232 2233 h = host_v4(s); 2234 2235 /* IPv6 address? */ 2236 if (h == NULL) 2237 h = host_v6(s); 2238 2239 if (h != NULL) { 2240 if (port != NULL) 2241 memcpy(&h->port, port, sizeof(h->port)); 2242 if (ifname != NULL) { 2243 if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >= 2244 sizeof(h->ifname)) { 2245 log_warnx("%s: interface name truncated", 2246 __func__); 2247 free(h); 2248 return (-1); 2249 } 2250 } 2251 if (ipproto != -1) 2252 h->ipproto = ipproto; 2253 2254 TAILQ_INSERT_HEAD(al, h, entry); 2255 return (1); 2256 } 2257 2258 return (host_dns(s, al, max, port, ifname, ipproto)); 2259 } 2260 2261 struct server * 2262 server_inherit(struct server *src, struct server_config *alias, 2263 struct server_config *addr) 2264 { 2265 struct server *dst, *s, *dstl; 2266 2267 if ((dst = calloc(1, sizeof(*dst))) == NULL) 2268 fatal("out of memory"); 2269 2270 /* Copy the source server and assign a new Id */ 2271 memcpy(&dst->srv_conf, &src->srv_conf, sizeof(dst->srv_conf)); 2272 if ((dst->srv_conf.tls_cert_file = 2273 strdup(src->srv_conf.tls_cert_file)) == NULL) 2274 fatal("out of memory"); 2275 if ((dst->srv_conf.tls_key_file = 2276 strdup(src->srv_conf.tls_key_file)) == NULL) 2277 fatal("out of memory"); 2278 if (src->srv_conf.tls_ocsp_staple_file != NULL) { 2279 if ((dst->srv_conf.tls_ocsp_staple_file = 2280 strdup(src->srv_conf.tls_ocsp_staple_file)) == NULL) 2281 fatal("out of memory"); 2282 } 2283 2284 if (src->srv_conf.return_uri != NULL && 2285 (dst->srv_conf.return_uri = 2286 strdup(src->srv_conf.return_uri)) == NULL) 2287 fatal("out of memory"); 2288 2289 dst->srv_conf.id = ++last_server_id; 2290 dst->srv_conf.parent_id = dst->srv_conf.id; 2291 dst->srv_s = -1; 2292 2293 if (last_server_id == INT_MAX) { 2294 yyerror("too many servers defined"); 2295 serverconfig_free(&dst->srv_conf); 2296 free(dst); 2297 return (NULL); 2298 } 2299 2300 /* Now set alias and listen address */ 2301 strlcpy(dst->srv_conf.name, alias->name, sizeof(dst->srv_conf.name)); 2302 memcpy(&dst->srv_conf.ss, &addr->ss, sizeof(dst->srv_conf.ss)); 2303 dst->srv_conf.port = addr->port; 2304 dst->srv_conf.prefixlen = addr->prefixlen; 2305 if (addr->flags & SRVFLAG_TLS) 2306 dst->srv_conf.flags |= SRVFLAG_TLS; 2307 else 2308 dst->srv_conf.flags &= ~SRVFLAG_TLS; 2309 2310 /* Don't inherit the "match" option, use it from the alias */ 2311 dst->srv_conf.flags &= ~SRVFLAG_SERVER_MATCH; 2312 dst->srv_conf.flags |= (alias->flags & SRVFLAG_SERVER_MATCH); 2313 2314 if (server_tls_load_keypair(dst) == -1) 2315 log_warnx("%s:%d: server \"%s\": failed to " 2316 "load public/private keys", file->name, 2317 yylval.lineno, dst->srv_conf.name); 2318 2319 if (server_tls_load_ca(dst) == -1) { 2320 yyerror("failed to load ca cert(s) for server %s", 2321 dst->srv_conf.name); 2322 serverconfig_free(&dst->srv_conf); 2323 return NULL; 2324 } 2325 2326 if (server_tls_load_crl(dst) == -1) { 2327 yyerror("failed to load crl(s) for server %s", 2328 dst->srv_conf.name); 2329 serverconfig_free(&dst->srv_conf); 2330 free(dst); 2331 return NULL; 2332 } 2333 2334 if (server_tls_load_ocsp(dst) == -1) { 2335 yyerror("failed to load ocsp staple " 2336 "for server %s", dst->srv_conf.name); 2337 serverconfig_free(&dst->srv_conf); 2338 free(dst); 2339 return (NULL); 2340 } 2341 2342 /* Check if the new server already exists */ 2343 if (server_match(dst, 1) != NULL) { 2344 yyerror("server \"%s\" defined twice", 2345 dst->srv_conf.name); 2346 serverconfig_free(&dst->srv_conf); 2347 free(dst); 2348 return (NULL); 2349 } 2350 2351 /* Copy all the locations of the source server */ 2352 TAILQ_FOREACH(s, conf->sc_servers, srv_entry) { 2353 if (!(s->srv_conf.flags & SRVFLAG_LOCATION && 2354 s->srv_conf.parent_id == src->srv_conf.parent_id)) 2355 continue; 2356 2357 if ((dstl = calloc(1, sizeof(*dstl))) == NULL) 2358 fatal("out of memory"); 2359 2360 memcpy(&dstl->srv_conf, &s->srv_conf, sizeof(dstl->srv_conf)); 2361 strlcpy(dstl->srv_conf.name, alias->name, 2362 sizeof(dstl->srv_conf.name)); 2363 2364 /* Copy the new Id and listen address */ 2365 dstl->srv_conf.id = ++last_server_id; 2366 dstl->srv_conf.parent_id = dst->srv_conf.id; 2367 memcpy(&dstl->srv_conf.ss, &addr->ss, 2368 sizeof(dstl->srv_conf.ss)); 2369 dstl->srv_conf.port = addr->port; 2370 dstl->srv_conf.prefixlen = addr->prefixlen; 2371 dstl->srv_s = -1; 2372 2373 DPRINTF("adding location \"%s\" for \"%s[%u]\"", 2374 dstl->srv_conf.location, 2375 dstl->srv_conf.name, dstl->srv_conf.id); 2376 2377 TAILQ_INSERT_TAIL(conf->sc_servers, dstl, srv_entry); 2378 } 2379 2380 return (dst); 2381 } 2382 2383 int 2384 listen_on(const char *addr, int tls, struct portrange *port) 2385 { 2386 struct addresslist al; 2387 struct address *h; 2388 struct server_config *s_conf, *alias = NULL; 2389 2390 if (parentsrv != NULL) { 2391 yyerror("listen %s inside location", addr); 2392 return (-1); 2393 } 2394 2395 TAILQ_INIT(&al); 2396 if (strcmp("*", addr) == 0) { 2397 if (host("0.0.0.0", &al, 1, port, NULL, -1) <= 0) { 2398 yyerror("invalid listen ip: %s", 2399 "0.0.0.0"); 2400 return (-1); 2401 } 2402 if (host("::", &al, 1, port, NULL, -1) <= 0) { 2403 yyerror("invalid listen ip: %s", "::"); 2404 return (-1); 2405 } 2406 } else { 2407 if (host(addr, &al, HTTPD_MAX_ALIAS_IP, port, NULL, 2408 -1) <= 0) { 2409 yyerror("invalid listen ip: %s", addr); 2410 return (-1); 2411 } 2412 } 2413 2414 while ((h = TAILQ_FIRST(&al)) != NULL) { 2415 if (srv->srv_conf.ss.ss_family != AF_UNSPEC) { 2416 if ((alias = calloc(1, 2417 sizeof(*alias))) == NULL) 2418 fatal("out of memory"); 2419 /* Add as an IP-based alias. */ 2420 s_conf = alias; 2421 } else 2422 s_conf = &srv->srv_conf; 2423 memcpy(&s_conf->ss, &h->ss, sizeof(s_conf->ss)); 2424 s_conf->prefixlen = h->prefixlen; 2425 /* Set the default port to 80 or 443 */ 2426 if (!h->port.op) 2427 s_conf->port = htons(tls ? 2428 HTTPS_PORT : HTTP_PORT); 2429 else 2430 s_conf->port = h->port.val[0]; 2431 2432 if (tls) 2433 s_conf->flags |= SRVFLAG_TLS; 2434 2435 if (alias != NULL) { 2436 /* 2437 * IP-based; use name match flags from 2438 * parent 2439 */ 2440 alias->flags &= ~SRVFLAG_SERVER_MATCH; 2441 alias->flags |= srv->srv_conf.flags & 2442 SRVFLAG_SERVER_MATCH; 2443 TAILQ_INSERT_TAIL(&srv->srv_hosts, 2444 alias, entry); 2445 } 2446 TAILQ_REMOVE(&al, h, entry); 2447 free(h); 2448 } 2449 2450 return (0); 2451 } 2452 2453 int 2454 getservice(char *n) 2455 { 2456 struct servent *s; 2457 const char *errstr; 2458 long long llval; 2459 2460 llval = strtonum(n, 0, UINT16_MAX, &errstr); 2461 if (errstr) { 2462 s = getservbyname(n, "tcp"); 2463 if (s == NULL) 2464 s = getservbyname(n, "udp"); 2465 if (s == NULL) 2466 return (-1); 2467 return (s->s_port); 2468 } 2469 2470 return (htons((unsigned short)llval)); 2471 } 2472 2473 int 2474 is_if_in_group(const char *ifname, const char *groupname) 2475 { 2476 unsigned int len; 2477 struct ifgroupreq ifgr; 2478 struct ifg_req *ifg; 2479 int s; 2480 int ret = 0; 2481 2482 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 2483 err(1, "socket"); 2484 2485 memset(&ifgr, 0, sizeof(ifgr)); 2486 if (strlcpy(ifgr.ifgr_name, ifname, IFNAMSIZ) >= IFNAMSIZ) 2487 err(1, "IFNAMSIZ"); 2488 if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) { 2489 if (errno == EINVAL || errno == ENOTTY) 2490 goto end; 2491 err(1, "SIOCGIFGROUP"); 2492 } 2493 2494 len = ifgr.ifgr_len; 2495 ifgr.ifgr_groups = calloc(len / sizeof(struct ifg_req), 2496 sizeof(struct ifg_req)); 2497 if (ifgr.ifgr_groups == NULL) 2498 err(1, "getifgroups"); 2499 if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) 2500 err(1, "SIOCGIFGROUP"); 2501 2502 ifg = ifgr.ifgr_groups; 2503 for (; ifg && len >= sizeof(struct ifg_req); ifg++) { 2504 len -= sizeof(struct ifg_req); 2505 if (strcmp(ifg->ifgrq_group, groupname) == 0) { 2506 ret = 1; 2507 break; 2508 } 2509 } 2510 free(ifgr.ifgr_groups); 2511 2512 end: 2513 close(s); 2514 return (ret); 2515 } 2516 2517 int 2518 get_fastcgi_dest(struct server_config *xsrv_conf, const char *node, char *port) 2519 { 2520 struct addrinfo hints, *res; 2521 int s; 2522 2523 memset(&hints, 0, sizeof(hints)); 2524 hints.ai_family = AF_UNSPEC; 2525 hints.ai_socktype = SOCK_STREAM; 2526 2527 if ((s = getaddrinfo(node, port, &hints, &res)) != 0) { 2528 yyerror("getaddrinfo: %s\n", gai_strerror(s)); 2529 return -1; 2530 } 2531 2532 memset(&(xsrv_conf)->fastcgi_ss, 0, sizeof(xsrv_conf->fastcgi_ss)); 2533 memcpy(&(xsrv_conf)->fastcgi_ss, res->ai_addr, res->ai_addrlen); 2534 2535 freeaddrinfo(res); 2536 2537 return (0); 2538 } 2539 2540 void 2541 remove_locations(struct server_config *xsrv_conf) 2542 { 2543 struct server *s, *next; 2544 2545 TAILQ_FOREACH_SAFE(s, conf->sc_servers, srv_entry, next) { 2546 if (!(s->srv_conf.flags & SRVFLAG_LOCATION && 2547 s->srv_conf.parent_id == xsrv_conf->parent_id)) 2548 continue; 2549 TAILQ_REMOVE(conf->sc_servers, s, srv_entry); 2550 serverconfig_free(&s->srv_conf); 2551 free(s); 2552 } 2553 } 2554