summaryrefslogtreecommitdiff
path: root/usr.sbin/httpd
diff options
context:
space:
mode:
authorPaul Irofti <pirofti@cvs.openbsd.org>2019-02-19 11:37:27 +0000
committerPaul Irofti <pirofti@cvs.openbsd.org>2019-02-19 11:37:27 +0000
commit91975801693a607dc9256aa5ab66192e86cd5926 (patch)
tree15494e593dbcb7c8df412ebcbf0e2b929442bf07 /usr.sbin/httpd
parent2b561a692db10877dfeb769d4e3330b13a82a028 (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.c101
-rw-r--r--usr.sbin/httpd/httpd.conf.515
-rw-r--r--usr.sbin/httpd/httpd.h17
-rw-r--r--usr.sbin/httpd/parse.y36
-rw-r--r--usr.sbin/httpd/server.c11
-rw-r--r--usr.sbin/httpd/server_fcgi.c10
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(&param, 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(&param, "REMOTE_ADDR", hbuf, clt) == -1) {
errstr = "failed to encode param";