diff options
| author | Louis Burda <quent.burda@gmail.com> | 2021-07-07 23:17:31 +0200 |
|---|---|---|
| committer | Louis Burda <quent.burda@gmail.com> | 2021-07-07 23:17:39 +0200 |
| commit | 8e430a00c145647cf6a67504640bd919af2c4fdf (patch) | |
| tree | 1ad8cbac62cede66e383266d653b042337572058 /service | |
| parent | 3139342aa61d78985298d7450f97513a8aeec681 (diff) | |
| download | enowars5-service-stldoctor-8e430a00c145647cf6a67504640bd919af2c4fdf.tar.gz enowars5-service-stldoctor-8e430a00c145647cf6a67504640bd919af2c4fdf.zip | |
stash before adding attack_info for fixing exploit variant 2
Diffstat (limited to 'service')
| -rw-r--r-- | service/Dockerfile | 13 | ||||
| -rw-r--r-- | service/cleaner.sh | 24 | ||||
| -rw-r--r-- | service/cleaner/.gitignore | 1 | ||||
| -rw-r--r-- | service/cleaner/Makefile | 7 | ||||
| -rw-r--r-- | service/cleaner/main.c | 155 | ||||
| -rwxr-xr-x | service/entrypoint.sh | 15 | ||||
| -rw-r--r-- | service/src/main.c | 93 |
7 files changed, 243 insertions, 65 deletions
diff --git a/service/Dockerfile b/service/Dockerfile index 66952dc..c49190e 100644 --- a/service/Dockerfile +++ b/service/Dockerfile @@ -8,16 +8,19 @@ RUN adduser --system --ingroup service --uid 1000 service COPY entrypoint.sh / RUN chmod 755 /entrypoint.sh -COPY cleaner.sh / -RUN chmod 755 /cleaner.sh +COPY cleaner /cleaner +RUN make -C /cleaner clean && make -C /cleaner +RUN cp /cleaner/cleaner /usr/bin/cleaner +run chmod +x /usr/bin/cleaner COPY src/ /service/ +RUN make -C /service clean && make -C /service +RUN chmod +x /service/build/stldoctor WORKDIR /service/ -RUN make clean && make - -EXPOSE 9000 ENV RESULTDIR=/data/uploads +EXPOSE 9000 + ENTRYPOINT ["/entrypoint.sh"] diff --git a/service/cleaner.sh b/service/cleaner.sh deleted file mode 100644 index bd67705..0000000 --- a/service/cleaner.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh - -timeref="/data/lastclean" - -if [ -z "$RESULTDIR" ]; then - echo "RESULTDIR is undefined! skipping cleanup.." - exit 1 -fi - -if [ -f "$timeref" ]; then - files="$(find "$RESULTDIR" -mindepth 1 \! -newer "$timeref")" - echo "$files" | while read path; do - rm -rf "$path" - done - if [ -z "$files" ]; then - filecount=0 - else - filecount=$(echo "$files" | wc -l) - fi - echo "[ $(date +%T) ] Removed $filecount old files!" -fi - -touch "$timeref" - diff --git a/service/cleaner/.gitignore b/service/cleaner/.gitignore new file mode 100644 index 0000000..021c4e8 --- /dev/null +++ b/service/cleaner/.gitignore @@ -0,0 +1 @@ +cleaner diff --git a/service/cleaner/Makefile b/service/cleaner/Makefile new file mode 100644 index 0000000..1589c27 --- /dev/null +++ b/service/cleaner/Makefile @@ -0,0 +1,7 @@ +all: cleaner + +clean: + rm cleaner + +cleaner: main.c + $(CC) -o $@ $< diff --git a/service/cleaner/main.c b/service/cleaner/main.c new file mode 100644 index 0000000..ef48dfa --- /dev/null +++ b/service/cleaner/main.c @@ -0,0 +1,155 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> + +#include <unistd.h> +#include <dirent.h> +#include <time.h> +#include <sys/file.h> +#include <sys/stat.h> + +void +die(const char *fmtstr, ...) +{ + va_list ap; + + fprintf(stderr, "CLEANER: "); + va_start(ap, fmtstr); + vfprintf(stderr, fmtstr, ap); + va_end(ap); + + exit(EXIT_FAILURE); +} + +int +creation_time(const char *path) +{ + struct stat attrib; + + stat(path, &attrib); + return attrib.st_ctim.tv_sec; +} + +char* +aprintf(const char *fmtstr, ...) +{ + va_list ap, cpy; + size_t nb; + char *str; + + va_copy(cpy, ap); + + va_start(cpy, fmtstr); + nb = vsnprintf(NULL, 0, fmtstr, cpy); + va_end(cpy); + + if (nb <= 0) die("Invalid fmtstr!\n"); + str = malloc(nb+1); + if (!str) die("Alloc of fmtstr failed\n"); + + va_start(ap, fmtstr); + nb = vsnprintf(str, nb+1, fmtstr, ap); + va_end(ap); + + return str; +} + +void +recdel(const char *path) +{ + struct stat attrib; + struct dirent *de; + char *subpath; + DIR *d; + + stat(path, &attrib); + if (S_ISDIR(attrib.st_mode)) { + d = opendir(path); + while ((de = readdir(d))) { + if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) + continue; + subpath = aprintf("%s/%s", path, de->d_name); + recdel(subpath); + free(subpath); + } + closedir(d); + rmdir(path); + } else { + remove(path); + } +} + +int +main(int argc, const char **argv) +{ + char buf[256], *end, *path, + **paths, *oldpath, *newpath; + unsigned long reftime; + int i, pathc, pathcap, nread; + const char *dirpath; + FILE *f, *fn; + + if (argc != 3) die("USAGE: cleaner DIR REFTIME\n"); + + dirpath = argv[1]; + + reftime = strtoul(argv[2], &end, 10); + if (end && *end) die("Invalid unix time reference\n"); + + oldpath = aprintf("%s/.index", dirpath); + if (!(f = fopen(oldpath, "r+"))) + die("Missing index file: %s\n", oldpath); + flock(fileno(f), LOCK_EX); + + newpath = aprintf("%s/.index.next", dirpath); + if (!(fn = fopen(newpath, "w+"))) + die("Failed to create index file: %s\n", newpath); + + pathc = 0; + pathcap = 1024; + paths = malloc(pathcap * sizeof(char*)); + if (!paths) die("OOM - allocating initial path array\n"); + + while (fgets(buf, sizeof(buf), f)) { + if (*buf && buf[strlen(buf)-1] == '\n') + buf[strlen(buf)-1] = '\0'; + + path = aprintf("%s/%s", dirpath, buf); + if (creation_time(path) < reftime) { + paths[pathc] = strdup(path); + if (!paths[pathc++]) die("OOM - during path str alloc\n"); + if (pathc == pathcap) { + pathcap *= 2; + paths = realloc(paths, pathcap * sizeof(char*)); + if (!paths) die("OOM - too many paths to alloc\n"); + } + } else { + fwrite(buf, 1, strlen(buf), fn); + putc('\n', fn); + } + free(path); + } + + fseek(f, 0, SEEK_SET); + fseek(fn, 0, SEEK_SET); + while ((nread = fread(buf, 1, sizeof(buf), fn)) > 0) + fwrite(buf, 1, nread, f); + ftruncate(fileno(f), ftell(f)); + + nread = ftell(f); + + flock(fileno(f), LOCK_UN); + fclose(f); + fclose(fn); + + if (!nread && getenv("DELROOT")) { + remove(oldpath); + remove(newpath); + } + + for (i = 0; i < pathc; i++) { + printf("CLEANER: REMOVED %s\n", paths[i]); + recdel(paths[i]); + } +} diff --git a/service/entrypoint.sh b/service/entrypoint.sh index 614b251..f266474 100755 --- a/service/entrypoint.sh +++ b/service/entrypoint.sh @@ -3,10 +3,19 @@ mkdir -p "$RESULTDIR" chown -R service:service "$RESULTDIR" +expiry=$((13*60)) while [ 1 ]; do - /cleaner.sh - sleep $((60*13)) # data persistence for atleast 11 rounds + reftime="$(($(date +%s)-$expiry))" + echo "[FILE CLEANUP] @ $(date +%T)" + cleaner "$RESULTDIR" "$reftime" + DELROOT=1 find "$RESULTDIR" -maxdepth 1 -regextype posix-extended \ + -regex '.*/\.[^/]+$' ! -name .index ! -name .index.next \ + -exec cleaner {} "$reftime" \; + find "$RESULTDIR" -regextype posix-extended \ + -regex '.*/\.[^/]+$' -type d -empty -delete + sleep 70 done & -CMD="socat -T180 -s TCP-LISTEN:9000,nodelay,reuseaddr,fork EXEC:/service/build/stldoctor,raw,pty,echo=0,stderr" +CMD="socat -T180 -s TCP-LISTEN:9000,nodelay,reuseaddr,fork \ +EXEC:/service/build/stldoctor,raw,pty,echo=0,stderr" su -s /bin/sh -c "$CMD" service diff --git a/service/src/main.c b/service/src/main.c index 5f3282d..cc92cf5 100644 --- a/service/src/main.c +++ b/service/src/main.c @@ -2,7 +2,6 @@ #include <string.h> #include <stdarg.h> #include <unistd.h> -#include <dirent.h> #include <fcntl.h> #include <time.h> #include <errno.h> @@ -56,7 +55,6 @@ save_submission(struct parseinfo *info, char *stldata, int stlsize) *indexpath = NULL, *modelpath = NULL; FILE *f = NULL; int status = OK; - DIR *d; modeldir = aprintf("%s%s-%i", loggedin ? "." : "", info->hash, time(NULL)); @@ -296,22 +294,28 @@ search_cmd(const char *arg) while ((c = fgetc(f)) > 0) { if (c == '\n') { matchlen = 0; + continue; } else if (matchlen == -1) { continue; + } else if (!matchlen && c == '.') { + if (!loggedin) matchlen = -1; + continue; } else if (c == hash[matchlen]) { matchlen += 1; - if (matchlen == strlen(hash)) { - fseek(f, -matchlen, SEEK_CUR); - putchar(' '); - while ((c = fgetc(f)) > 0 && c != '\n') - putchar(c); - putchar('\n'); - matchlen = 0; - reslen += 1; - } } else { matchlen = -1; } + + if (matchlen == strlen(hash)) { + fseek(f, -matchlen, SEEK_CUR); + putchar(' '); + if (loggedin) putchar('.'); + while ((c = fgetc(f)) > 0 && c != '\n') + putchar(c); + putchar('\n'); + matchlen = 0; + reslen += 1; + } } flock(fileno(f), LOCK_UN); @@ -326,7 +330,7 @@ search_cmd(const char *arg) resp = ask("> Enter %s [q to quit]: ", resp ? "another" : "hash"); if (strchr(resp, 'q')) break; - if (checkalph(resp, "abcdef0123456789-") != OK) { + if (checkalph(resp, ".abcdef0123456789-") != OK) { ERR("Invalid model id specified\n"); goto exit; } @@ -345,43 +349,50 @@ exit: void list_cmd(const char *arg) { - struct dirent *de; struct parseinfo info; - char *path; - FILE *f; - DIR *d; + char buf[256], *path; + FILE *f, *fn; if (!loggedin) { ERR("Not logged in!\n"); return; } - if (!(d = opendir(resultdir))) return; - - while ((de = readdir(d))) { - if (*de->d_name == '.' && !strchr(".", de->d_name[1])) { - printf(">> %s\n", de->d_name); - path = aprintf("%s/%s/info", resultdir, de->d_name); - if ((f = fopen(path, "r")) && load_info(&info, f) == OK) { - print_info(&info); - free_info(&info); - } else { - ERR("Failed to read file info!\n"); - } - if (f) fclose(f); - free(path); - } + path = aprintf("%s/.index", resultdir); + if (!(f = fopen(path, "r"))) { + ERR("Failed to get files index\n"); + free(path); + return; } + free(path); - closedir(d); + flock(fileno(f), LOCK_SH); + while (fgets(buf, sizeof(buf), f)) { + if (*buf && buf[strlen(buf)-1] == '\n') + buf[strlen(buf)-1] = '\0'; + + printf(">> %s\n", buf); + path = aprintf("%s/%s/info", resultdir, buf); + if ((fn = fopen(path, "r")) && load_info(&info, fn) == OK) { + print_info(&info); + free_info(&info); + } else { + ERR("Failed to read file info!\n"); + } + if (fn) fclose(f); + free(path); + } + flock(fileno(f), LOCK_UN); + fclose(f); } void auth_cmd(const char *arg) { const char *hash; - char *ndir; + char *ndir, *indexpath; int ret; + FILE *f; if (loggedin) { ERR("Already logged in!\n"); @@ -400,6 +411,22 @@ auth_cmd(const char *arg) return; } + if (errno != EEXIST) { + indexpath = aprintf("%s/.index", resultdir); + if (!(f = fopen(indexpath, "a+"))) { + free(indexpath); + ERR("Auth failed!\n"); + return; + } + flock(fileno(f), LOCK_EX); + fputc('.', f); + fwrite(hash, 1, strlen(hash), f); + fputc('\n', f); + flock(fileno(f), LOCK_UN); + fclose(f); + free(indexpath); + } + free(resultdir); resultdir = ndir; loggedin = 1; |
