diff options
author | Paul Irofti <pirofti@cvs.openbsd.org> | 2019-02-19 11:37:27 +0000 |
---|---|---|
committer | Paul Irofti <pirofti@cvs.openbsd.org> | 2019-02-19 11:37:27 +0000 |
commit | 91975801693a607dc9256aa5ab66192e86cd5926 (patch) | |
tree | 15494e593dbcb7c8df412ebcbf0e2b929442bf07 /usr.sbin/httpd | |
parent | 2b561a692db10877dfeb769d4e3330b13a82a028 (diff) |
httpd(8): add support for setting custom FastCGI parameters.
This commit extends the existing grammar by adding the param option
to the fastcgi directive: fastcgi param name value.
Example usage:
fastcgi param VAR1 hello
fastcgi param VAR2 world
With help and OK florian@
Rogue manpage bits, feel free to modify them.
Diffstat (limited to 'usr.sbin/httpd')
-rw-r--r-- | usr.sbin/httpd/config.c | 101 | ||||
-rw-r--r-- | usr.sbin/httpd/httpd.conf.5 | 15 | ||||
-rw-r--r-- | usr.sbin/httpd/httpd.h | 17 | ||||
-rw-r--r-- | usr.sbin/httpd/parse.y | 36 | ||||
-rw-r--r-- | usr.sbin/httpd/server.c | 11 | ||||
-rw-r--r-- | usr.sbin/httpd/server_fcgi.c | 10 |
6 files changed, 180 insertions, 10 deletions
diff --git a/usr.sbin/httpd/config.c b/usr.sbin/httpd/config.c index 0b8c251bc3e..cc6b875ab11 100644 --- a/usr.sbin/httpd/config.c +++ b/usr.sbin/httpd/config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: config.c,v 1.55 2018/06/20 16:43:05 reyk Exp $ */ +/* $OpenBSD: config.c,v 1.56 2019/02/19 11:37:26 pirofti Exp $ */ /* * Copyright (c) 2011 - 2015 Reyk Floeter <reyk@openbsd.org> @@ -231,6 +231,9 @@ config_setserver(struct httpd *env, struct server *srv) __func__, srv->srv_conf.name); return (-1); } + + /* Configure FCGI parmeters if necessary. */ + config_setserver_fcgiparams(env, srv); } } @@ -295,6 +298,102 @@ config_settls(struct httpd *env, struct server *srv, enum tls_config_type type, } int +config_getserver_fcgiparams(struct httpd *env, struct imsg *imsg) +{ + struct server *srv; + struct server_config *srv_conf, *iconf; + struct fastcgi_param *fp; + uint32_t id; + size_t c, nc, len; + uint8_t *p = imsg->data; + + len = sizeof(nc) + sizeof(id); + if (IMSG_DATA_SIZE(imsg) < len) { + log_debug("%s: invalid message length", __func__); + return (-1); + } + + memcpy(&nc, p, sizeof(nc)); /* number of params */ + p += sizeof(nc); + + memcpy(&id, p, sizeof(id)); /* server conf id */ + srv_conf = serverconfig_byid(id); + p += sizeof(id); + + len += nc*sizeof(*fp); + if (IMSG_DATA_SIZE(imsg) < len) { + log_debug("%s: invalid message length", __func__); + return (-1); + } + + /* Find associated server config */ + TAILQ_FOREACH(srv, env->sc_servers, srv_entry) { + if (srv->srv_conf.id == id) { + srv_conf = &srv->srv_conf; + break; + } + TAILQ_FOREACH(iconf, &srv->srv_hosts, entry) { + if (iconf->id == id) { + srv_conf = iconf; + break; + } + } + } + + /* Fetch FCGI parameters */ + for (c = 0; c < nc; c++) { + if ((fp = calloc(1, sizeof(*fp))) == NULL) + fatalx("fcgiparams out of memory"); + memcpy(fp, p, sizeof(*fp)); + TAILQ_INSERT_HEAD(&srv_conf->fcgiparams, fp, entry); + + p += sizeof(*fp); + } + + return (0); +} + +int +config_setserver_fcgiparams(struct httpd *env, struct server *srv) +{ + struct privsep *ps = env->sc_ps; + struct server_config *srv_conf = &srv->srv_conf; + struct fastcgi_param *fp; + struct iovec *iov; + size_t c = 0, nc = 0; + + DPRINTF("%s: sending fcgiparam for \"%s[%u]\" to %s fd %d", __func__, + srv_conf->name, srv_conf->id, ps->ps_title[PROC_SERVER], + srv->srv_s); + + if (TAILQ_EMPTY(&srv_conf->fcgiparams)) /* nothing to do */ + return (0); + + TAILQ_FOREACH(fp, &srv_conf->fcgiparams, entry) { + nc++; + } + if ((iov = calloc(nc + 2, sizeof(*iov))) == NULL) + return (-1); + + iov[c].iov_base = &nc; /* number of params */ + iov[c++].iov_len = sizeof(nc); + iov[c].iov_base = &srv_conf->id; /* server config id */ + iov[c++].iov_len = sizeof(srv_conf->id); + + TAILQ_FOREACH(fp, &srv_conf->fcgiparams, entry) { /* push FCGI params */ + iov[c].iov_base = fp; + iov[c++].iov_len = sizeof(*fp); + } + if (proc_composev(ps, PROC_SERVER, IMSG_CFG_FCGI, iov, c) != 0) { + log_warn("%s: failed to compose IMSG_CFG_FCGI imsg for " + "`%s'", __func__, srv_conf->name); + return (-1); + } + + return (0); +} + +int config_setserver_tls(struct httpd *env, struct server *srv) { struct server_config *srv_conf = &srv->srv_conf; diff --git a/usr.sbin/httpd/httpd.conf.5 b/usr.sbin/httpd/httpd.conf.5 index d75c47269e0..608701e59c4 100644 --- a/usr.sbin/httpd/httpd.conf.5 +++ b/usr.sbin/httpd/httpd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: httpd.conf.5,v 1.102 2019/02/08 11:46:07 florian Exp $ +.\" $OpenBSD: httpd.conf.5,v 1.103 2019/02/19 11:37:26 pirofti Exp $ .\" .\" Copyright (c) 2014, 2015 Reyk Floeter <reyk@openbsd.org> .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: February 8 2019 $ +.Dd $Mdocdate: February 19 2019 $ .Dt HTTPD.CONF 5 .Os .Sh NAME @@ -274,8 +274,11 @@ Disable the directory index. .Xr httpd 8 will neither display nor generate a directory index. .El -.It Oo Ic no Oc Ic fastcgi Op Ic socket Ar socket +.It Oo Ic no Oc Ic fastcgi Oo Ar option Oc Enable FastCGI instead of serving files. +Valid options are: +.Bl -tag -width Ds +.It Ic socket Ar socket .Nm httpd passes HTTP requests to a FastCGI handler listening on the socket .Ar socket . @@ -293,8 +296,12 @@ Alternatively if the FastCGI handler is listening on a TCP socket, .Ar socket starts with a colon followed by the TCP port number. +.It Ic param Ar variable value +Sets a variable that will be sent to the FastCGI server. +Each statement defines one variable. +.El .Pp -The FastCGI handler will be given the following variables: +The FastCGI handler will be given the following variables by default: .Pp .Bl -tag -width GATEWAY_INTERFACE -offset indent -compact .It Ic DOCUMENT_ROOT diff --git a/usr.sbin/httpd/httpd.h b/usr.sbin/httpd/httpd.h index 3d150a53ac9..52d41b3d158 100644 --- a/usr.sbin/httpd/httpd.h +++ b/usr.sbin/httpd/httpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: httpd.h,v 1.142 2018/10/11 09:52:22 benno Exp $ */ +/* $OpenBSD: httpd.h,v 1.143 2019/02/19 11:37:26 pirofti Exp $ */ /* * Copyright (c) 2006 - 2015 Reyk Floeter <reyk@openbsd.org> @@ -64,6 +64,8 @@ #define HTTPD_TLS_CIPHERS "compat" #define HTTPD_TLS_DHE_PARAMS "none" #define HTTPD_TLS_ECDHE_CURVES "default" +#define HTTPD_FCGI_NAME_MAX 511 +#define HTTPD_FCGI_VAL_MAX 511 #define FD_RESERVE 5 #define SERVER_MAX_CLIENTS 1024 @@ -225,6 +227,7 @@ enum imsg_type { IMSG_CFG_TLS, IMSG_CFG_MEDIA, IMSG_CFG_AUTH, + IMSG_CFG_FCGI, IMSG_CFG_DONE, IMSG_LOG_ACCESS, IMSG_LOG_ERROR, @@ -467,6 +470,14 @@ struct server_tls_ticket { unsigned char tt_key[TLS_TICKET_KEY_SIZE]; }; +struct fastcgi_param { + char name[HTTPD_FCGI_NAME_MAX]; + char value[HTTPD_FCGI_VAL_MAX]; + + TAILQ_ENTRY(fastcgi_param) entry; +}; +TAILQ_HEAD(server_fcgiparams, fastcgi_param); + struct server_config { uint32_t id; uint32_t parent_id; @@ -534,6 +545,8 @@ struct server_config { int hsts_max_age; uint8_t hsts_flags; + struct server_fcgiparams fcgiparams; + TAILQ_ENTRY(server_config) entry; }; TAILQ_HEAD(serverhosts, server_config); @@ -818,8 +831,10 @@ int config_getreset(struct httpd *, struct imsg *); int config_getcfg(struct httpd *, struct imsg *); int config_setserver(struct httpd *, struct server *); int config_setserver_tls(struct httpd *, struct server *); +int config_setserver_fcgiparams(struct httpd *, struct server *); int config_getserver(struct httpd *, struct imsg *); int config_getserver_tls(struct httpd *, struct imsg *); +int config_getserver_fcgiparams(struct httpd *, struct imsg *); int config_setmedia(struct httpd *, struct media_type *); int config_getmedia(struct httpd *, struct imsg *); int config_setauth(struct httpd *, struct auth *); diff --git a/usr.sbin/httpd/parse.y b/usr.sbin/httpd/parse.y index a3662debfcc..c6cb1ac32f7 100644 --- a/usr.sbin/httpd/parse.y +++ b/usr.sbin/httpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.109 2019/02/13 22:57:08 deraadt Exp $ */ +/* $OpenBSD: parse.y,v 1.110 2019/02/19 11:37:26 pirofti Exp $ */ /* * Copyright (c) 2007 - 2015 Reyk Floeter <reyk@openbsd.org> @@ -140,7 +140,7 @@ typedef struct { %token PROTOCOLS REQUESTS ROOT SACK SERVER SOCKET STRIP STYLE SYSLOG TCP TICKET %token TIMEOUT TLS TYPE TYPES HSTS MAXAGE SUBDOMAINS DEFAULT PRELOAD REQUEST %token ERROR INCLUDE AUTHENTICATE WITH BLOCK DROP RETURN PASS REWRITE -%token CA CLIENT CRL OPTIONAL +%token CA CLIENT CRL OPTIONAL PARAM %token <v.string> STRING %token <v.number> NUMBER %type <v.port> port @@ -290,6 +290,7 @@ server : SERVER optmatch STRING { SPLAY_INIT(&srv->srv_clients); TAILQ_INIT(&srv->srv_hosts); + TAILQ_INIT(&srv_conf->fcgiparams); TAILQ_INSERT_TAIL(&srv->srv_hosts, srv_conf, entry); } '{' optnl serveropts_l '}' { @@ -658,6 +659,36 @@ fcgiflags : SOCKET STRING { free($2); srv_conf->flags |= SRVFLAG_SOCKET; } + | PARAM STRING STRING { + struct fastcgi_param *param; + + if ((param = calloc(1, sizeof(*param))) == NULL) + fatal("out of memory"); + + if (strlcpy(param->name, $2, sizeof(param->name)) >= + sizeof(param->name)) { + yyerror("fastcgi_param name truncated"); + free($2); + free($3); + free(param); + YYERROR; + } + if (strlcpy(param->value, $3, sizeof(param->value)) >= + sizeof(param->value)) { + yyerror("fastcgi_param value truncated"); + free($2); + free($3); + free(param); + YYERROR; + } + free($2); + free($3); + + DPRINTF("[%s,%s,%d]: adding param \"%s\" value \"%s\"", + srv_conf->location, srv_conf->name, srv_conf->id, + param->name, param->value); + TAILQ_INSERT_HEAD(&srv_conf->fcgiparams, param, entry); + } ; connection : CONNECTION '{' optnl conflags_l '}' @@ -1282,6 +1313,7 @@ lookup(char *s) { "ocsp", OCSP }, { "on", ON }, { "optional", OPTIONAL }, + { "param", PARAM }, { "pass", PASS }, { "port", PORT }, { "prefork", PREFORK }, diff --git a/usr.sbin/httpd/server.c b/usr.sbin/httpd/server.c index 82d2c44c8f0..daedde16551 100644 --- a/usr.sbin/httpd/server.c +++ b/usr.sbin/httpd/server.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server.c,v 1.117 2019/01/08 18:35:27 florian Exp $ */ +/* $OpenBSD: server.c,v 1.118 2019/02/19 11:37:26 pirofti Exp $ */ /* * Copyright (c) 2006 - 2015 Reyk Floeter <reyk@openbsd.org> @@ -491,6 +491,8 @@ server_purge(struct server *srv) void serverconfig_free(struct server_config *srv_conf) { + struct fastcgi_param *param, *tparam; + free(srv_conf->return_uri); free(srv_conf->tls_ca_file); free(srv_conf->tls_ca); @@ -502,6 +504,9 @@ serverconfig_free(struct server_config *srv_conf) free(srv_conf->tls_ocsp_staple); freezero(srv_conf->tls_cert, srv_conf->tls_cert_len); freezero(srv_conf->tls_key, srv_conf->tls_key_len); + + TAILQ_FOREACH_SAFE(param, &srv_conf->fcgiparams, entry, tparam) + free(param); } void @@ -519,6 +524,7 @@ serverconfig_reset(struct server_config *srv_conf) srv_conf->tls_key_file = NULL; srv_conf->tls_ocsp_staple = NULL; srv_conf->tls_ocsp_staple_file = NULL; + TAILQ_INIT(&srv_conf->fcgiparams); } struct server * @@ -1370,6 +1376,9 @@ server_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg) case IMSG_CFG_TLS: config_getserver_tls(httpd_env, imsg); break; + case IMSG_CFG_FCGI: + config_getserver_fcgiparams(httpd_env, imsg); + break; case IMSG_CFG_DONE: config_getcfg(httpd_env, imsg); break; diff --git a/usr.sbin/httpd/server_fcgi.c b/usr.sbin/httpd/server_fcgi.c index e0a23fc627a..bdd150fa932 100644 --- a/usr.sbin/httpd/server_fcgi.c +++ b/usr.sbin/httpd/server_fcgi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server_fcgi.c,v 1.77 2018/10/15 08:16:17 bentley Exp $ */ +/* $OpenBSD: server_fcgi.c,v 1.78 2019/02/19 11:37:26 pirofti Exp $ */ /* * Copyright (c) 2014 Florian Obser <florian@openbsd.org> @@ -92,6 +92,7 @@ server_fcgi(struct httpd *env, struct client *clt) struct http_descriptor *desc = clt->clt_descreq; struct fcgi_record_header *h; struct fcgi_begin_request_body *begin; + struct fastcgi_param *fcgiparam; char hbuf[HOST_NAME_MAX+1]; size_t scriptlen; int pathlen; @@ -295,6 +296,13 @@ server_fcgi(struct httpd *env, struct client *clt) } } + TAILQ_FOREACH(fcgiparam, &srv_conf->fcgiparams, entry) { + if (fcgi_add_param(¶m, fcgiparam->name, fcgiparam->value, clt) == -1) { + errstr = "failed to encode param"; + goto fail; + } + } + (void)print_host(&clt->clt_ss, hbuf, sizeof(hbuf)); if (fcgi_add_param(¶m, "REMOTE_ADDR", hbuf, clt) == -1) { errstr = "failed to encode param"; |