Merge branch 'master' of tildegit.org:solene/vger
This commit is contained in:
commit
de52acecfc
2 changed files with 28 additions and 65 deletions
81
main.c
81
main.c
|
@ -27,12 +27,14 @@
|
|||
*/
|
||||
#define GEMINI_REQUEST_MAX 1025
|
||||
|
||||
int virtualhost;
|
||||
|
||||
void autoindex(const char *);
|
||||
void cgi(const char *cgicmd);
|
||||
void display_file(const char *);
|
||||
void status(const int, const char *);
|
||||
void status_redirect(const int, const char *);
|
||||
void status_error(const int, const char*);
|
||||
void drop_privileges(const char *, const char *);
|
||||
int uridecode(char *);
|
||||
|
||||
|
@ -129,16 +131,14 @@ drop_privileges(const char *user, const char *path)
|
|||
|
||||
eunveil(cgifullpath, "rx");
|
||||
}
|
||||
/* forbid more unveil */
|
||||
eunveil(NULL, NULL);
|
||||
|
||||
/*
|
||||
* prevent system calls other parsing queryfor fread file and
|
||||
* write to stdio
|
||||
*/
|
||||
if (strlen(cgibin) > 0) {
|
||||
/* cgi need execlp() (exec) and fork() (proc) */
|
||||
epledge("stdio rpath exec proc", NULL);
|
||||
/* cgi need execlp() (exec) */
|
||||
epledge("stdio rpath exec", NULL);
|
||||
} else {
|
||||
epledge("stdio rpath", NULL);
|
||||
}
|
||||
|
@ -159,6 +159,13 @@ status_redirect(const int code, const char *url)
|
|||
code, url);
|
||||
}
|
||||
|
||||
void
|
||||
status_error(const int code, const char *reason)
|
||||
{
|
||||
printf("%i %s\r\n",
|
||||
code, reason);
|
||||
}
|
||||
|
||||
void
|
||||
display_file(const char *uri)
|
||||
{
|
||||
|
@ -190,7 +197,9 @@ display_file(const char *uri)
|
|||
if (S_ISDIR(sb.st_mode) != 0) {
|
||||
if (fp[strlen(fp) -1 ] != '/') {
|
||||
/* no ending "/", redirect to "path/" */
|
||||
estrlcpy(tmp, uri, sizeof(tmp));
|
||||
if (virtualhost)
|
||||
estrlcat(tmp, "gemini://", sizeof(tmp));
|
||||
estrlcat(tmp, uri, sizeof(tmp));
|
||||
estrlcat(tmp, "/", sizeof(tmp));
|
||||
status_redirect(31, tmp);
|
||||
return;
|
||||
|
@ -229,7 +238,7 @@ display_file(const char *uri)
|
|||
|
||||
err:
|
||||
/* return an error code and no content */
|
||||
status(51, "text/gemini");
|
||||
status_error(51, "file not found");
|
||||
syslog(LOG_DAEMON, "path invalid %s", fp);
|
||||
goto closefd;
|
||||
|
||||
|
@ -255,11 +264,8 @@ autoindex(const char *path)
|
|||
char *pos = NULL;
|
||||
struct dirent **namelist; /* this must be freed at last */
|
||||
|
||||
|
||||
syslog(LOG_DAEMON, "autoindex: %s", path);
|
||||
|
||||
status(20, "text/gemini");
|
||||
|
||||
/* display link to parent */
|
||||
char parent[PATH_MAX] = {'\0'};
|
||||
/* parent is "path" without chroot_dir */
|
||||
|
@ -273,13 +279,14 @@ autoindex(const char *path)
|
|||
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) {
|
||||
status(51, "text/gemini");
|
||||
status_error(50, "Internal server error");
|
||||
errlog("Can't scan %s", path);
|
||||
} else {
|
||||
status(20, "text/gemini");
|
||||
printf("=> %s ../\n", parent);
|
||||
for(int j = 0; j < n; j++) {
|
||||
/* skip self and parent */
|
||||
if ((strcmp(namelist[j]->d_name, ".") == 0) ||
|
||||
|
@ -301,58 +308,11 @@ autoindex(const char *path)
|
|||
void
|
||||
cgi(const char *cgicmd)
|
||||
{
|
||||
|
||||
int pipedes[2] = {0};
|
||||
pid_t pid;
|
||||
|
||||
/* get a pipe to get stdout */
|
||||
if (pipe(pipedes) != 0) {
|
||||
status(42, "text/gemini");
|
||||
err(1, "pipe failed");
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
|
||||
if (pid < 0) {
|
||||
close(pipedes[0]);
|
||||
close(pipedes[1]);
|
||||
status(42, "text/gemini");
|
||||
err(1, "fork failed");
|
||||
}
|
||||
|
||||
if (pid > 0) { /* parent */
|
||||
char buf[3];
|
||||
size_t nread = 0;
|
||||
FILE *output = NULL;
|
||||
|
||||
close(pipedes[1]); /* make sure entry is closed so fread() gets EOF */
|
||||
|
||||
/* use fread/fwrite because are buffered */
|
||||
output = fdopen(pipedes[0], "r");
|
||||
if (output == NULL) {
|
||||
status(42, "text/gemini");
|
||||
err(1, "fdopen failed");
|
||||
}
|
||||
|
||||
/* read pipe output */
|
||||
while ((nread = fread(buf, 1, sizeof(buf), output)) != 0) {
|
||||
fwrite(buf, 1, nread, stdout);
|
||||
}
|
||||
close(pipedes[0]);
|
||||
fclose(output);
|
||||
|
||||
wait(NULL); /* wait for child to terminate */
|
||||
|
||||
exit(0);
|
||||
|
||||
} else if (pid == 0) { /* child */
|
||||
dup2(pipedes[1], STDOUT_FILENO); /* set pipe output equal to stdout */
|
||||
close(pipedes[1]); /* no need this file descriptor : it is now stdout */
|
||||
execlp(cgicmd, cgicmd, NULL);
|
||||
/* if execlp is ok, this will never be reached */
|
||||
status(42, "text/gemini");
|
||||
status(42, "Couldn't execute CGI script");
|
||||
errlog("error when trying to execlp %s", cgicmd);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -363,7 +323,6 @@ main(int argc, char **argv)
|
|||
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;
|
||||
|
||||
|
|
|
@ -31,6 +31,10 @@ if ! [ $OUT = "fcc5a293f316e01f7b3103f97eca26b1" ] ; then echo "error" ; exit 1
|
|||
OUT=$(printf "gemini://host.name/subdir\r\n" | ../vger -d var/gemini/ | tee /dev/stderr | MD5)
|
||||
if ! [ $OUT = "84e5e7bb3eee0dfcc8db14865dc83e77" ] ; then echo "error" ; exit 1 ; fi
|
||||
|
||||
# redirect to uri with trailing / if directory and vhost enabled
|
||||
OUT=$(printf "gemini://perso.pw/cgi-bin\r\n" | ../vger -vd var/gemini | tee /dev/stderr | MD5)
|
||||
if ! [ $OUT = "c782da4173898f57033a0804b8e96fc3" ] ; then echo "error" ; exit 1 ; fi
|
||||
|
||||
# file from local directory with lang=fr and markdown MIME type
|
||||
OUT=$(printf "gemini://perso.pw/file.md\r\n" | ../vger -d var/gemini/ -l fr | tee /dev/stderr | MD5)
|
||||
if ! [ $OUT = "e663f17730d5ddc24010c14a238e1e78" ] ; then echo "error" ; exit 1 ; fi
|
||||
|
@ -85,7 +89,7 @@ if ! [ $OUT = "fa065a67d1f7c973501d4a9e3ca2ea57" ] ; then echo "error" ; exit 1
|
|||
|
||||
# cgi with error
|
||||
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 = "4156170c2aa8a6a8a0892ff5a61bf5f5" ] ; 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)
|
||||
|
|
Loading…
Reference in a new issue