1193326Sed/* $OpenBSD: server.c,v 1.129 2023/11/08 19:19:10 millert Exp $ */ 2193326Sed 3193326Sed/* 4193326Sed * Copyright (c) 2006 - 2015 Reyk Floeter <reyk@openbsd.org> 5193326Sed * 6193326Sed * Permission to use, copy, modify, and distribute this software for any 7193326Sed * purpose with or without fee is hereby granted, provided that the above 8193326Sed * copyright notice and this permission notice appear in all copies. 9193326Sed * 10193326Sed * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11193326Sed * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12193326Sed * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13193326Sed * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14193326Sed * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15193326Sed * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16205219Srdivacky * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17193326Sed */ 18193326Sed 19193326Sed#include <sys/types.h> 20198092Srdivacky#include <sys/queue.h> 21193326Sed#include <sys/time.h> 22193326Sed#include <sys/stat.h> 23205219Srdivacky#include <sys/socket.h> 24205219Srdivacky#include <sys/uio.h> 25205219Srdivacky#include <sys/tree.h> 26193326Sed 27193326Sed#include <netinet/in.h> 28193326Sed#include <netinet/tcp.h> 29193326Sed#include <arpa/inet.h> 30193326Sed 31193326Sed#include <stdio.h> 32193326Sed#include <stdlib.h> 33193326Sed#include <stdarg.h> 34193326Sed#include <limits.h> 35205408Srdivacky#include <errno.h> 36193326Sed#include <fcntl.h> 37193326Sed#include <string.h> 38193326Sed#include <syslog.h> 39193326Sed#include <unistd.h> 40193326Sed#include <event.h> 41193326Sed#include <imsg.h> 42205408Srdivacky#include <tls.h> 43193326Sed#include <vis.h> 44193326Sed 45193326Sed#include "httpd.h" 46193326Sed 47193326Sed#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) 48200583Srdivacky 49193326Sedint server_dispatch_parent(int, struct privsep_proc *, 50205408Srdivacky struct imsg *); 51205408Srdivackyint server_dispatch_logger(int, struct privsep_proc *, 52193326Sed struct imsg *); 53193326Sedvoid server_shutdown(void); 54200583Srdivacky 55205408Srdivackyvoid server_init(struct privsep *, struct privsep_proc *p, void *); 56200583Srdivackyvoid server_launch(void); 57205408Srdivackyint server_socket(struct sockaddr_storage *, in_port_t, 58205408Srdivacky struct server_config *, int, int); 59205408Srdivackyint server_socket_listen(struct sockaddr_storage *, in_port_t, 60200583Srdivacky struct server_config *); 61200583Srdivackystruct server *server_byid(uint32_t); 62205219Srdivacky 63205219Srdivackyint server_tls_init(struct server *); 64205219Srdivackyvoid server_tls_readcb(int, short, void *); 65205219Srdivackyvoid server_tls_writecb(int, short, void *); 66205219Srdivackyvoid server_tls_handshake(int, short, void *); 67193326Sed 68205408Srdivackyvoid server_accept(int, short, void *); 69205219Srdivackyvoid server_input(struct client *); 70205219Srdivackyvoid server_inflight_dec(struct client *, const char *); 71205408Srdivacky 72205408Srdivackyextern void bufferevent_read_pressure_cb(struct evbuffer *, size_t, 73205408Srdivacky size_t, void *); 74205408Srdivacky 75200583Srdivackyvolatile int server_clients; 76200583Srdivackyvolatile int server_inflight = 0; 77200583Srdivackyuint32_t server_cltid; 78200583Srdivacky 79200583Srdivackystatic struct privsep_proc procs[] = { 80200583Srdivacky { "parent", PROC_PARENT, server_dispatch_parent }, 81200583Srdivacky { "logger", PROC_LOGGER, server_dispatch_logger } 82200583Srdivacky}; 83200583Srdivacky 84200583Srdivackyvoid 85205408Srdivackyserver(struct privsep *ps, struct privsep_proc *p) 86200583Srdivacky{ 87205408Srdivacky proc_run(ps, p, procs, nitems(procs), server_init, NULL); 88205408Srdivacky server_http(); 89205408Srdivacky} 90200583Srdivacky 91200583Srdivackyvoid 92206084Srdivackyserver_shutdown(void) 93206084Srdivacky{ 94206084Srdivacky config_purge(httpd_env, CONFIG_ALL); 95206084Srdivacky usleep(200); /* XXX server needs to shutdown last */ 96206084Srdivacky} 97206084Srdivacky 98206084Srdivackyint 99206084Srdivackyserver_privinit(struct server *srv) 100205408Srdivacky{ 101205408Srdivacky struct server *s; 102206084Srdivacky 103205408Srdivacky if (srv->srv_conf.flags & SRVFLAG_LOCATION) 104205408Srdivacky return (0); 105205408Srdivacky 106206084Srdivacky log_debug("%s: adding server %s", __func__, srv->srv_conf.name); 107206084Srdivacky 108206084Srdivacky /* 109206084Srdivacky * There's no need to open a new socket if a server with the 110206084Srdivacky * same address already exists. 111206084Srdivacky */ 112205408Srdivacky TAILQ_FOREACH(s, httpd_env->sc_servers, srv_entry) { 113198092Srdivacky if (s != srv && s->srv_s != -1 && 114198092Srdivacky s->srv_conf.port == srv->srv_conf.port && 115205219Srdivacky sockaddr_cmp((struct sockaddr *)&s->srv_conf.ss, 116205408Srdivacky (struct sockaddr *)&srv->srv_conf.ss, 117205408Srdivacky s->srv_conf.prefixlen) == 0) 118205408Srdivacky return (0); 119205408Srdivacky } 120198092Srdivacky 121198092Srdivacky /* Open listening socket in the privileged process */ 122193326Sed if ((srv->srv_s = server_socket_listen(&srv->srv_conf.ss, 123193326Sed srv->srv_conf.port, &srv->srv_conf)) == -1) 124193326Sed return (-1); 125198092Srdivacky 126193326Sed return (0); 127193326Sed} 128193326Sed 129198092Srdivackyint 130193326Sedserver_tls_cmp(struct server *s1, struct server *s2) 131193326Sed{ 132193326Sed struct server_config *sc1, *sc2; 133193326Sed 134193326Sed sc1 = &s1->srv_conf; 135193326Sed sc2 = &s2->srv_conf; 136193326Sed 137193326Sed if (sc1->tls_flags != sc2->tls_flags) 138193326Sed return (-1); 139193326Sed if (sc1->tls_protocols != sc2->tls_protocols) 140193326Sed return (-1); 141193326Sed if (sc1->tls_ticket_lifetime != sc2->tls_ticket_lifetime) 142198092Srdivacky return (-1); 143193326Sed if (strcmp(sc1->tls_ciphers, sc2->tls_ciphers) != 0) 144193326Sed return (-1); 145198092Srdivacky if (strcmp(sc1->tls_dhe_params, sc2->tls_dhe_params) != 0) 146193326Sed return (-1); 147193326Sed if (strcmp(sc1->tls_ecdhe_curves, sc2->tls_ecdhe_curves) != 0) 148198092Srdivacky return (-1); 149193326Sed 150193326Sed return (0); 151193326Sed} 152193326Sed 153193326Sedint 154198092Srdivackyserver_tls_load_keypair(struct server *srv) 155193326Sed{ 156193326Sed if ((srv->srv_conf.flags & SRVFLAG_TLS) == 0) 157193326Sed return (0); 158193326Sed 159193326Sed if ((srv->srv_conf.tls_cert = tls_load_file(srv->srv_conf.tls_cert_file, 160198092Srdivacky &srv->srv_conf.tls_cert_len, NULL)) == NULL) 161193326Sed return (-1); 162193326Sed log_debug("%s: using certificate %s", __func__, 163193326Sed srv->srv_conf.tls_cert_file); 164193326Sed 165193326Sed /* XXX allow to specify password for encrypted key */ 166193326Sed if ((srv->srv_conf.tls_key = tls_load_file(srv->srv_conf.tls_key_file, 167193326Sed &srv->srv_conf.tls_key_len, NULL)) == NULL) 168193326Sed return (-1); 169193326Sed log_debug("%s: using private key %s", __func__, 170193326Sed srv->srv_conf.tls_key_file); 171193326Sed 172193326Sed return (0); 173193326Sed} 174193326Sed 175198092Srdivackyint 176193326Sedserver_tls_load_ocsp(struct server *srv) 177198092Srdivacky{ 178193326Sed if ((srv->srv_conf.flags & SRVFLAG_TLS) == 0) 179193326Sed return (0); 180193326Sed 181193326Sed if (srv->srv_conf.tls_ocsp_staple_file == NULL) 182193326Sed return (0); 183193326Sed 184193326Sed if ((srv->srv_conf.tls_ocsp_staple = tls_load_file( 185193326Sed srv->srv_conf.tls_ocsp_staple_file, 186193326Sed &srv->srv_conf.tls_ocsp_staple_len, NULL)) == NULL) { 187193326Sed log_warnx("%s: Failed to load ocsp staple from %s", __func__, 188193326Sed srv->srv_conf.tls_ocsp_staple_file); 189198092Srdivacky return (-1); 190193326Sed } 191193326Sed 192193326Sed if (srv->srv_conf.tls_ocsp_staple_len == 0) { 193193326Sed log_warnx("%s: ignoring 0 length ocsp staple from %s", __func__, 194193326Sed srv->srv_conf.tls_ocsp_staple_file); 195193326Sed return (0); 196198092Srdivacky } 197193326Sed 198193326Sed log_debug("%s: using ocsp staple from %s", __func__, 199193326Sed srv->srv_conf.tls_ocsp_staple_file); 200193326Sed 201193326Sed return (0); 202193326Sed} 203193326Sed 204198092Srdivackyint 205193326Sedserver_tls_load_ca(struct server *srv) 206193326Sed{ 207193326Sed if ((srv->srv_conf.tls_flags & TLSFLAG_CA) == 0 || 208193326Sed srv->srv_conf.tls_ca_file == NULL) 209193326Sed return (0); 210193326Sed 211193326Sed if ((srv->srv_conf.tls_ca = tls_load_file( 212193326Sed srv->srv_conf.tls_ca_file, 213193326Sed &srv->srv_conf.tls_ca_len, NULL)) == NULL) 214193326Sed return (-1); 215193326Sed log_debug("%s: using ca cert(s) from %s", __func__, 216193326Sed srv->srv_conf.tls_ca_file); 217193326Sed 218193326Sed return (0); 219193326Sed} 220193326Sed 221193326Sedint 222193326Sedserver_tls_load_crl(struct server *srv) 223198092Srdivacky{ 224193326Sed if ((srv->srv_conf.tls_flags & TLSFLAG_CA) == 0 || 225193326Sed srv->srv_conf.tls_crl_file == NULL) 226193326Sed return (0); 227193326Sed 228193326Sed if ((srv->srv_conf.tls_crl = tls_load_file( 229198092Srdivacky srv->srv_conf.tls_crl_file, 230193326Sed &srv->srv_conf.tls_crl_len, NULL)) == NULL) 231193326Sed return (-1); 232193326Sed log_debug("%s: using crl(s) from %s", __func__, 233193326Sed srv->srv_conf.tls_crl_file); 234193326Sed 235193326Sed return (0); 236193326Sed} 237193326Sed 238193326Sedint 239193326Sedserver_tls_init(struct server *srv) 240193326Sed{ 241193326Sed struct server_config *srv_conf; 242193326Sed 243198092Srdivacky if ((srv->srv_conf.flags & SRVFLAG_TLS) == 0) 244193326Sed return (0); 245193326Sed 246193326Sed log_debug("%s: setting up tls for %s", __func__, srv->srv_conf.name); 247193326Sed 248198092Srdivacky if ((srv->srv_tls_config = tls_config_new()) == NULL) { 249193326Sed log_warnx("%s: failed to get tls config", __func__); 250193326Sed return (-1); 251193326Sed } 252193326Sed if ((srv->srv_tls_ctx = tls_server()) == NULL) { 253193326Sed log_warnx("%s: failed to get tls server", __func__); 254193326Sed return (-1); 255193326Sed } 256193326Sed 257193326Sed if (tls_config_set_protocols(srv->srv_tls_config, 258193326Sed srv->srv_conf.tls_protocols) != 0) { 259193326Sed log_warnx("%s: failed to set tls protocols: %s", 260193326Sed __func__, tls_config_error(srv->srv_tls_config)); 261193326Sed return (-1); 262193326Sed } 263193326Sed if (tls_config_set_ciphers(srv->srv_tls_config, 264193326Sed srv->srv_conf.tls_ciphers) != 0) { 265193326Sed log_warnx("%s: failed to set tls ciphers: %s", 266198092Srdivacky __func__, tls_config_error(srv->srv_tls_config)); 267193326Sed return (-1); 268193326Sed } 269198092Srdivacky if (tls_config_set_dheparams(srv->srv_tls_config, 270193326Sed srv->srv_conf.tls_dhe_params) != 0) { 271193326Sed log_warnx("%s: failed to set tls dhe params: %s", 272198092Srdivacky __func__, tls_config_error(srv->srv_tls_config)); 273193326Sed return (-1); 274193326Sed } 275198092Srdivacky if (tls_config_set_ecdhecurves(srv->srv_tls_config, 276193326Sed srv->srv_conf.tls_ecdhe_curves) != 0) { 277193326Sed log_warnx("%s: failed to set tls ecdhe curves: %s", 278193326Sed __func__, tls_config_error(srv->srv_tls_config)); 279193326Sed return (-1); 280193326Sed } 281193326Sed 282193326Sed if (tls_config_set_keypair_ocsp_mem(srv->srv_tls_config, 283198092Srdivacky srv->srv_conf.tls_cert, srv->srv_conf.tls_cert_len, 284193326Sed srv->srv_conf.tls_key, srv->srv_conf.tls_key_len, 285193326Sed srv->srv_conf.tls_ocsp_staple, 286193326Sed srv->srv_conf.tls_ocsp_staple_len) != 0) { 287193326Sed log_warnx("%s: failed to set tls certificate/key: %s", 288193326Sed __func__, tls_config_error(srv->srv_tls_config)); 289198092Srdivacky return (-1); 290193326Sed } 291193326Sed 292193326Sed if (srv->srv_conf.tls_ca != NULL) { 293193326Sed if (tls_config_set_ca_mem(srv->srv_tls_config, 294193326Sed srv->srv_conf.tls_ca, srv->srv_conf.tls_ca_len) != 0) { 295193326Sed log_warnx("%s: failed to add ca cert(s)", __func__); 296193326Sed return (-1); 297193326Sed } 298193326Sed if (tls_config_set_crl_mem(srv->srv_tls_config, 299193326Sed srv->srv_conf.tls_crl, srv->srv_conf.tls_crl_len) != 0) { 300193326Sed log_warnx("%s: failed to add crl(s)", __func__); 301193326Sed return (-1); 302193326Sed } 303193326Sed if (srv->srv_conf.tls_flags & TLSFLAG_OPTIONAL) 304193326Sed tls_config_verify_client_optional(srv->srv_tls_config); 305193326Sed else 306198092Srdivacky tls_config_verify_client(srv->srv_tls_config); 307193326Sed } 308193326Sed 309193326Sed TAILQ_FOREACH(srv_conf, &srv->srv_hosts, entry) { 310193326Sed if (srv_conf->tls_cert == NULL || srv_conf->tls_key == NULL) 311193326Sed continue; 312193326Sed log_debug("%s: adding keypair for server %s", __func__, 313193326Sed srv->srv_conf.name); 314193326Sed if (tls_config_add_keypair_ocsp_mem(srv->srv_tls_config, 315193326Sed srv_conf->tls_cert, srv_conf->tls_cert_len, 316193326Sed srv_conf->tls_key, srv_conf->tls_key_len, 317193326Sed srv_conf->tls_ocsp_staple, 318193326Sed srv_conf->tls_ocsp_staple_len) != 0) { 319193326Sed log_warnx("%s: failed to add tls keypair", __func__); 320193326Sed return (-1); 321193326Sed } 322193326Sed } 323193326Sed 324193326Sed /* set common session ID among all processes */ 325193326Sed if (tls_config_set_session_id(srv->srv_tls_config, 326193326Sed httpd_env->sc_tls_sid, sizeof(httpd_env->sc_tls_sid)) == -1) { 327198092Srdivacky log_warnx("%s: could not set the TLS session ID: %s", 328193326Sed __func__, tls_config_error(srv->srv_tls_config)); 329193326Sed return (-1); 330198092Srdivacky } 331193326Sed 332193326Sed /* ticket support */ 333193326Sed if (srv->srv_conf.tls_ticket_lifetime) { 334193326Sed if (tls_config_set_session_lifetime(srv->srv_tls_config, 335193326Sed srv->srv_conf.tls_ticket_lifetime) == -1) { 336193326Sed log_warnx("%s: could not set the TLS session lifetime: " 337193326Sed "%s", __func__, 338193326Sed tls_config_error(srv->srv_tls_config)); 339193326Sed return (-1); 340193326Sed } 341198092Srdivacky tls_config_add_ticket_key(srv->srv_tls_config, 342193326Sed srv->srv_conf.tls_ticket_key.tt_keyrev, 343193326Sed srv->srv_conf.tls_ticket_key.tt_key, 344193326Sed sizeof(srv->srv_conf.tls_ticket_key.tt_key)); 345198092Srdivacky explicit_bzero(&srv->srv_conf.tls_ticket_key, 346193326Sed sizeof(srv->srv_conf.tls_ticket_key)); 347193326Sed } 348193326Sed 349193326Sed if (tls_configure(srv->srv_tls_ctx, srv->srv_tls_config) != 0) { 350193326Sed log_warnx("%s: failed to configure tls - %s", __func__, 351193326Sed tls_error(srv->srv_tls_ctx)); 352193326Sed return (-1); 353193326Sed } 354193326Sed 355193326Sed /* We're now done with the public/private key & ca/crl... */ 356193326Sed tls_config_clear_keys(srv->srv_tls_config); 357193326Sed freezero(srv->srv_conf.tls_cert, srv->srv_conf.tls_cert_len); 358193326Sed freezero(srv->srv_conf.tls_key, srv->srv_conf.tls_key_len); 359193326Sed free(srv->srv_conf.tls_ca); 360193326Sed free(srv->srv_conf.tls_crl); 361193326Sed srv->srv_conf.tls_ca = NULL; 362193326Sed srv->srv_conf.tls_cert = NULL; 363193326Sed srv->srv_conf.tls_crl = NULL; 364193326Sed srv->srv_conf.tls_key = NULL; 365193326Sed srv->srv_conf.tls_ca_len = 0; 366193326Sed srv->srv_conf.tls_cert_len = 0; 367193326Sed srv->srv_conf.tls_crl_len = 0; 368193326Sed srv->srv_conf.tls_key_len = 0; 369193326Sed 370193326Sed return (0); 371193326Sed} 372193326Sed 373193326Sedvoid 374193326Sedserver_generate_ticket_key(struct server_config *srv_conf) 375193326Sed{ 376193326Sed struct server_tls_ticket *key = &srv_conf->tls_ticket_key; 377193326Sed 378193326Sed key->tt_id = srv_conf->id; 379193326Sed key->tt_keyrev = arc4random(); 380193326Sed arc4random_buf(key->tt_key, sizeof(key->tt_key)); 381193326Sed} 382193326Sed 383193326Sedvoid 384193326Sedserver_init(struct privsep *ps, struct privsep_proc *p, void *arg) 385193326Sed{ 386193326Sed server_http(); 387193326Sed 388193326Sed if (config_init(ps->ps_env) == -1) 389193326Sed fatal("failed to initialize configuration"); 390193326Sed 391193326Sed /* We use a custom shutdown callback */ 392193326Sed p->p_shutdown = server_shutdown; 393193326Sed 394193326Sed /* Unlimited file descriptors (use system limits) */ 395193326Sed socket_rlimit(-1); 396193326Sed 397193326Sed if (pledge("stdio rpath inet unix recvfd", NULL) == -1) 398193326Sed fatal("pledge"); 399193326Sed 400193326Sed#if 0 401193326Sed /* Schedule statistics timer */ 402193326Sed evtimer_set(&ps->ps_env->sc_statev, server_statistics, NULL); 403193326Sed memcpy(&tv, &ps->ps_env->sc_statinterval, sizeof(tv)); 404193326Sed evtimer_add(&ps->ps_env->sc_statev, &tv); 405193326Sed#endif 406193326Sed} 407193326Sed 408193326Sedvoid 409193326Sedserver_launch(void) 410193326Sed{ 411193326Sed struct server *srv; 412193326Sed 413193326Sed TAILQ_FOREACH(srv, httpd_env->sc_servers, srv_entry) { 414193326Sed log_debug("%s: configuring server %s", __func__, 415198092Srdivacky srv->srv_conf.name); 416193326Sed 417198092Srdivacky server_tls_init(srv); 418193326Sed server_http_init(srv); 419193326Sed 420198092Srdivacky log_debug("%s: running server %s", __func__, 421193326Sed srv->srv_conf.name); 422193326Sed 423194613Sed event_set(&srv->srv_ev, srv->srv_s, EV_READ, 424205408Srdivacky server_accept, srv); 425193326Sed event_add(&srv->srv_ev, NULL); 426193326Sed evtimer_set(&srv->srv_evt, server_accept, srv); 427198092Srdivacky } 428193326Sed} 429193326Sed 430193326Sedvoid 431193326Sedserver_purge(struct server *srv) 432193326Sed{ 433198092Srdivacky struct client *clt; 434193326Sed struct server_config *srv_conf; 435193326Sed 436194711Sed /* shutdown and remove server */ 437194711Sed if (event_initialized(&srv->srv_ev)) 438193326Sed event_del(&srv->srv_ev); 439193326Sed if (evtimer_initialized(&srv->srv_evt)) 440193326Sed evtimer_del(&srv->srv_evt); 441193326Sed 442193326Sed if (srv->srv_s != -1) 443193326Sed close(srv->srv_s); 444193326Sed TAILQ_REMOVE(httpd_env->sc_servers, srv, srv_entry); 445193326Sed 446193326Sed /* cleanup sessions */ 447193326Sed while ((clt = 448193326Sed SPLAY_ROOT(&srv->srv_clients)) != NULL) 449193326Sed server_close(clt, NULL); 450193326Sed 451193326Sed /* cleanup hosts */ 452193326Sed while ((srv_conf = 453198092Srdivacky TAILQ_FIRST(&srv->srv_hosts)) != NULL) { 454193326Sed TAILQ_REMOVE(&srv->srv_hosts, srv_conf, entry); 455198092Srdivacky 456193326Sed /* It might point to our own "default" entry */ 457193326Sed if (srv_conf != &srv->srv_conf) { 458193326Sed serverconfig_free(srv_conf); 459193326Sed free(srv_conf); 460193326Sed } 461193326Sed } 462193326Sed 463193326Sed tls_config_free(srv->srv_tls_config); 464193326Sed tls_free(srv->srv_tls_ctx); 465193326Sed 466193326Sed free(srv); 467193326Sed} 468200583Srdivacky 469205219Srdivackyvoid 470205219Srdivackyserverconfig_free(struct server_config *srv_conf) 471200583Srdivacky{ 472205219Srdivacky struct fastcgi_param *param, *tparam; 473205219Srdivacky 474200583Srdivacky free(srv_conf->return_uri); 475200583Srdivacky free(srv_conf->tls_ca_file); 476200583Srdivacky free(srv_conf->tls_ca); 477200583Srdivacky free(srv_conf->tls_cert_file); 478200583Srdivacky free(srv_conf->tls_crl_file); 479200583Srdivacky free(srv_conf->tls_crl); 480200583Srdivacky free(srv_conf->tls_key_file); 481200583Srdivacky free(srv_conf->tls_ocsp_staple_file); 482200583Srdivacky free(srv_conf->tls_ocsp_staple); 483200583Srdivacky freezero(srv_conf->tls_cert, srv_conf->tls_cert_len); 484200583Srdivacky freezero(srv_conf->tls_key, srv_conf->tls_key_len); 485200583Srdivacky 486205219Srdivacky TAILQ_FOREACH_SAFE(param, &srv_conf->fcgiparams, entry, tparam) 487205408Srdivacky free(param); 488205408Srdivacky} 489205219Srdivacky 490205408Srdivackyvoid 491205408Srdivackyserverconfig_reset(struct server_config *srv_conf) 492205408Srdivacky{ 493205408Srdivacky srv_conf->auth = NULL; 494205219Srdivacky srv_conf->return_uri = NULL; 495205219Srdivacky srv_conf->tls_ca = NULL; 496193326Sed srv_conf->tls_ca_file = NULL; 497193326Sed srv_conf->tls_cert = NULL; 498193326Sed srv_conf->tls_cert_file = NULL; 499193326Sed srv_conf->tls_crl = NULL; 500193326Sed srv_conf->tls_crl_file = NULL; 501193326Sed srv_conf->tls_key = NULL; 502193326Sed srv_conf->tls_key_file = NULL; 503193326Sed srv_conf->tls_ocsp_staple = NULL; 504193326Sed srv_conf->tls_ocsp_staple_file = NULL; 505193326Sed TAILQ_INIT(&srv_conf->fcgiparams); 506193326Sed} 507193326Sed 508193326Sedstruct server * 509198092Srdivackyserver_byaddr(struct sockaddr *addr, in_port_t port) 510193326Sed{ 511193326Sed struct server *srv; 512193326Sed 513193326Sed TAILQ_FOREACH(srv, httpd_env->sc_servers, srv_entry) { 514193326Sed if (port == srv->srv_conf.port && 515193326Sed sockaddr_cmp((struct sockaddr *)&srv->srv_conf.ss, 516193326Sed addr, srv->srv_conf.prefixlen) == 0) 517193326Sed return (srv); 518198092Srdivacky } 519193326Sed 520193326Sed return (NULL); 521193326Sed} 522198092Srdivacky 523193326Sedstruct server_config * 524193326Sedserverconfig_byid(uint32_t id) 525193326Sed{ 526193326Sed struct server *srv; 527193326Sed struct server_config *srv_conf; 528193326Sed 529193326Sed TAILQ_FOREACH(srv, httpd_env->sc_servers, srv_entry) { 530193326Sed if (srv->srv_conf.id == id) 531193326Sed return (&srv->srv_conf); 532193326Sed TAILQ_FOREACH(srv_conf, &srv->srv_hosts, entry) { 533193326Sed if (srv_conf->id == id) 534193326Sed return (srv_conf); 535193326Sed } 536193326Sed } 537193326Sed 538193326Sed return (NULL); 539193326Sed} 540193326Sed 541193326Sedstruct server * 542193326Sedserver_byid(uint32_t id) 543193326Sed{ 544193326Sed struct server *srv; 545193326Sed 546193326Sed TAILQ_FOREACH(srv, httpd_env->sc_servers, srv_entry) { 547193326Sed if (srv->srv_conf.id == id) 548193326Sed return (srv); 549193326Sed } 550193326Sed return (NULL); 551193326Sed} 552193326Sed 553193326Sedint 554193326Sedserver_foreach(int (*srv_cb)(struct server *, 555193326Sed struct server_config *, void *), void *arg) 556193326Sed{ 557198092Srdivacky struct server *srv; 558193326Sed struct server_config *srv_conf; 559193326Sed 560193326Sed TAILQ_FOREACH(srv, httpd_env->sc_servers, srv_entry) { 561193326Sed if ((srv_cb)(srv, &srv->srv_conf, arg) == -1) 562193326Sed return (-1); 563193326Sed TAILQ_FOREACH(srv_conf, &srv->srv_hosts, entry) { 564193326Sed if ((srv_cb)(srv, srv_conf, arg) == -1) 565193326Sed return (-1); 566193326Sed } 567193326Sed } 568193326Sed 569198092Srdivacky return (0); 570193326Sed} 571198092Srdivacky 572193326Sedstruct server * 573193326Sedserver_match(struct server *s2, int match_name) 574193326Sed{ 575193326Sed struct server *s1; 576193326Sed 577193326Sed /* Attempt to find matching server. */ 578198092Srdivacky TAILQ_FOREACH(s1, httpd_env->sc_servers, srv_entry) { 579193326Sed if ((s1->srv_conf.flags & SRVFLAG_LOCATION) != 0) 580193326Sed continue; 581193326Sed if (match_name) { 582193326Sed if (strcmp(s1->srv_conf.name, s2->srv_conf.name) != 0) 583193326Sed continue; 584193326Sed } 585193326Sed if (s1->srv_conf.port != s2->srv_conf.port) 586193326Sed continue; 587193326Sed if (sockaddr_cmp( 588193326Sed (struct sockaddr *)&s1->srv_conf.ss, 589193326Sed (struct sockaddr *)&s2->srv_conf.ss, 590193326Sed s1->srv_conf.prefixlen) != 0) 591193326Sed continue; 592193326Sed 593193326Sed return (s1); 594193326Sed } 595193326Sed 596198092Srdivacky return (NULL); 597193326Sed} 598193326Sed 599193326Sedint 600193326Sedserver_socket_af(struct sockaddr_storage *ss, in_port_t port) 601193326Sed{ 602193326Sed switch (ss->ss_family) { 603193326Sed case AF_INET: 604193326Sed ((struct sockaddr_in *)ss)->sin_port = port; 605203955Srdivacky ((struct sockaddr_in *)ss)->sin_len = 606203955Srdivacky sizeof(struct sockaddr_in); 607203955Srdivacky break; 608203955Srdivacky case AF_INET6: 609203955Srdivacky ((struct sockaddr_in6 *)ss)->sin6_port = port; 610203955Srdivacky ((struct sockaddr_in6 *)ss)->sin6_len = 611203955Srdivacky sizeof(struct sockaddr_in6); 612193326Sed break; 613193326Sed default: 614193326Sed return (-1); 615193326Sed } 616193326Sed 617193326Sed return (0); 618193326Sed} 619193326Sed 620193326Sedin_port_t 621193326Sedserver_socket_getport(struct sockaddr_storage *ss) 622193326Sed{ 623193326Sed switch (ss->ss_family) { 624193326Sed case AF_INET: 625193326Sed return (((struct sockaddr_in *)ss)->sin_port); 626193326Sed case AF_INET6: 627193326Sed return (((struct sockaddr_in6 *)ss)->sin6_port); 628193326Sed default: 629193326Sed return (0); 630193326Sed } 631193326Sed 632193326Sed /* NOTREACHED */ 633193326Sed return (0); 634193326Sed} 635193326Sed 636193326Sedint 637198092Srdivackyserver_socket(struct sockaddr_storage *ss, in_port_t port, 638193326Sed struct server_config *srv_conf, int fd, int reuseport) 639193326Sed{ 640193326Sed struct linger lng; 641193326Sed int s = -1, val; 642198092Srdivacky 643193326Sed if (server_socket_af(ss, port) == -1) 644193326Sed goto bad; 645193326Sed 646193326Sed s = fd == -1 ? socket(ss->ss_family, SOCK_STREAM | SOCK_NONBLOCK, 647193326Sed IPPROTO_TCP) : fd; 648193326Sed if (s == -1) 649193326Sed goto bad; 650193326Sed 651193326Sed /* 652193326Sed * Socket options 653193326Sed */ 654193326Sed memset(&lng, 0, sizeof(lng)); 655198092Srdivacky if (setsockopt(s, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng)) == -1) 656193326Sed goto bad; 657193326Sed if (reuseport) { 658193326Sed val = 1; 659193326Sed if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &val, 660198092Srdivacky sizeof(int)) == -1) 661193326Sed goto bad; 662193326Sed } 663193326Sed if (srv_conf->tcpflags & TCPFLAG_BUFSIZ) { 664193326Sed val = srv_conf->tcpbufsiz; 665193326Sed if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, 666193326Sed &val, sizeof(val)) == -1) 667193326Sed goto bad; 668193326Sed val = srv_conf->tcpbufsiz; 669193326Sed if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, 670193326Sed &val, sizeof(val)) == -1) 671193326Sed goto bad; 672193326Sed } 673193326Sed 674193326Sed /* 675193326Sed * IP options 676193326Sed */ 677193326Sed if (srv_conf->tcpflags & TCPFLAG_IPTTL) { 678193326Sed val = (int)srv_conf->tcpipttl; 679193326Sed switch (ss->ss_family) { 680193326Sed case AF_INET: 681193326Sed if (setsockopt(s, IPPROTO_IP, IP_TTL, 682193326Sed &val, sizeof(val)) == -1) 683193326Sed goto bad; 684193326Sed break; 685193326Sed case AF_INET6: 686193326Sed if (setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, 687193326Sed &val, sizeof(val)) == -1) 688193326Sed goto bad; 689193326Sed break; 690198092Srdivacky } 691193326Sed } 692193326Sed if (srv_conf->tcpflags & TCPFLAG_IPMINTTL) { 693198092Srdivacky val = (int)srv_conf->tcpipminttl; 694193326Sed switch (ss->ss_family) { 695193326Sed case AF_INET: 696193326Sed if (setsockopt(s, IPPROTO_IP, IP_MINTTL, 697193326Sed &val, sizeof(val)) == -1) 698193326Sed goto bad; 699193326Sed break; 700193326Sed case AF_INET6: 701193326Sed if (setsockopt(s, IPPROTO_IPV6, IPV6_MINHOPCOUNT, 702193326Sed &val, sizeof(val)) == -1) 703193326Sed goto bad; 704193326Sed break; 705193326Sed } 706193326Sed } 707193326Sed 708193326Sed /* 709193326Sed * TCP options 710193326Sed */ 711205219Srdivacky if (srv_conf->tcpflags & (TCPFLAG_NODELAY|TCPFLAG_NNODELAY)) { 712205219Srdivacky if (srv_conf->tcpflags & TCPFLAG_NNODELAY) 713193326Sed val = 0; 714193326Sed else 715193326Sed val = 1; 716198092Srdivacky if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, 717193326Sed &val, sizeof(val)) == -1) 718205219Srdivacky goto bad; 719205219Srdivacky } 720205219Srdivacky if (srv_conf->tcpflags & (TCPFLAG_SACK|TCPFLAG_NSACK)) { 721205219Srdivacky if (srv_conf->tcpflags & TCPFLAG_NSACK) 722205219Srdivacky val = 0; 723205219Srdivacky else 724205219Srdivacky val = 1; 725193326Sed if (setsockopt(s, IPPROTO_TCP, TCP_SACK_ENABLE, 726193326Sed &val, sizeof(val)) == -1) 727193326Sed goto bad; 728193326Sed } 729193326Sed 730205219Srdivacky return (s); 731205219Srdivacky 732205219Srdivacky bad: 733205219Srdivacky if (s != -1) 734205219Srdivacky close(s); 735205219Srdivacky return (-1); 736198092Srdivacky} 737205219Srdivacky 738205219Srdivackyint 739205219Srdivackyserver_socket_listen(struct sockaddr_storage *ss, in_port_t port, 740193326Sed struct server_config *srv_conf) 741193326Sed{ 742193326Sed int s; 743193326Sed 744193326Sed if ((s = server_socket(ss, port, srv_conf, -1, 1)) == -1) 745193326Sed return (-1); 746205219Srdivacky 747205219Srdivacky if (bind(s, (struct sockaddr *)ss, ss->ss_len) == -1) 748193326Sed goto bad; 749193326Sed if (listen(s, srv_conf->tcpbacklog) == -1) 750205219Srdivacky goto bad; 751193326Sed 752193326Sed return (s); 753205219Srdivacky 754205219Srdivacky bad: 755193326Sed close(s); 756193326Sed return (-1); 757205219Srdivacky} 758193326Sed 759193326Sedint 760205219Srdivackyserver_socket_connect(struct sockaddr_storage *ss, in_port_t port, 761205219Srdivacky struct server_config *srv_conf) 762205219Srdivacky{ 763205219Srdivacky int s; 764205219Srdivacky 765205219Srdivacky if ((s = server_socket(ss, port, srv_conf, -1, 0)) == -1) 766193326Sed return (-1); 767205219Srdivacky 768205219Srdivacky if (connect(s, (struct sockaddr *)ss, ss->ss_len) == -1) { 769205219Srdivacky if (errno != EINPROGRESS) 770198092Srdivacky goto bad; 771193326Sed } 772193326Sed 773193326Sed return (s); 774198092Srdivacky 775193326Sed bad: 776193326Sed close(s); 777198092Srdivacky return (-1); 778193326Sed} 779193326Sed 780193326Sedvoid 781193326Sedserver_tls_readcb(int fd, short event, void *arg) 782193326Sed{ 783193326Sed struct bufferevent *bufev = arg; 784193326Sed struct client *clt = bufev->cbarg; 785193326Sed char rbuf[IBUF_READ_SIZE]; 786193326Sed int what = EVBUFFER_READ; 787193326Sed int howmuch = IBUF_READ_SIZE; 788193326Sed ssize_t ret; 789193326Sed size_t len; 790198092Srdivacky 791193326Sed if (event == EV_TIMEOUT) { 792193326Sed what |= EVBUFFER_TIMEOUT; 793193326Sed goto err; 794193326Sed } 795193326Sed 796193326Sed if (bufev->wm_read.high != 0) 797193326Sed howmuch = MINIMUM(sizeof(rbuf), bufev->wm_read.high); 798193326Sed 799193326Sed ret = tls_read(clt->clt_tls_ctx, rbuf, howmuch); 800193326Sed if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT) { 801193326Sed goto retry; 802193326Sed } else if (ret == -1) { 803193326Sed what |= EVBUFFER_ERROR; 804198092Srdivacky goto err; 805193326Sed } 806193326Sed len = ret; 807193326Sed 808193326Sed if (len == 0) { 809193326Sed what |= EVBUFFER_EOF; 810193326Sed goto err; 811193326Sed } 812193326Sed 813193326Sed if (evbuffer_add(bufev->input, rbuf, len) == -1) { 814193326Sed what |= EVBUFFER_ERROR; 815205219Srdivacky goto err; 816205219Srdivacky } 817193326Sed 818193326Sed server_bufferevent_add(&bufev->ev_read, bufev->timeout_read); 819193326Sed 820193326Sed len = EVBUFFER_LENGTH(bufev->input); 821193326Sed if (bufev->wm_read.low != 0 && len < bufev->wm_read.low) 822193326Sed return; 823198092Srdivacky if (bufev->wm_read.high != 0 && len > bufev->wm_read.high) { 824193326Sed struct evbuffer *buf = bufev->input; 825193326Sed event_del(&bufev->ev_read); 826205219Srdivacky evbuffer_setcb(buf, bufferevent_read_pressure_cb, bufev); 827205219Srdivacky return; 828205219Srdivacky } 829205219Srdivacky 830205219Srdivacky if (bufev->readcb != NULL) 831205219Srdivacky (*bufev->readcb)(bufev, bufev->cbarg); 832205219Srdivacky return; 833205219Srdivacky 834205219Srdivacky retry: 835193326Sed server_bufferevent_add(&bufev->ev_read, bufev->timeout_read); 836193326Sed return; 837193326Sed 838193326Sed err: 839193326Sed (*bufev->errorcb)(bufev, what, bufev->cbarg); 840193326Sed} 841198092Srdivacky 842193326Sedvoid 843193326Sedserver_tls_writecb(int fd, short event, void *arg) 844193326Sed{ 845198092Srdivacky struct bufferevent *bufev = arg; 846193326Sed struct client *clt = bufev->cbarg; 847193326Sed ssize_t ret; 848193326Sed short what = EVBUFFER_WRITE; 849193326Sed size_t len; 850193326Sed 851193326Sed if (event == EV_TIMEOUT) { 852193326Sed what |= EVBUFFER_TIMEOUT; 853193326Sed goto err; 854193326Sed } 855193326Sed 856193326Sed if (EVBUFFER_LENGTH(bufev->output)) { 857193326Sed ret = tls_write(clt->clt_tls_ctx, 858193326Sed EVBUFFER_DATA(bufev->output), 859193326Sed EVBUFFER_LENGTH(bufev->output)); 860193326Sed if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT) { 861198092Srdivacky goto retry; 862193326Sed } else if (ret == -1) { 863193326Sed what |= EVBUFFER_ERROR; 864193326Sed goto err; 865193326Sed } 866193326Sed len = ret; 867193326Sed evbuffer_drain(bufev->output, len); 868193326Sed } 869193326Sed 870193326Sed if (EVBUFFER_LENGTH(bufev->output) != 0) 871193326Sed server_bufferevent_add(&bufev->ev_write, bufev->timeout_write); 872193326Sed 873193326Sed if (bufev->writecb != NULL && 874193326Sed EVBUFFER_LENGTH(bufev->output) <= bufev->wm_write.low) 875193326Sed (*bufev->writecb)(bufev, bufev->cbarg); 876193326Sed return; 877193326Sed 878193326Sed retry: 879193326Sed server_bufferevent_add(&bufev->ev_write, bufev->timeout_write); 880193326Sed return; 881193326Sed 882193326Sed err: 883198092Srdivacky (*bufev->errorcb)(bufev, what, bufev->cbarg); 884193326Sed} 885193326Sed 886193326Sedvoid 887193326Sedserver_input(struct client *clt) 888193326Sed{ 889193326Sed struct server_config *srv_conf = clt->clt_srv_conf; 890198092Srdivacky evbuffercb inrd = server_read; 891193326Sed evbuffercb inwr = server_write; 892193326Sed socklen_t slen; 893198092Srdivacky 894193326Sed if (server_httpdesc_init(clt) == -1) { 895193326Sed server_close(clt, "failed to allocate http descriptor"); 896193326Sed return; 897193326Sed } 898193326Sed 899193326Sed clt->clt_toread = TOREAD_HTTP_HEADER; 900193326Sed inrd = server_read_http; 901193326Sed 902198092Srdivacky slen = sizeof(clt->clt_sndbufsiz); 903193326Sed if (getsockopt(clt->clt_s, SOL_SOCKET, SO_SNDBUF, 904193326Sed &clt->clt_sndbufsiz, &slen) == -1) { 905193326Sed server_close(clt, "failed to get send buffer size"); 906193326Sed return; 907193326Sed } 908198092Srdivacky 909193326Sed /* 910193326Sed * Client <-> Server 911193326Sed */ 912198092Srdivacky clt->clt_bev = bufferevent_new(clt->clt_s, inrd, inwr, 913193326Sed server_error, clt); 914193326Sed if (clt->clt_bev == NULL) { 915193326Sed server_close(clt, "failed to allocate input buffer event"); 916193326Sed return; 917193326Sed } 918193326Sed 919193326Sed if (srv_conf->flags & SRVFLAG_TLS) { 920205219Srdivacky event_set(&clt->clt_bev->ev_read, clt->clt_s, EV_READ, 921205219Srdivacky server_tls_readcb, clt->clt_bev); 922193326Sed event_set(&clt->clt_bev->ev_write, clt->clt_s, EV_WRITE, 923193326Sed server_tls_writecb, clt->clt_bev); 924193326Sed } 925193326Sed 926205219Srdivacky /* Adjust write watermark to the socket buffer output size */ 927205219Srdivacky bufferevent_setwatermark(clt->clt_bev, EV_WRITE, 928193326Sed SERVER_MIN_PREFETCHED * clt->clt_sndbufsiz, 0); 929193326Sed /* Read at most amount of data that fits in one fcgi record. */ 930193326Sed bufferevent_setwatermark(clt->clt_bev, EV_READ, 0, FCGI_CONTENT_SIZE); 931193326Sed 932193326Sed bufferevent_settimeout(clt->clt_bev, 933193326Sed srv_conf->requesttimeout.tv_sec, srv_conf->requesttimeout.tv_sec); 934198092Srdivacky bufferevent_enable(clt->clt_bev, EV_READ|EV_WRITE); 935193326Sed} 936193326Sed 937193326Sedvoid 938193326Sedserver_write(struct bufferevent *bev, void *arg) 939193326Sed{ 940193326Sed struct client *clt = arg; 941198092Srdivacky struct evbuffer *dst = EVBUFFER_OUTPUT(bev); 942193326Sed 943193326Sed if (EVBUFFER_LENGTH(dst) == 0 && 944193326Sed clt->clt_toread == TOREAD_HTTP_NONE) 945193326Sed goto done; 946193326Sed 947193326Sed getmonotime(&clt->clt_tv_last); 948193326Sed 949193326Sed if (clt->clt_done) 950193326Sed goto done; 951198092Srdivacky 952193326Sed if (clt->clt_srvbev && clt->clt_srvbev_throttled) { 953193326Sed bufferevent_enable(clt->clt_srvbev, EV_READ); 954193326Sed clt->clt_srvbev_throttled = 0; 955193326Sed } 956198092Srdivacky 957193326Sed return; 958193326Sed done: 959193326Sed (*bev->errorcb)(bev, EVBUFFER_WRITE, bev->cbarg); 960193326Sed return; 961193326Sed} 962193326Sed 963193326Sedvoid 964193326Sedserver_dump(struct client *clt, const void *buf, size_t len) 965193326Sed{ 966193326Sed if (!len) 967205219Srdivacky return; 968205219Srdivacky 969193326Sed /* 970198092Srdivacky * This function will dump the specified message directly 971205219Srdivacky * to the underlying client, without waiting for success 972193326Sed * of non-blocking events etc. This is useful to print an 973193326Sed * error message before gracefully closing the client. 974193326Sed */ 975193326Sed if (clt->clt_tls_ctx != NULL) 976193326Sed (void)tls_write(clt->clt_tls_ctx, buf, len); 977193326Sed else 978193326Sed (void)write(clt->clt_s, buf, len); 979193326Sed} 980193326Sed 981193326Sedvoid 982193326Sedserver_read(struct bufferevent *bev, void *arg) 983193326Sed{ 984198092Srdivacky struct client *clt = arg; 985193326Sed struct evbuffer *src = EVBUFFER_INPUT(bev); 986193326Sed 987198092Srdivacky getmonotime(&clt->clt_tv_last); 988193326Sed 989193326Sed if (!EVBUFFER_LENGTH(src)) 990198092Srdivacky return; 991193326Sed if (server_bufferevent_write_buffer(clt, src) == -1) 992193326Sed goto fail; 993193326Sed if (clt->clt_done) 994198092Srdivacky goto done; 995205219Srdivacky 996193326Sed if (EVBUFFER_LENGTH(EVBUFFER_OUTPUT(clt->clt_bev)) > (size_t) 997193326Sed SERVER_MAX_PREFETCH * clt->clt_sndbufsiz) { 998193326Sed bufferevent_disable(clt->clt_srvbev, EV_READ); 999198092Srdivacky clt->clt_srvbev_throttled = 1; 1000193326Sed } 1001193326Sed 1002193326Sed return; 1003193326Sed done: 1004193326Sed (*bev->errorcb)(bev, EVBUFFER_READ, bev->cbarg); 1005193326Sed return; 1006193326Sed fail: 1007193326Sed server_close(clt, strerror(errno)); 1008193326Sed} 1009193326Sed 1010193326Sedvoid 1011193326Sedserver_error(struct bufferevent *bev, short error, void *arg) 1012193326Sed{ 1013193326Sed struct client *clt = arg; 1014193326Sed struct evbuffer *dst; 1015193326Sed 1016193326Sed if (error & EVBUFFER_TIMEOUT) { 1017198092Srdivacky if (!clt->clt_headersdone && clt->clt_line > 0) 1018193326Sed server_abort_http(clt, 408, "timeout"); 1019198092Srdivacky else 1020193326Sed server_close(clt, "timeout"); 1021193326Sed return; 1022193326Sed } 1023193326Sed if (error & EVBUFFER_ERROR) { 1024193326Sed if (errno == EFBIG) { 1025193326Sed bufferevent_enable(bev, EV_READ); 1026193326Sed return; 1027193326Sed } 1028193326Sed server_close(clt, "buffer event error"); 1029193326Sed return; 1030193326Sed } 1031193326Sed if (error & EVBUFFER_EOF) { 1032193326Sed server_close(clt, "closed"); 1033193326Sed return; 1034193326Sed } 1035194613Sed if (error & (EVBUFFER_READ|EVBUFFER_WRITE)) { 1036194613Sed bufferevent_disable(bev, EV_READ|EV_WRITE); 1037194613Sed 1038194613Sed clt->clt_done = 1; 1039194613Sed 1040194613Sed dst = EVBUFFER_OUTPUT(clt->clt_bev); 1041194613Sed if (EVBUFFER_LENGTH(dst)) { 1042194613Sed /* Finish writing all data first */ 1043193326Sed bufferevent_enable(clt->clt_bev, EV_WRITE); 1044194613Sed return; 1045194613Sed } 1046194613Sed 1047194613Sed server_close(clt, "done"); 1048198092Srdivacky return; 1049194613Sed } 1050194613Sed server_close(clt, "unknown event error"); 1051205219Srdivacky return; 1052205219Srdivacky} 1053205219Srdivacky 1054205219Srdivackyvoid 1055205219Srdivackyserver_accept(int fd, short event, void *arg) 1056205219Srdivacky{ 1057194613Sed struct server *srv = arg; 1058200583Srdivacky struct client *clt = NULL; 1059200583Srdivacky socklen_t slen; 1060200583Srdivacky struct sockaddr_storage ss; 1061200583Srdivacky int s = -1; 1062200583Srdivacky 1063200583Srdivacky event_add(&srv->srv_ev, NULL); 1064200583Srdivacky if ((event & EV_TIMEOUT)) 1065200583Srdivacky return; 1066200583Srdivacky 1067200583Srdivacky slen = sizeof(ss); 1068200583Srdivacky if ((s = accept_reserve(fd, (struct sockaddr *)&ss, 1069200583Srdivacky &slen, FD_RESERVE, &server_inflight)) == -1) { 1070200583Srdivacky /* 1071200583Srdivacky * Pause accept if we are out of file descriptors, or 1072200583Srdivacky * libevent will haunt us here too. 1073200583Srdivacky */ 1074200583Srdivacky if (errno == ENFILE || errno == EMFILE) { 1075200583Srdivacky struct timeval evtpause = { 1, 0 }; 1076200583Srdivacky 1077200583Srdivacky event_del(&srv->srv_ev); 1078200583Srdivacky evtimer_add(&srv->srv_evt, &evtpause); 1079200583Srdivacky log_debug("%s: deferring connections", __func__); 1080200583Srdivacky } 1081200583Srdivacky return; 1082200583Srdivacky } 1083200583Srdivacky if (server_clients >= SERVER_MAX_CLIENTS) 1084204643Srdivacky goto err; 1085205219Srdivacky 1086204643Srdivacky if ((clt = calloc(1, sizeof(*clt))) == NULL) 1087204643Srdivacky goto err; 1088204643Srdivacky 1089204643Srdivacky /* Pre-allocate log buffer */ 1090204643Srdivacky clt->clt_log = evbuffer_new(); 1091204643Srdivacky if (clt->clt_log == NULL) 1092205219Srdivacky goto err; 1093205219Srdivacky 1094204643Srdivacky clt->clt_s = s; 1095204643Srdivacky clt->clt_fd = -1; 1096204643Srdivacky clt->clt_toread = TOREAD_UNLIMITED; 1097204643Srdivacky clt->clt_srv = srv; 1098204643Srdivacky clt->clt_srv_conf = &srv->srv_conf; 1099204643Srdivacky clt->clt_id = ++server_cltid; 1100204643Srdivacky clt->clt_srv_id = srv->srv_conf.id; 1101204643Srdivacky clt->clt_pid = getpid(); 1102200583Srdivacky clt->clt_inflight = 1; 1103194613Sed 1104194613Sed /* get local address */ 1105195099Sed slen = sizeof(clt->clt_srv_ss); 1106195099Sed if (getsockname(s, (struct sockaddr *)&clt->clt_srv_ss, 1107195099Sed &slen) == -1) { 1108195099Sed server_close(clt, "listen address lookup failed"); 1109195099Sed return; 1110195099Sed } 1111195099Sed 1112195099Sed /* get client address */ 1113198092Srdivacky memcpy(&clt->clt_ss, &ss, sizeof(clt->clt_ss)); 1114195099Sed 1115195099Sed /* get ports */ 1116198092Srdivacky switch (ss.ss_family) { 1117195099Sed case AF_INET: 1118195099Sed clt->clt_port = ((struct sockaddr_in *)&ss)->sin_port; 1119195099Sed break; 1120194613Sed case AF_INET6: 1121195099Sed clt->clt_port = ((struct sockaddr_in6 *)&ss)->sin6_port; 1122195099Sed break; 1123198092Srdivacky } 1124195099Sed 1125195099Sed getmonotime(&clt->clt_tv_start); 1126195099Sed memcpy(&clt->clt_tv_last, &clt->clt_tv_start, sizeof(clt->clt_tv_last)); 1127198092Srdivacky 1128195099Sed server_clients++; 1129195099Sed SPLAY_INSERT(client_tree, &srv->srv_clients, clt); 1130198092Srdivacky 1131195099Sed /* Pre-allocate output buffer */ 1132195099Sed clt->clt_output = evbuffer_new(); 1133195099Sed if (clt->clt_output == NULL) { 1134195099Sed server_close(clt, "failed to allocate output buffer"); 1135195099Sed return; 1136195099Sed } 1137195099Sed 1138195099Sed if (srv->srv_conf.flags & SRVFLAG_TLS) { 1139195099Sed if (tls_accept_socket(srv->srv_tls_ctx, &clt->clt_tls_ctx, 1140195099Sed clt->clt_s) != 0) { 1141195099Sed server_close(clt, "failed to accept tls socket"); 1142195099Sed return; 1143195099Sed } 1144195099Sed event_again(&clt->clt_ev, clt->clt_s, EV_TIMEOUT|EV_READ, 1145195099Sed server_tls_handshake, &clt->clt_tv_start, 1146195099Sed &srv->srv_conf.timeout, clt); 1147195099Sed return; 1148198092Srdivacky } 1149195099Sed 1150195099Sed server_input(clt); 1151198092Srdivacky return; 1152195099Sed 1153198092Srdivacky err: 1154195099Sed if (s != -1) { 1155195099Sed close(s); 1156198092Srdivacky free(clt); 1157195099Sed /* 1158195099Sed * the client struct was not completely set up, but still 1159195099Sed * counted as an inflight client. account for this. 1160195099Sed */ 1161195099Sed server_inflight_dec(NULL, __func__); 1162195099Sed } 1163195099Sed} 1164195099Sed 1165195099Sedvoid 1166195099Sedserver_tls_handshake(int fd, short event, void *arg) 1167195099Sed{ 1168195099Sed struct client *clt = (struct client *)arg; 1169195099Sed struct server *srv = (struct server *)clt->clt_srv; 1170198092Srdivacky int ret; 1171195099Sed 1172195099Sed if (event == EV_TIMEOUT) { 1173198092Srdivacky server_close(clt, "tls handshake timeout"); 1174195099Sed return; 1175198092Srdivacky } 1176195099Sed 1177195099Sed if (srv->srv_tls_ctx == NULL || clt->clt_tls_ctx == NULL) 1178195099Sed fatalx("NULL tls context"); 1179195099Sed 1180198092Srdivacky ret = tls_handshake(clt->clt_tls_ctx); 1181200583Srdivacky if (ret == 0) { 1182200583Srdivacky server_input(clt); 1183200583Srdivacky } else if (ret == TLS_WANT_POLLIN) { 1184200583Srdivacky event_again(&clt->clt_ev, clt->clt_s, EV_TIMEOUT|EV_READ, 1185200583Srdivacky server_tls_handshake, &clt->clt_tv_start, 1186198092Srdivacky &srv->srv_conf.timeout, clt); 1187200583Srdivacky } else if (ret == TLS_WANT_POLLOUT) { 1188200583Srdivacky event_again(&clt->clt_ev, clt->clt_s, EV_TIMEOUT|EV_WRITE, 1189200583Srdivacky server_tls_handshake, &clt->clt_tv_start, 1190200583Srdivacky &srv->srv_conf.timeout, clt); 1191200583Srdivacky } else { 1192198092Srdivacky log_debug("%s: tls handshake failed - %s", __func__, 1193200583Srdivacky tls_error(clt->clt_tls_ctx)); 1194200583Srdivacky server_close(clt, "tls handshake failed"); 1195195099Sed } 1196195099Sed} 1197193326Sed 1198193326Sedvoid 1199193326Sedserver_inflight_dec(struct client *clt, const char *why) 1200198092Srdivacky{ 1201198092Srdivacky if (clt != NULL) { 1202198092Srdivacky /* the flight already left inflight mode. */ 1203198092Srdivacky if (clt->clt_inflight == 0) 1204198092Srdivacky return; 1205198092Srdivacky clt->clt_inflight = 0; 1206193326Sed } 1207193326Sed 1208193326Sed /* the file was never opened, thus this was an inflight client. */ 1209193326Sed server_inflight--; 1210193326Sed DPRINTF("%s: inflight decremented, now %d, %s", 1211193326Sed __func__, server_inflight, why); 1212198092Srdivacky} 1213198092Srdivacky 1214198092Srdivackyvoid 1215198092Srdivackyserver_sendlog(struct server_config *srv_conf, int cmd, const char *emsg, ...) 1216198092Srdivacky{ 1217193326Sed va_list ap; 1218193326Sed char *msg; 1219193326Sed int ret; 1220 struct iovec iov[2]; 1221 1222 if (srv_conf->flags & SRVFLAG_SYSLOG) { 1223 va_start(ap, emsg); 1224 if (cmd == IMSG_LOG_ACCESS) 1225 vlog(LOG_INFO, emsg, ap); 1226 else 1227 vlog(LOG_DEBUG, emsg, ap); 1228 va_end(ap); 1229 return; 1230 } 1231 1232 va_start(ap, emsg); 1233 ret = vasprintf(&msg, emsg, ap); 1234 va_end(ap); 1235 if (ret == -1) { 1236 log_warn("%s: vasprintf", __func__); 1237 return; 1238 } 1239 1240 iov[0].iov_base = &srv_conf->id; 1241 iov[0].iov_len = sizeof(srv_conf->id); 1242 iov[1].iov_base = msg; 1243 iov[1].iov_len = ret + 1; 1244 1245 if (proc_composev(httpd_env->sc_ps, PROC_LOGGER, cmd, iov, 2) != 0) { 1246 log_warn("%s: failed to compose imsg", __func__); 1247 free(msg); 1248 return; 1249 } 1250 free(msg); 1251} 1252 1253void 1254server_log(struct client *clt, const char *msg) 1255{ 1256 char ibuf[HOST_NAME_MAX+1], obuf[HOST_NAME_MAX+1]; 1257 struct server_config *srv_conf = clt->clt_srv_conf; 1258 char *ptr = NULL, *vmsg = NULL; 1259 int debug_cmd = -1; 1260 1261 switch (srv_conf->logformat) { 1262 case LOG_FORMAT_CONNECTION: 1263 debug_cmd = IMSG_LOG_ACCESS; 1264 break; 1265 default: 1266 if (log_getverbose() > 1) 1267 debug_cmd = IMSG_LOG_ERROR; 1268 if (EVBUFFER_LENGTH(clt->clt_log)) { 1269 while ((ptr = 1270 evbuffer_readline(clt->clt_log)) != NULL) { 1271 server_sendlog(srv_conf, 1272 IMSG_LOG_ACCESS, "%s", ptr); 1273 free(ptr); 1274 } 1275 } 1276 break; 1277 } 1278 1279 if (debug_cmd != -1 && msg != NULL) { 1280 memset(ibuf, 0, sizeof(ibuf)); 1281 memset(obuf, 0, sizeof(obuf)); 1282 (void)print_host(&clt->clt_ss, ibuf, sizeof(ibuf)); 1283 (void)server_http_host(&clt->clt_srv_ss, obuf, sizeof(obuf)); 1284 if (EVBUFFER_LENGTH(clt->clt_log) && 1285 evbuffer_add_printf(clt->clt_log, "\n") != -1) 1286 ptr = evbuffer_readline(clt->clt_log); 1287 (void)stravis(&vmsg, msg, HTTPD_LOGVIS); 1288 server_sendlog(srv_conf, debug_cmd, "server %s, " 1289 "client %d (%d active), %s:%u -> %s, " 1290 "%s%s%s", srv_conf->name, clt->clt_id, server_clients, 1291 ibuf, ntohs(clt->clt_port), obuf, vmsg == NULL ? "" : vmsg, 1292 ptr == NULL ? "" : ",", ptr == NULL ? "" : ptr); 1293 free(vmsg); 1294 free(ptr); 1295 } 1296} 1297 1298void 1299server_close(struct client *clt, const char *msg) 1300{ 1301 struct server *srv = clt->clt_srv; 1302 1303 if (clt->clt_fcgi_count-- > 0) { 1304 clt->clt_fcgi_error = msg; 1305 return; 1306 } 1307 1308 SPLAY_REMOVE(client_tree, &srv->srv_clients, clt); 1309 1310 /* free the HTTP descriptors incl. headers */ 1311 server_close_http(clt); 1312 1313 /* tls_close must be called before the underlying socket is closed. */ 1314 if (clt->clt_tls_ctx != NULL) 1315 tls_close(clt->clt_tls_ctx); /* XXX - error handling */ 1316 tls_free(clt->clt_tls_ctx); 1317 1318 event_del(&clt->clt_ev); 1319 if (clt->clt_bev != NULL) 1320 bufferevent_disable(clt->clt_bev, EV_READ|EV_WRITE); 1321 if (clt->clt_srvbev != NULL) 1322 bufferevent_disable(clt->clt_srvbev, EV_READ|EV_WRITE); 1323 1324 server_log(clt, msg); 1325 1326 if (clt->clt_bev != NULL) 1327 bufferevent_free(clt->clt_bev); 1328 if (clt->clt_output != NULL) 1329 evbuffer_free(clt->clt_output); 1330 if (clt->clt_srvevb != NULL) 1331 evbuffer_free(clt->clt_srvevb); 1332 1333 if (clt->clt_srvbev != NULL) 1334 bufferevent_free(clt->clt_srvbev); 1335 1336 if (clt->clt_fd != -1) 1337 close(clt->clt_fd); 1338 if (clt->clt_s != -1) 1339 close(clt->clt_s); 1340 1341 server_inflight_dec(clt, __func__); 1342 1343 if (clt->clt_log != NULL) 1344 evbuffer_free(clt->clt_log); 1345 1346 free(clt); 1347 server_clients--; 1348} 1349 1350int 1351server_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg) 1352{ 1353 struct server *srv; 1354 struct server_tls_ticket key; 1355 1356 switch (imsg->hdr.type) { 1357 case IMSG_CFG_MEDIA: 1358 config_getmedia(httpd_env, imsg); 1359 break; 1360 case IMSG_CFG_AUTH: 1361 config_getauth(httpd_env, imsg); 1362 break; 1363 case IMSG_CFG_SERVER: 1364 config_getserver(httpd_env, imsg); 1365 break; 1366 case IMSG_CFG_TLS: 1367 config_getserver_tls(httpd_env, imsg); 1368 break; 1369 case IMSG_CFG_FCGI: 1370 config_getserver_fcgiparams(httpd_env, imsg); 1371 break; 1372 case IMSG_CFG_DONE: 1373 config_getcfg(httpd_env, imsg); 1374 break; 1375 case IMSG_CTL_START: 1376 server_launch(); 1377 break; 1378 case IMSG_CTL_RESET: 1379 config_getreset(httpd_env, imsg); 1380 break; 1381 case IMSG_TLSTICKET_REKEY: 1382 IMSG_SIZE_CHECK(imsg, (&key)); 1383 memcpy(&key, imsg->data, sizeof(key)); 1384 /* apply to the right server */ 1385 srv = server_byid(key.tt_id); 1386 if (srv) { 1387 tls_config_add_ticket_key(srv->srv_tls_config, 1388 key.tt_keyrev, key.tt_key, sizeof(key.tt_key)); 1389 } 1390 break; 1391 default: 1392 return (-1); 1393 } 1394 1395 return (0); 1396} 1397 1398int 1399server_dispatch_logger(int fd, struct privsep_proc *p, struct imsg *imsg) 1400{ 1401 switch (imsg->hdr.type) { 1402 default: 1403 return (-1); 1404 } 1405 1406 return (0); 1407} 1408 1409int 1410server_bufferevent_add(struct event *ev, int timeout) 1411{ 1412 struct timeval tv, *ptv = NULL; 1413 1414 if (timeout) { 1415 timerclear(&tv); 1416 tv.tv_sec = timeout; 1417 ptv = &tv; 1418 } 1419 1420 return (event_add(ev, ptv)); 1421} 1422 1423int 1424server_bufferevent_printf(struct client *clt, const char *fmt, ...) 1425{ 1426 int ret; 1427 va_list ap; 1428 char *str; 1429 1430 va_start(ap, fmt); 1431 ret = vasprintf(&str, fmt, ap); 1432 va_end(ap); 1433 1434 if (ret == -1) 1435 return (ret); 1436 1437 ret = server_bufferevent_print(clt, str); 1438 free(str); 1439 1440 return (ret); 1441} 1442 1443int 1444server_bufferevent_print(struct client *clt, const char *str) 1445{ 1446 if (clt->clt_bev == NULL) 1447 return (evbuffer_add(clt->clt_output, str, strlen(str))); 1448 return (bufferevent_write(clt->clt_bev, str, strlen(str))); 1449} 1450 1451int 1452server_bufferevent_write_buffer(struct client *clt, struct evbuffer *buf) 1453{ 1454 if (clt->clt_bev == NULL) 1455 return (evbuffer_add_buffer(clt->clt_output, buf)); 1456 return (bufferevent_write_buffer(clt->clt_bev, buf)); 1457} 1458 1459int 1460server_bufferevent_write_chunk(struct client *clt, 1461 struct evbuffer *buf, size_t size) 1462{ 1463 int ret; 1464 ret = server_bufferevent_write(clt, EVBUFFER_DATA(buf), size); 1465 if (ret != -1) 1466 evbuffer_drain(buf, size); 1467 return (ret); 1468} 1469 1470int 1471server_bufferevent_write(struct client *clt, void *data, size_t size) 1472{ 1473 if (clt->clt_bev == NULL) 1474 return (evbuffer_add(clt->clt_output, data, size)); 1475 return (bufferevent_write(clt->clt_bev, data, size)); 1476} 1477 1478int 1479server_client_cmp(struct client *a, struct client *b) 1480{ 1481 return ((int)a->clt_id - b->clt_id); 1482} 1483 1484SPLAY_GENERATE(client_tree, client, clt_nodes, server_client_cmp); 1485