diff options
author | 2020-08-24 15:49:10 +0000 | |
---|---|---|
committer | 2020-08-24 15:49:10 +0000 | |
commit | 9ea72f9543d63ae921141b99692fee4e15e41d5a (patch) | |
tree | a2d13ee7e3074274d8e0006def307b4d829086ce | |
parent | Rehash main ruleset after rule expiration (diff) | |
download | wireguard-openbsd-9ea72f9543d63ae921141b99692fee4e15e41d5a.tar.xz wireguard-openbsd-9ea72f9543d63ae921141b99692fee4e15e41d5a.zip |
Add support for non-localhost fastcgi sockets.
Lots of review time kn@
Lots of review time, tweaks, and ok florian@
-rw-r--r-- | usr.sbin/httpd/config.c | 15 | ||||
-rw-r--r-- | usr.sbin/httpd/httpd.conf.5 | 16 | ||||
-rw-r--r-- | usr.sbin/httpd/httpd.h | 6 | ||||
-rw-r--r-- | usr.sbin/httpd/parse.y | 75 | ||||
-rw-r--r-- | usr.sbin/httpd/server_fcgi.c | 45 |
5 files changed, 103 insertions, 54 deletions
diff --git a/usr.sbin/httpd/config.c b/usr.sbin/httpd/config.c index 9502647d44a..4136a2b6270 100644 --- a/usr.sbin/httpd/config.c +++ b/usr.sbin/httpd/config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: config.c,v 1.58 2020/08/03 10:55:58 benno Exp $ */ +/* $OpenBSD: config.c,v 1.59 2020/08/24 15:49:10 tracey Exp $ */ /* * Copyright (c) 2011 - 2015 Reyk Floeter <reyk@openbsd.org> @@ -18,6 +18,8 @@ #include <sys/types.h> #include <sys/queue.h> +#include <sys/socket.h> +#include <sys/un.h> #include <sys/tree.h> #include <sys/time.h> #include <sys/uio.h> @@ -496,9 +498,16 @@ config_getserver_config(struct httpd *env, struct server *srv, f = SRVFLAG_SOCKET|SRVFLAG_FCGI; if ((srv_conf->flags & f) == SRVFLAG_FCGI) { + struct sockaddr_un *sun; + sun = (struct sockaddr_un *) &srv_conf->fastcgi_ss; + + memset(sun, 0, sizeof(*sun)); + sun->sun_family = AF_UNIX; + (void)strlcpy(sun->sun_path, HTTPD_FCGI_SOCKET, + sizeof(sun->sun_path)); + srv_conf->fastcgi_ss.ss_len = + sizeof(struct sockaddr_un); srv_conf->flags |= f; - (void)strlcpy(srv_conf->socket, HTTPD_FCGI_SOCKET, - sizeof(srv_conf->socket)); } f = SRVFLAG_ROOT; diff --git a/usr.sbin/httpd/httpd.conf.5 b/usr.sbin/httpd/httpd.conf.5 index 02b4442693b..6ef70becdd7 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.111 2020/05/16 16:58:11 jmc Exp $ +.\" $OpenBSD: httpd.conf.5,v 1.112 2020/08/24 15:49:10 tracey 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: May 16 2020 $ +.Dd $Mdocdate: August 24 2020 $ .Dt HTTPD.CONF 5 .Os .Sh NAME @@ -284,12 +284,13 @@ will neither display nor generate a directory index. Enable FastCGI instead of serving files. Valid options are: .Bl -tag -width Ds -.It Ic socket Ar socket +.It Ic socket Oo Cm tcp Oc Ar socket Oo Ar port Oc .Nm httpd passes HTTP requests to a FastCGI handler listening on the socket .Ar socket . -The socket can either be a UNIX domain socket or a TCP socket listening -on localhost (127.0.0.1). +The +.Ar socket +can either be a UNIX domain socket or a TCP socket. If the FastCGI handler is listening on a UNIX domain socket, .Ar socket is a local path name within the @@ -301,7 +302,10 @@ and defaults to Alternatively if the FastCGI handler is listening on a TCP socket, .Ar socket -starts with a colon followed by the TCP port number. +is a hostname or an IP address. +If the +.Ar port +is not specified, it defaults to port 9000. .It Ic strip Ar number Strip .Ar number diff --git a/usr.sbin/httpd/httpd.h b/usr.sbin/httpd/httpd.h index 12183f8cef0..8d17b67319e 100644 --- a/usr.sbin/httpd/httpd.h +++ b/usr.sbin/httpd/httpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: httpd.h,v 1.149 2020/08/03 11:05:24 benno Exp $ */ +/* $OpenBSD: httpd.h,v 1.150 2020/08/24 15:49:10 tracey Exp $ */ /* * Copyright (c) 2006 - 2015 Reyk Floeter <reyk@openbsd.org> @@ -96,6 +96,7 @@ #define CONFIG_ALL 0xff #define FCGI_CONTENT_SIZE 65535 +#define FCGI_DEFAULT_PORT "9000" #define PROC_PARENT_SOCK_FILENO 3 #define PROC_MAX_INSTANCES 32 @@ -475,11 +476,12 @@ struct server_config { char root[PATH_MAX]; char path[PATH_MAX]; char index[PATH_MAX]; - char socket[PATH_MAX]; char accesslog[PATH_MAX]; char errorlog[PATH_MAX]; struct media_type default_type; + struct sockaddr_storage fastcgi_ss; + in_port_t port; struct sockaddr_storage ss; int prefixlen; diff --git a/usr.sbin/httpd/parse.y b/usr.sbin/httpd/parse.y index bc531b5eddb..f9a73fe1041 100644 --- a/usr.sbin/httpd/parse.y +++ b/usr.sbin/httpd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.114 2020/02/09 09:44:04 florian Exp $ */ +/* $OpenBSD: parse.y,v 1.115 2020/08/24 15:49:11 tracey Exp $ */ /* * Copyright (c) 2007 - 2015 Reyk Floeter <reyk@openbsd.org> @@ -27,6 +27,7 @@ %{ #include <sys/types.h> #include <sys/socket.h> +#include <sys/un.h> #include <sys/stat.h> #include <sys/queue.h> #include <sys/tree.h> @@ -116,6 +117,7 @@ struct server *server_inherit(struct server *, struct server_config *, int listen_on(const char *, int, struct portrange *); int getservice(char *); int is_if_in_group(const char *, const char *); +int get_fastcgi_dest(struct server_config *, const char *, char *); typedef struct { union { @@ -144,6 +146,7 @@ typedef struct { %token <v.string> STRING %token <v.number> NUMBER %type <v.port> port +%type <v.string> fcgiport %type <v.number> opttls optmatch %type <v.tv> timeout %type <v.string> numberstring optstring @@ -648,17 +651,41 @@ fcgiflags_l : fcgiflags optcommanl fcgiflags_l | fcgiflags optnl ; -fcgiflags : SOCKET STRING { - if (strlcpy(srv_conf->socket, $2, - sizeof(srv_conf->socket)) >= - sizeof(srv_conf->socket)) { - yyerror("fastcgi socket too long"); +fcgiflags : SOCKET STRING { + struct sockaddr_un *sun; + sun = (struct sockaddr_un *)&srv_conf->fastcgi_ss; + memset(sun, 0, sizeof(*sun)); + sun->sun_family = AF_UNIX; + if (strlcpy(sun->sun_path, $2, sizeof(sun->sun_path)) + >= sizeof(sun->sun_path)) { + yyerror("socket path too long"); free($2); YYERROR; } + srv_conf->fastcgi_ss.ss_len = + sizeof(struct sockaddr_un); free($2); srv_conf->flags |= SRVFLAG_SOCKET; } + | SOCKET TCP STRING { + if (get_fastcgi_dest(srv_conf, $3, FCGI_DEFAULT_PORT) + == -1) { + free($3); + YYERROR; + } + free($3); + srv_conf->flags |= SRVFLAG_SOCKET; + } + | SOCKET TCP STRING fcgiport { + if (get_fastcgi_dest(srv_conf, $3, $4) == -1) { + free($3); + free($4); + YYERROR; + } + free($3); + free($4); + srv_conf->flags |= SRVFLAG_SOCKET; + } | PARAM STRING STRING { struct fastcgi_param *param; @@ -1086,6 +1113,19 @@ optstring : /* empty */ { $$ = NULL; } | STRING { $$ = $1; } ; +fcgiport : NUMBER { + if ($1 <= 0 || $1 > (int)USHRT_MAX) { + yyerror("invalid port: %lld", $1); + YYERROR; + } + if (asprintf(&$$, "%lld", $1) == -1) { + yyerror("out of memory"); + YYERROR; + } + } + | STRING { $$ = $1; } + ; + tcpip : TCP '{' optnl tcpflags_l '}' | TCP tcpflags ; @@ -2379,3 +2419,26 @@ end: close(s); return (ret); } + +int +get_fastcgi_dest(struct server_config *xsrv_conf, const char *node, char *port) +{ + struct addrinfo hints, *res; + int s; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + if ((s = getaddrinfo(node, port, &hints, &res)) != 0) { + yyerror("getaddrinfo: %s\n", gai_strerror(s)); + return -1; + } + + memset(&(xsrv_conf)->fastcgi_ss, 0, sizeof(xsrv_conf->fastcgi_ss)); + memcpy(&(xsrv_conf)->fastcgi_ss, res->ai_addr, res->ai_addrlen); + + freeaddrinfo(res); + + return (0); +} diff --git a/usr.sbin/httpd/server_fcgi.c b/usr.sbin/httpd/server_fcgi.c index 243fc1236eb..ac841c10e05 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.82 2020/08/03 10:58:38 benno Exp $ */ +/* $OpenBSD: server_fcgi.c,v 1.83 2020/08/24 15:49:11 tracey Exp $ */ /* * Copyright (c) 2014 Florian Obser <florian@openbsd.org> @@ -97,44 +97,15 @@ server_fcgi(struct httpd *env, struct client *clt) size_t scriptlen; int pathlen; int fd = -1, ret; - const char *stripped, *p, *alias, *errstr = NULL; + const char *stripped, *alias, *errstr = NULL; char *query_alias, *str, *script = NULL; - if (srv_conf->socket[0] == ':') { - struct sockaddr_storage ss; - in_port_t port; - - p = srv_conf->socket + 1; - - port = strtonum(p, 0, 0xffff, &errstr); - if (errstr != NULL) { - log_warn("%s: strtonum %s, %s", __func__, p, errstr); - goto fail; - } - memset(&ss, 0, sizeof(ss)); - ss.ss_family = AF_INET; - ((struct sockaddr_in *) - &ss)->sin_addr.s_addr = htonl(INADDR_LOOPBACK); - port = htons(port); - - if ((fd = server_socket_connect(&ss, port, srv_conf)) == -1) - goto fail; - } else { - struct sockaddr_un sun; - - if ((fd = socket(AF_UNIX, - SOCK_STREAM | SOCK_NONBLOCK, 0)) == -1) - goto fail; - - memset(&sun, 0, sizeof(sun)); - sun.sun_family = AF_UNIX; - if (strlcpy(sun.sun_path, srv_conf->socket, - sizeof(sun.sun_path)) >= sizeof(sun.sun_path)) { - errstr = "socket path to long"; - goto fail; - } - - if (connect(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) + if ((fd = socket(srv_conf->fastcgi_ss.ss_family, + SOCK_STREAM | SOCK_NONBLOCK, 0)) == -1) + goto fail; + if ((connect(fd, (struct sockaddr *) &srv_conf->fastcgi_ss, + srv_conf->fastcgi_ss.ss_len)) == -1) { + if (errno != EINPROGRESS) goto fail; } |