-
Notifications
You must be signed in to change notification settings - Fork 867
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add location (found|not found) option to test for resource path exist…
…ence. Diff by Matthias Pressfreund <mpfr @ fn de>. Thanks.
- Loading branch information
denis
committed
Oct 29, 2020
1 parent
1938344
commit e96b74b
Showing
4 changed files
with
92 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
.\" $OpenBSD: httpd.conf.5,v 1.113 2020/09/05 11:49:38 tb Exp $ | ||
.\" $OpenBSD: httpd.conf.5,v 1.114 2020/10/29 12:30:52 denis Exp $ | ||
.\" | ||
.\" Copyright (c) 2014, 2015 Reyk Floeter <[email protected]> | ||
.\" | ||
|
@@ -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: September 5 2020 $ | ||
.Dd $Mdocdate: October 29 2020 $ | ||
.Dt HTTPD.CONF 5 | ||
.Os | ||
.Sh NAME | ||
|
@@ -399,11 +399,16 @@ of the host's domain should be considered HSTS hosts. | |
.It Ic listen on Ar address Oo Ic tls Oc Ic port Ar number | ||
Set the listen address and port. | ||
This statement can be specified multiple times. | ||
.It Ic location Ar path Brq ... | ||
.It Ic location Oo Oo Ic not Oc Ic found Oc Ar path Brq ... | ||
Specify server configuration rules for a specific location. | ||
The | ||
.Ar path | ||
argument will be matched against the request path with shell globbing rules. | ||
Optionally, it is also possible to match for | ||
.Ic found | ||
(i.e. accessible) or | ||
.Ic not found | ||
request paths only. | ||
In case of multiple location statements in the same context, the | ||
first matching location statement will be put into effect, while all | ||
later ones will be ignored. | ||
|
@@ -419,7 +424,7 @@ except | |
.Ic tcp | ||
and | ||
.Ic tls . | ||
.It Ic location match Ar path Brq ... | ||
.It Ic location Oo Oo Ic not Oc Ic found Oc Ic match Ar path Brq ... | ||
Like the | ||
.Ic location | ||
option, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
/* $OpenBSD: httpd.h,v 1.152 2020/08/29 07:53:48 florian Exp $ */ | ||
/* $OpenBSD: httpd.h,v 1.153 2020/10/29 12:30:52 denis Exp $ */ | ||
|
||
/* | ||
* Copyright (c) 2006 - 2015 Reyk Floeter <[email protected]> | ||
|
@@ -391,13 +391,16 @@ SPLAY_HEAD(client_tree, client); | |
#define SRVFLAG_DEFAULT_TYPE 0x00800000 | ||
#define SRVFLAG_PATH_REWRITE 0x01000000 | ||
#define SRVFLAG_NO_PATH_REWRITE 0x02000000 | ||
#define SRVFLAG_LOCATION_FOUND 0x40000000 | ||
#define SRVFLAG_LOCATION_NOT_FOUND 0x80000000 | ||
|
||
#define SRVFLAG_BITS \ | ||
"\10\01INDEX\02NO_INDEX\03AUTO_INDEX\04NO_AUTO_INDEX" \ | ||
"\05ROOT\06LOCATION\07FCGI\10NO_FCGI\11LOG\12NO_LOG" \ | ||
"\14SYSLOG\15NO_SYSLOG\16TLS\17ACCESS_LOG\20ERROR_LOG" \ | ||
"\21AUTH\22NO_AUTH\23BLOCK\24NO_BLOCK\25LOCATION_MATCH" \ | ||
"\26SERVER_MATCH\27SERVER_HSTS\30DEFAULT_TYPE\31PATH\32NO_PATH" | ||
"\26SERVER_MATCH\27SERVER_HSTS\30DEFAULT_TYPE\31PATH\32NO_PATH" \ | ||
"\37LOCATION_FOUND\40LOCATION_NOT_FOUND" | ||
|
||
#define TCPFLAG_NODELAY 0x01 | ||
#define TCPFLAG_NNODELAY 0x02 | ||
|
@@ -690,6 +693,7 @@ const char * | |
server_root_strip(const char *, int); | ||
struct server_config * | ||
server_getlocation(struct client *, const char *); | ||
int server_locationaccesstest(struct server_config *, const char *); | ||
const char * | ||
server_http_host(struct sockaddr_storage *, char *, size_t); | ||
char *server_http_parsehost(char *, char *, size_t, int *); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
/* $OpenBSD: parse.y,v 1.119 2020/10/26 19:31:22 denis Exp $ */ | ||
/* $OpenBSD: parse.y,v 1.120 2020/10/29 12:30:52 denis Exp $ */ | ||
|
||
/* | ||
* Copyright (c) 2020 Matthias Pressfreund <[email protected]> | ||
|
@@ -143,12 +143,12 @@ 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 PARAM FORWARDED | ||
%token CA CLIENT CRL OPTIONAL PARAM FORWARDED FOUND NOT | ||
%token <v.string> STRING | ||
%token <v.number> NUMBER | ||
%type <v.port> port | ||
%type <v.string> fcgiport | ||
%type <v.number> opttls optmatch | ||
%type <v.number> opttls optmatch optfound | ||
%type <v.tv> timeout | ||
%type <v.string> numberstring optstring | ||
%type <v.auth> authopts | ||
|
@@ -514,39 +514,39 @@ serveroptsl : LISTEN ON STRING opttls port { | |
| fastcgi | ||
| authenticate | ||
| filter | ||
| LOCATION optmatch STRING { | ||
| LOCATION optfound optmatch STRING { | ||
struct server *s; | ||
struct sockaddr_un *sun; | ||
|
||
if (srv->srv_conf.ss.ss_family == AF_UNSPEC) { | ||
yyerror("listen address not specified"); | ||
free($3); | ||
free($4); | ||
YYERROR; | ||
} | ||
|
||
if (parentsrv != NULL) { | ||
yyerror("location %s inside location", $3); | ||
free($3); | ||
yyerror("location %s inside location", $4); | ||
free($4); | ||
YYERROR; | ||
} | ||
|
||
if (!loadcfg) { | ||
free($3); | ||
free($4); | ||
YYACCEPT; | ||
} | ||
|
||
if ((s = calloc(1, sizeof (*s))) == NULL) | ||
fatal("out of memory"); | ||
|
||
if (strlcpy(s->srv_conf.location, $3, | ||
if (strlcpy(s->srv_conf.location, $4, | ||
sizeof(s->srv_conf.location)) >= | ||
sizeof(s->srv_conf.location)) { | ||
yyerror("server location truncated"); | ||
free($3); | ||
free($4); | ||
free(s); | ||
YYERROR; | ||
} | ||
free($3); | ||
free($4); | ||
|
||
if (strlcpy(s->srv_conf.name, srv->srv_conf.name, | ||
sizeof(s->srv_conf.name)) >= | ||
|
@@ -566,7 +566,18 @@ serveroptsl : LISTEN ON STRING opttls port { | |
/* A location entry uses the parent id */ | ||
s->srv_conf.parent_id = srv->srv_conf.id; | ||
s->srv_conf.flags = SRVFLAG_LOCATION; | ||
if ($2) | ||
if ($2 == 1) { | ||
s->srv_conf.flags &= | ||
~SRVFLAG_LOCATION_NOT_FOUND; | ||
s->srv_conf.flags |= | ||
SRVFLAG_LOCATION_FOUND; | ||
} else if ($2 == -1) { | ||
s->srv_conf.flags &= | ||
~SRVFLAG_LOCATION_FOUND; | ||
s->srv_conf.flags |= | ||
SRVFLAG_LOCATION_NOT_FOUND; | ||
} | ||
if ($3) | ||
s->srv_conf.flags |= SRVFLAG_LOCATION_MATCH; | ||
s->srv_s = -1; | ||
memcpy(&s->srv_conf.ss, &srv->srv_conf.ss, | ||
|
@@ -586,12 +597,18 @@ serveroptsl : LISTEN ON STRING opttls port { | |
SPLAY_INIT(&srv->srv_clients); | ||
} '{' optnl serveropts_l '}' { | ||
struct server *s = NULL; | ||
uint32_t f; | ||
|
||
f = SRVFLAG_LOCATION_FOUND | | ||
SRVFLAG_LOCATION_NOT_FOUND; | ||
|
||
TAILQ_FOREACH(s, conf->sc_servers, srv_entry) { | ||
/* Compare locations of same parent server */ | ||
if ((s->srv_conf.flags & SRVFLAG_LOCATION) && | ||
s->srv_conf.parent_id == | ||
srv_conf->parent_id && | ||
(s->srv_conf.flags & f) == | ||
(srv_conf->flags & f) && | ||
strcmp(s->srv_conf.location, | ||
srv_conf->location) == 0) | ||
break; | ||
|
@@ -629,6 +646,11 @@ serveroptsl : LISTEN ON STRING opttls port { | |
} | ||
; | ||
|
||
optfound : /* empty */ { $$ = 0; } | ||
| FOUND { $$ = 1; } | ||
| NOT FOUND { $$ = -1; } | ||
; | ||
|
||
hsts : HSTS '{' optnl hstsflags_l '}' | ||
| HSTS hstsflags | ||
| HSTS | ||
|
@@ -1377,6 +1399,7 @@ lookup(char *s) | |
{ "error", ERR }, | ||
{ "fastcgi", FCGI }, | ||
{ "forwarded", FORWARDED }, | ||
{ "found", FOUND }, | ||
{ "hsts", HSTS }, | ||
{ "include", INCLUDE }, | ||
{ "index", INDEX }, | ||
|
@@ -1392,6 +1415,7 @@ lookup(char *s) | |
{ "max-age", MAXAGE }, | ||
{ "no", NO }, | ||
{ "nodelay", NODELAY }, | ||
{ "not", NOT }, | ||
{ "ocsp", OCSP }, | ||
{ "on", ON }, | ||
{ "optional", OPTIONAL }, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
/* $OpenBSD: server_http.c,v 1.141 2020/09/12 07:34:17 yasuoka Exp $ */ | ||
/* $OpenBSD: server_http.c,v 1.142 2020/10/29 12:30:52 denis Exp $ */ | ||
|
||
/* | ||
* Copyright (c) 2020 Matthias Pressfreund <[email protected]> | ||
* Copyright (c) 2006 - 2018 Reyk Floeter <[email protected]> | ||
* | ||
* Permission to use, copy, modify, and distribute this software for any | ||
|
@@ -20,6 +21,7 @@ | |
#include <sys/queue.h> | ||
#include <sys/socket.h> | ||
#include <sys/tree.h> | ||
#include <sys/stat.h> | ||
|
||
#include <netinet/in.h> | ||
#include <arpa/inet.h> | ||
|
@@ -36,6 +38,7 @@ | |
#include <event.h> | ||
#include <ctype.h> | ||
#include <vis.h> | ||
#include <fcntl.h> | ||
|
||
#include "httpd.h" | ||
#include "http.h" | ||
|
@@ -1317,7 +1320,11 @@ server_response(struct httpd *httpd, struct client *clt) | |
goto fail; | ||
|
||
/* Now search for the location */ | ||
srv_conf = server_getlocation(clt, desc->http_path); | ||
if ((srv_conf = server_getlocation(clt, | ||
desc->http_path)) == NULL) { | ||
server_abort_http(clt, 500, desc->http_path); | ||
return (-1); | ||
} | ||
|
||
/* Optional rewrite */ | ||
if (srv_conf->flags & SRVFLAG_PATH_REWRITE) { | ||
|
@@ -1353,7 +1360,11 @@ server_response(struct httpd *httpd, struct client *clt) | |
goto fail; | ||
|
||
/* Now search for the updated location */ | ||
srv_conf = server_getlocation(clt, desc->http_path_alias); | ||
if ((srv_conf = server_getlocation(clt, | ||
desc->http_path_alias)) == NULL) { | ||
server_abort_http(clt, 500, desc->http_path_alias); | ||
return (-1); | ||
} | ||
} | ||
|
||
if (clt->clt_toread > 0 && (size_t)clt->clt_toread > | ||
|
@@ -1419,6 +1430,12 @@ server_getlocation(struct client *clt, const char *path) | |
path, FNM_CASEFOLD); | ||
} | ||
if (ret == 0 && errstr == NULL) { | ||
if ((ret = server_locationaccesstest(location, | ||
path)) == -1) | ||
return (NULL); | ||
|
||
if (ret) | ||
continue; | ||
/* Replace host configuration */ | ||
clt->clt_srv_conf = srv_conf = location; | ||
break; | ||
|
@@ -1429,6 +1446,27 @@ server_getlocation(struct client *clt, const char *path) | |
return (srv_conf); | ||
} | ||
|
||
int | ||
server_locationaccesstest(struct server_config *srv_conf, const char *path) | ||
{ | ||
int rootfd, ret; | ||
struct stat sb; | ||
|
||
if (((SRVFLAG_LOCATION_FOUND | SRVFLAG_LOCATION_NOT_FOUND) & | ||
srv_conf->flags) == 0) | ||
return (0); | ||
|
||
if ((rootfd = open(srv_conf->root, O_RDONLY)) == -1) | ||
return (-1); | ||
|
||
path = server_root_strip(path, srv_conf->strip) + 1; | ||
if ((ret = faccessat(rootfd, path, R_OK, 0)) != -1) | ||
ret = fstatat(rootfd, path, &sb, 0); | ||
close(rootfd); | ||
return ((ret == -1 && SRVFLAG_LOCATION_FOUND & srv_conf->flags) || | ||
(ret == 0 && SRVFLAG_LOCATION_NOT_FOUND & srv_conf->flags)); | ||
} | ||
|
||
int | ||
server_response_http(struct client *clt, unsigned int code, | ||
struct media_type *media, off_t size, time_t mtime) | ||
|