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