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