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