restore parent link in autoindex and add comments
This commit is contained in:
parent
189803ab52
commit
55042768e5
4 changed files with 42 additions and 15 deletions
5
Makefile
5
Makefile
|
@ -10,7 +10,10 @@ CFLAGS += -pedantic -Wall -Wextra -Wmissing-prototypes \
|
||||||
all: vger
|
all: vger
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f vger *.core *.o
|
find . -name vger -o \
|
||||||
|
-name \*\.o -o \
|
||||||
|
-name \*\.core \
|
||||||
|
-delete
|
||||||
|
|
||||||
vger: main.o mimes.o utils.o opts.h
|
vger: main.o mimes.o utils.o opts.h
|
||||||
${CC} ${CFLAGS} -o $@ main.o mimes.o utils.o
|
${CC} ${CFLAGS} -o $@ main.o mimes.o utils.o
|
||||||
|
|
48
main.c
48
main.c
|
@ -76,13 +76,16 @@ drop_privileges(const char *user, const char *path)
|
||||||
} else {
|
} else {
|
||||||
eunveil(path, "r");
|
eunveil(path, "r");
|
||||||
}
|
}
|
||||||
|
/* permission to execute what's inside cgipath */
|
||||||
if (strlen(cgibin) > 0) {
|
if (strlen(cgibin) > 0) {
|
||||||
|
/* first, build the full path of cgi (not in chroot) */
|
||||||
char cgifullpath[PATH_MAX] = {'\0'};
|
char cgifullpath[PATH_MAX] = {'\0'};
|
||||||
estrlcpy(cgifullpath, path, sizeof(cgifullpath));
|
estrlcpy(cgifullpath, path, sizeof(cgifullpath));
|
||||||
estrlcat(cgifullpath, cgibin, sizeof(cgifullpath));
|
estrlcat(cgifullpath, cgibin, sizeof(cgifullpath));
|
||||||
|
|
||||||
eunveil(cgifullpath, "rx");
|
eunveil(cgifullpath, "rx");
|
||||||
}
|
}
|
||||||
/* no more unveil later */
|
/* forbid more unveil */
|
||||||
eunveil(NULL, NULL);
|
eunveil(NULL, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -90,6 +93,7 @@ drop_privileges(const char *user, const char *path)
|
||||||
* write to stdio
|
* write to stdio
|
||||||
*/
|
*/
|
||||||
if (strlen(cgibin) > 0) {
|
if (strlen(cgibin) > 0) {
|
||||||
|
/* cgi need execlp() (exec) and fork() (proc) */
|
||||||
epledge("stdio rpath exec proc", NULL);
|
epledge("stdio rpath exec proc", NULL);
|
||||||
} else {
|
} else {
|
||||||
epledge("stdio rpath", NULL);
|
epledge("stdio rpath", NULL);
|
||||||
|
@ -121,6 +125,7 @@ display_file(const char *uri)
|
||||||
char *buffer[BUFSIZ];
|
char *buffer[BUFSIZ];
|
||||||
char target[FILENAME_MAX] = {'\0'};
|
char target[FILENAME_MAX] = {'\0'};
|
||||||
char fp[PATH_MAX] = {'\0'};
|
char fp[PATH_MAX] = {'\0'};
|
||||||
|
char tmp[PATH_MAX] = {'\0'}; /* used to build temporary path */
|
||||||
|
|
||||||
/* build file path inside chroot */
|
/* build file path inside chroot */
|
||||||
estrlcpy(fp, chroot_dir, sizeof(fp));
|
estrlcpy(fp, chroot_dir, sizeof(fp));
|
||||||
|
@ -141,21 +146,19 @@ display_file(const char *uri)
|
||||||
if (S_ISDIR(sb.st_mode) != 0) {
|
if (S_ISDIR(sb.st_mode) != 0) {
|
||||||
if (fp[strlen(fp) -1 ] != '/') {
|
if (fp[strlen(fp) -1 ] != '/') {
|
||||||
/* no ending "/", redirect to "path/" */
|
/* no ending "/", redirect to "path/" */
|
||||||
char new_uri[PATH_MAX] = {'\0'};
|
estrlcpy(tmp, uri, sizeof(tmp));
|
||||||
estrlcpy(new_uri, uri, sizeof(new_uri));
|
estrlcat(tmp, "/", sizeof(tmp));
|
||||||
estrlcat(new_uri, "/", sizeof(new_uri));
|
status_redirect(31, tmp);
|
||||||
status_redirect(31, new_uri);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* there is a leading "/", display index.gmi */
|
/* there is a leading "/", display index.gmi */
|
||||||
char index_path[PATH_MAX] = {'\0'};
|
estrlcpy(tmp, fp, sizeof(tmp));
|
||||||
estrlcpy(index_path, fp, sizeof(index_path));
|
estrlcat(tmp, "index.gmi", sizeof(tmp));
|
||||||
estrlcat(index_path, "index.gmi", sizeof(index_path));
|
|
||||||
|
|
||||||
/* check if index.gmi exists or show autoindex */
|
/* check if index.gmi exists or show autoindex */
|
||||||
if (stat(index_path, &sb) == 0) {
|
if (stat(tmp, &sb) == 0) {
|
||||||
estrlcpy(fp, index_path, sizeof(fp));
|
estrlcpy(fp, tmp, sizeof(fp));
|
||||||
} else if (doautoidx != 0) {
|
} else if (doautoidx != 0) {
|
||||||
autoindex(fp);
|
autoindex(fp);
|
||||||
return;
|
return;
|
||||||
|
@ -172,7 +175,7 @@ display_file(const char *uri)
|
||||||
|
|
||||||
status(20, file_mime);
|
status(20, file_mime);
|
||||||
|
|
||||||
/* read the file and write it to stdout */
|
/* read the file byte after byte in buffer and write it to stdout */
|
||||||
while ((nread = fread(buffer, 1, sizeof(buffer), fd)) != 0)
|
while ((nread = fread(buffer, 1, sizeof(buffer), fd)) != 0)
|
||||||
fwrite(buffer, 1, nread, stdout);
|
fwrite(buffer, 1, nread, stdout);
|
||||||
goto closefd;
|
goto closefd;
|
||||||
|
@ -205,22 +208,41 @@ void
|
||||||
autoindex(const char *path)
|
autoindex(const char *path)
|
||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
struct dirent **namelist;
|
char *pos = NULL;
|
||||||
|
struct dirent **namelist; /* this must be freed at last */
|
||||||
|
|
||||||
|
|
||||||
syslog(LOG_DAEMON, "autoindex: %s", path);
|
syslog(LOG_DAEMON, "autoindex: %s", path);
|
||||||
|
|
||||||
status(20, "text/gemini");
|
status(20, "text/gemini");
|
||||||
|
|
||||||
|
/* display link to parent */
|
||||||
|
char parent[PATH_MAX] = {'\0'};
|
||||||
|
/* parent is "path" without chroot_dir */
|
||||||
|
estrlcpy(parent, path+strlen(chroot_dir), sizeof(parent));
|
||||||
|
/* remove ending '/' */
|
||||||
|
while (parent[strlen(parent)-1] == '/') {
|
||||||
|
parent[strlen(parent)-1] = '\0';
|
||||||
|
}
|
||||||
|
/* remove last part after '/' */
|
||||||
|
pos = strrchr(parent, '/');
|
||||||
|
if (pos != NULL) {
|
||||||
|
pos[1] = '\0'; /* at worse, parent is now "/" */
|
||||||
|
}
|
||||||
|
printf("=> %s ../\n", parent);
|
||||||
|
|
||||||
|
/* use alphasort to always have the same order on every system */
|
||||||
if ((n = scandir(path, &namelist, NULL, alphasort)) < 0) {
|
if ((n = scandir(path, &namelist, NULL, alphasort)) < 0) {
|
||||||
status(51, "text/gemini");
|
status(51, "text/gemini");
|
||||||
errlog("Can't scan %s", path);
|
errlog("Can't scan %s", path);
|
||||||
} else {
|
} else {
|
||||||
for(int j = 0; j < n; j++) {
|
for(int j = 0; j < n; j++) {
|
||||||
|
/* skip self and parent */
|
||||||
if ((strcmp(namelist[j]->d_name, ".") == 0) ||
|
if ((strcmp(namelist[j]->d_name, ".") == 0) ||
|
||||||
(strcmp(namelist[j]->d_name, "..") == 0)) {
|
(strcmp(namelist[j]->d_name, "..") == 0)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
/* add "/" at the end of a directory path */
|
||||||
if (namelist[j]->d_type == DT_DIR) {
|
if (namelist[j]->d_type == DT_DIR) {
|
||||||
printf("=> ./%s/ %s/\n", namelist[j]->d_name, namelist[j]->d_name);
|
printf("=> ./%s/ %s/\n", namelist[j]->d_name, namelist[j]->d_name);
|
||||||
} else {
|
} else {
|
||||||
|
@ -239,6 +261,7 @@ cgi(const char *cgicmd)
|
||||||
int pipedes[2] = {0};
|
int pipedes[2] = {0};
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
|
/* get a pipe to get stdout */
|
||||||
if (pipe(pipedes) != 0) {
|
if (pipe(pipedes) != 0) {
|
||||||
status(42, "text/gemini");
|
status(42, "text/gemini");
|
||||||
err(1, "pipe failed");
|
err(1, "pipe failed");
|
||||||
|
@ -414,6 +437,7 @@ main(int argc, char **argv)
|
||||||
if ((strlen(cgibin) > 0) &&
|
if ((strlen(cgibin) > 0) &&
|
||||||
(strncmp(uri, cgibin, strlen(cgibin)) == 0)) {
|
(strncmp(uri, cgibin, strlen(cgibin)) == 0)) {
|
||||||
|
|
||||||
|
/* cgipath with chroot_dir at the beginning */
|
||||||
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));
|
||||||
|
|
|
@ -72,7 +72,7 @@ if ! [ $OUT = "874f5e1af67eff6b93bedf8ac8033066" ] ; then echo "error" ; exit 1
|
||||||
|
|
||||||
# auto index in directory
|
# auto index in directory
|
||||||
OUT=$(printf "gemini://host.name/autoidx/\r\n" | ../vger -d var/gemini/ -i | tee /dev/stderr | $MD5)
|
OUT=$(printf "gemini://host.name/autoidx/\r\n" | ../vger -d var/gemini/ -i | tee /dev/stderr | $MD5)
|
||||||
if ! [ $OUT = "988160d1908a9dcd0cadc21262de4490" ] ; then echo "error" ; exit 1 ; fi
|
if ! [ $OUT = "515bcb4ba5f8869360f53afe2841e044" ] ; then echo "error" ; exit 1 ; fi
|
||||||
|
|
||||||
# cgi simple script
|
# cgi simple script
|
||||||
OUT=$(printf "gemini://host.name/cgi-bin/test.cgi\r\n" | ../vger -d var/gemini/ -c /cgi-bin | tee /dev/stderr | $MD5)
|
OUT=$(printf "gemini://host.name/cgi-bin/test.cgi\r\n" | ../vger -d var/gemini/ -c /cgi-bin | tee /dev/stderr | $MD5)
|
||||||
|
|
2
utils.c
2
utils.c
|
@ -34,7 +34,7 @@ estrlcpy(char *dst, const char *src, size_t dstsize)
|
||||||
|
|
||||||
n = strlcpy(dst, src, dstsize);
|
n = strlcpy(dst, src, dstsize);
|
||||||
if (n >= dstsize) {
|
if (n >= dstsize) {
|
||||||
err(1, "strlcyp failed for %s = %s", dst, src);
|
err(1, "strlcpy failed for %s = %s", dst, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
|
|
Loading…
Add table
Reference in a new issue