ignore after ? and make cgi+virtualhost work (sort of)
This commit is contained in:
parent
3510035711
commit
de7cd12f9f
29
main.c
29
main.c
|
@ -82,6 +82,9 @@ drop_privileges(const char *user, const char *path)
|
||||||
estrlcat(cgifullpath, cgibin, sizeof(cgifullpath));
|
estrlcat(cgifullpath, cgibin, sizeof(cgifullpath));
|
||||||
eunveil(cgifullpath, "rx");
|
eunveil(cgifullpath, "rx");
|
||||||
}
|
}
|
||||||
|
/* no more unveil later */
|
||||||
|
eunveil(NULL, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* prevent system calls other parsing queryfor fread file and
|
* prevent system calls other parsing queryfor fread file and
|
||||||
* write to stdio
|
* write to stdio
|
||||||
|
@ -292,6 +295,7 @@ main(int argc, char **argv)
|
||||||
char hostname [GEMINI_REQUEST_MAX] = {'\0'};
|
char hostname [GEMINI_REQUEST_MAX] = {'\0'};
|
||||||
char uri [PATH_MAX] = {'\0'};
|
char uri [PATH_MAX] = {'\0'};
|
||||||
char user [_SC_LOGIN_NAME_MAX] = "";
|
char user [_SC_LOGIN_NAME_MAX] = "";
|
||||||
|
char query[PATH_MAX] = {'\0'};
|
||||||
int virtualhost = 0;
|
int virtualhost = 0;
|
||||||
int option = 0;
|
int option = 0;
|
||||||
char *pos = NULL;
|
char *pos = NULL;
|
||||||
|
@ -383,6 +387,14 @@ main(int argc, char **argv)
|
||||||
/* copy hostname from request */
|
/* copy hostname from request */
|
||||||
estrlcpy(hostname, request, sizeof(hostname));
|
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 +
|
* if virtualhost feature is actived looking under the chroot_path +
|
||||||
* hostname directory gemini://foobar/hello will look for
|
* hostname directory gemini://foobar/hello will look for
|
||||||
|
@ -392,15 +404,16 @@ main(int argc, char **argv)
|
||||||
if (strlen(uri) == 0) {
|
if (strlen(uri) == 0) {
|
||||||
estrlcpy(uri, "/index.gmi", sizeof(uri));
|
estrlcpy(uri, "/index.gmi", sizeof(uri));
|
||||||
}
|
}
|
||||||
char new_uri[PATH_MAX] = {'\0'};
|
char tmp[PATH_MAX] = {'\0'};
|
||||||
estrlcpy(new_uri, hostname, sizeof(new_uri));
|
estrlcpy(tmp, hostname, sizeof(tmp));
|
||||||
estrlcat(new_uri, uri, sizeof(new_uri));
|
estrlcat(tmp, uri, sizeof(tmp));
|
||||||
estrlcpy(uri, new_uri, sizeof(uri));
|
estrlcpy(uri, tmp, sizeof(uri));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if uri is cgibin */
|
/* check if uri is cgibin */
|
||||||
if ((strlen(cgibin) > 0) &&
|
if ((strlen(cgibin) > 0) &&
|
||||||
(strncmp(uri, cgibin, strlen(cgibin)) == 0)) {
|
(strncmp(uri, cgibin, strlen(cgibin)) == 0)) {
|
||||||
|
|
||||||
char cgipath[PATH_MAX] = {'\0'};
|
char cgipath[PATH_MAX] = {'\0'};
|
||||||
estrlcpy(cgipath, chroot_dir, sizeof(cgipath));
|
estrlcpy(cgipath, chroot_dir, sizeof(cgipath));
|
||||||
estrlcat(cgipath, uri, sizeof(cgipath));
|
estrlcat(cgipath, uri, sizeof(cgipath));
|
||||||
|
@ -410,14 +423,6 @@ main(int argc, char **argv)
|
||||||
esetenv("SERVER_PROTOCOL", "GEMINI", 1);
|
esetenv("SERVER_PROTOCOL", "GEMINI", 1);
|
||||||
esetenv("SERVER_SOFTWARE", "vger/1", 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 */
|
/* look for an extension to find PATH_INFO */
|
||||||
pos = strrchr(cgipath, '.');
|
pos = strrchr(cgipath, '.');
|
||||||
if (pos != NULL) {
|
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)
|
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
|
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 !
|
# must fail only on OpenBSD !
|
||||||
# try to escape from unveil
|
# try to escape from unveil
|
||||||
if [ -f /bsd ]
|
if [ -f /bsd ]
|
||||||
|
|
|
@ -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
|
.It Op Fl c
|
||||||
Enable CGI support.
|
Enable CGI support.
|
||||||
.Ar cgi_path
|
.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
|
.Bd -literal -offset indent
|
||||||
vger -c /cgi-bin/hello.cgi
|
vger -c /cgi-bin/hello.cgi
|
||||||
.Ed
|
.Ed
|
||||||
|
@ -53,10 +56,7 @@ Note you can define a directory instead of a single file.
|
||||||
.Pp
|
.Pp
|
||||||
In this case,
|
In this case,
|
||||||
.Xr pledge 2
|
.Xr pledge 2
|
||||||
promises are set to "stdio proc exec"
|
promises and unveil permission are set to enable cgi execution.
|
||||||
and an additional
|
|
||||||
.Xr unveil 2
|
|
||||||
permission on the cgi script is set to "rx".
|
|
||||||
.Pp
|
.Pp
|
||||||
Be very careful on how you write your CGI, it can read outside the chroot.
|
Be very careful on how you write your CGI, it can read outside the chroot.
|
||||||
.It Op Fl m Ar mimetype
|
.It Op Fl m Ar mimetype
|
||||||
|
|
Loading…
Reference in New Issue