ignore after ? and make cgi+virtualhost work (sort of)
This commit is contained in:
parent
3510035711
commit
de7cd12f9f
4 changed files with 39 additions and 17 deletions
29
main.c
29
main.c
|
@ -82,6 +82,9 @@ drop_privileges(const char *user, const char *path)
|
|||
estrlcat(cgifullpath, cgibin, sizeof(cgifullpath));
|
||||
eunveil(cgifullpath, "rx");
|
||||
}
|
||||
/* no more unveil later */
|
||||
eunveil(NULL, NULL);
|
||||
|
||||
/*
|
||||
* prevent system calls other parsing queryfor fread file and
|
||||
* write to stdio
|
||||
|
@ -292,6 +295,7 @@ main(int argc, char **argv)
|
|||
char hostname [GEMINI_REQUEST_MAX] = {'\0'};
|
||||
char uri [PATH_MAX] = {'\0'};
|
||||
char user [_SC_LOGIN_NAME_MAX] = "";
|
||||
char query[PATH_MAX] = {'\0'};
|
||||
int virtualhost = 0;
|
||||
int option = 0;
|
||||
char *pos = NULL;
|
||||
|
@ -383,6 +387,14 @@ main(int argc, char **argv)
|
|||
/* copy hostname from request */
|
||||
estrlcpy(hostname, request, sizeof(hostname));
|
||||
|
||||
/* look for "?" if any to set query for cgi, or remove it*/
|
||||
pos = strchr(uri, '?');
|
||||
if (pos != NULL) {
|
||||
estrlcpy(query, pos+1, sizeof(query));
|
||||
esetenv("QUERY_STRING", query, 1);
|
||||
pos[0] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* if virtualhost feature is actived looking under the chroot_path +
|
||||
* hostname directory gemini://foobar/hello will look for
|
||||
|
@ -392,15 +404,16 @@ main(int argc, char **argv)
|
|||
if (strlen(uri) == 0) {
|
||||
estrlcpy(uri, "/index.gmi", sizeof(uri));
|
||||
}
|
||||
char new_uri[PATH_MAX] = {'\0'};
|
||||
estrlcpy(new_uri, hostname, sizeof(new_uri));
|
||||
estrlcat(new_uri, uri, sizeof(new_uri));
|
||||
estrlcpy(uri, new_uri, sizeof(uri));
|
||||
char tmp[PATH_MAX] = {'\0'};
|
||||
estrlcpy(tmp, hostname, sizeof(tmp));
|
||||
estrlcat(tmp, uri, sizeof(tmp));
|
||||
estrlcpy(uri, tmp, sizeof(uri));
|
||||
}
|
||||
|
||||
/* check if uri is cgibin */
|
||||
if ((strlen(cgibin) > 0) &&
|
||||
(strncmp(uri, cgibin, strlen(cgibin)) == 0)) {
|
||||
|
||||
char cgipath[PATH_MAX] = {'\0'};
|
||||
estrlcpy(cgipath, chroot_dir, sizeof(cgipath));
|
||||
estrlcat(cgipath, uri, sizeof(cgipath));
|
||||
|
@ -410,14 +423,6 @@ main(int argc, char **argv)
|
|||
esetenv("SERVER_PROTOCOL", "GEMINI", 1);
|
||||
esetenv("SERVER_SOFTWARE", "vger/1", 1);
|
||||
|
||||
/* look for "?" to set query */
|
||||
pos = strchr(cgipath, '?');
|
||||
if (pos != NULL) {
|
||||
char query[PATH_MAX] = {'\0'};
|
||||
estrlcpy(query, pos+1, sizeof(query));
|
||||
esetenv("QUERY_STRING", query, 1);
|
||||
pos[0] = '\0';
|
||||
}
|
||||
/* look for an extension to find PATH_INFO */
|
||||
pos = strrchr(cgipath, '.');
|
||||
if (pos != NULL) {
|
||||
|
|
|
@ -86,6 +86,14 @@ if ! [ $OUT = "fa065a67d1f7c973501d4a9e3ca2ea57" ] ; then echo "error" ; exit 1
|
|||
OUT=$(printf "gemini://host.name/cgi-bin/nope\r\n" | ../vger -d var/gemini/ -c /cgi-bin | tee /dev/stderr | $MD5)
|
||||
if ! [ $OUT = "2c88347cfac44450035283a8508a29cb" ] ; then echo "error" ; exit 1 ; fi
|
||||
|
||||
# remove ?.* if any
|
||||
OUT=$(printf "gemini://host.name/main.gmi?anything-here\r\n" | ../vger -d var/gemini/ | tee /dev/stderr | $MD5)
|
||||
if ! [ $OUT = "c7e352d6aae4ee7e7604548f7874fb9d" ] ; then echo "error" ; exit 1 ; fi
|
||||
|
||||
# virtualhost + cgi
|
||||
OUT=$(printf "gemini://perso.pw/cgi-bin/test.cgi\r\n" | ../vger -v -d var/gemini/ -c perso.pw/cgi-bin | tee /dev/stderr | $MD5)
|
||||
if ! [ $OUT = "666e48200f90018b5e96c2cf974882dc" ] ; then echo "error" ; exit 1 ; fi
|
||||
|
||||
# must fail only on OpenBSD !
|
||||
# try to escape from unveil
|
||||
if [ -f /bsd ]
|
||||
|
|
9
tests/var/gemini/perso.pw/cgi-bin/test.cgi
Executable file
9
tests/var/gemini/perso.pw/cgi-bin/test.cgi
Executable file
|
@ -0,0 +1,9 @@
|
|||
#!/bin/sh
|
||||
|
||||
printf "%s %s: cgi_test\r\n" "20 text/plain"
|
||||
|
||||
echo "env vars:"
|
||||
echo $GATEWAY_INTERFACE
|
||||
echo $SERVER_SOFTWARE
|
||||
echo $PATH_INFO
|
||||
echo $QUERY_STRING
|
10
vger.8
10
vger.8
|
@ -44,7 +44,10 @@ will read the file /var/gemini/hostname.example/file.gmi
|
|||
.It Op Fl c
|
||||
Enable CGI support.
|
||||
.Ar cgi_path
|
||||
will be executed as a cgi script. This path is relative to the served capsule. As example, for a request gemini://hostname.example/cgi-bin/hello.cgi, one must set:
|
||||
will be executed as a cgi script. This path is relative to the directory set with
|
||||
.Fl d
|
||||
flag. If using virtualhost, you must insert the virtualhost directory in the cgi path.
|
||||
As example, for a request gemini://hostname.example/cgi-bin/hello.cgi, one must set:
|
||||
.Bd -literal -offset indent
|
||||
vger -c /cgi-bin/hello.cgi
|
||||
.Ed
|
||||
|
@ -53,10 +56,7 @@ Note you can define a directory instead of a single file.
|
|||
.Pp
|
||||
In this case,
|
||||
.Xr pledge 2
|
||||
promises are set to "stdio proc exec"
|
||||
and an additional
|
||||
.Xr unveil 2
|
||||
permission on the cgi script is set to "rx".
|
||||
promises and unveil permission are set to enable cgi execution.
|
||||
.Pp
|
||||
Be very careful on how you write your CGI, it can read outside the chroot.
|
||||
.It Op Fl m Ar mimetype
|
||||
|
|
Loading…
Reference in a new issue