diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | LICENSE | 13 | ||||
-rw-r--r-- | Makefile | 19 | ||||
-rw-r--r-- | README.md | 10 | ||||
-rw-r--r-- | cgit-about-filter.c | 59 | ||||
-rwxr-xr-x | cgit-chroot | 71 |
6 files changed, 173 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f14e924 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/cgit-about-filter @@ -0,0 +1,13 @@ +Copyright 2020 Wynn Wolf Arbor <wolf@oriole.systems> + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8f0a1e0 --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +PREFIX ?= /usr/local +LIBEXECDIR ?= ${PREFIX}/libexec/skein + +CFLAGS ?= -O2 -pipe -s +CFLAGS += -Wall -Wextra -Wpedantic -Werror + +LDFLAGS ?= -static + +cgit-about-filter: cgit-about-filter.c + ${CC} -o $@ ${CFLAGS} ${LDFLAGS} $< + +install: cgit-chroot cgit-about-filter + install -D -m 755 -t '${DESTDIR}${LIBEXECDIR}' cgit-chroot + install -D -m 755 -t '${DESTDIR}${LIBEXECDIR}' cgit-about-filter + +clean: + rm cgit-about-filter + +.PHONY: install clean diff --git a/README.md b/README.md new file mode 100644 index 0000000..ff80f7e --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# skein - secure cgit hosting with slowcgi(8) on Gentoo Linux + +This is a small collection of utilities needed for managing a secure and +extensible deployment of cgit using OpenBSD's slowcgi(8). + +## Utilities + +- cgit-chroot - set up skein's cgit chroot environment +- cgit-about-filter - a C implementation of a simple about-filter for + cgit using mandoc(1) and lowdown(1). diff --git a/cgit-about-filter.c b/cgit-about-filter.c new file mode 100644 index 0000000..68dfd9b --- /dev/null +++ b/cgit-about-filter.c @@ -0,0 +1,59 @@ +#define _POSIX_C_SOURCE 200809L + +#include <ctype.h> +#include <string.h> +#include <unistd.h> + +#define EXEC(args) execvp(args[0], args) + +static const char *extension(const char *filename); + +char *mandoc[] = { "mandoc", "-Thtml", "-Ofragment", NULL }; +char *lowdown[] = { "lowdown", "-Thtml", NULL }; + +int +main(int argc, char *argv[]) +{ + int opt; + while ((opt = getopt(argc, argv, "")) != -1) + return 1; + argc -= optind; + argv += optind; + + if (argc != 1) + return 1; + + const char *ext = extension(argv[0]); + if (ext == NULL) + return 1; + + if (strlen(ext) == 1 && isdigit(*ext)) { + EXEC(mandoc); + } else if (strcmp(ext, "md") == 0) { + EXEC(lowdown); + } + + return 1; +} + +static const char * +extension(const char *filename) +{ + const char *end = strrchr(filename, '.'); + + // no dot + if (end == NULL) + return NULL; + + // no extension + if (end == filename) + return NULL; + + const char *ext = end + 1; + + // extension is empty/name ends with dot + if (*ext == '\0') + return NULL; + + return ext; +} diff --git a/cgit-chroot b/cgit-chroot new file mode 100755 index 0000000..1828ee5 --- /dev/null +++ b/cgit-chroot @@ -0,0 +1,71 @@ +#!/bin/sh + +set -e + +CGIT_CHROOT=${CGIT_CHROOT:-/srv/cgit} +CGIT_GIT_ROOT=${CGIT_GIT_ROOT:-/srv/git} + +log() { + printf ' %s %s\n' "$1" "$2" +} + +ladd() { + log + "$1" +} + +ldel() { + log - "$1" +} + +remove_prefix() { + printf "%s" "${1#$CGIT_CHROOT/*}" +} + +bind_mount() { + mkdir "$2" + mount --rbind "$1" "$2" + mount --make-rslave "$2" + ladd "$(remove_prefix "$2")" +} + +bind_umount() { + umount "$i" + rmdir "$i" + ldel "$(remove_prefix "$i")" +} + +setup() { + mkdir "$CGIT_CHROOT"/dev + mknod "$CGIT_CHROOT"/dev/null c 1 3 + chmod 666 "$CGIT_CHROOT"/dev/null + + for i in "$CGIT_CHROOT"/instances/*; do + test -d "$i" || continue + user=$(basename "$i") + id -ru "$user" >/dev/null || continue + + git_repo_dir="${CGIT_GIT_ROOT}/$user" + test -d "$git_repo_dir" || continue + + instance_repo_dir="$CGIT_CHROOT"/instances/$user/repos + + bind_mount "$git_repo_dir" "$instance_repo_dir" + chmod 0701 "$instance_repo_dir" + done +} + +teardown() { + rm "$CGIT_CHROOT"/dev/null + rmdir "$CGIT_CHROOT"/dev + + for i in "$CGIT_CHROOT"/instances/*/repos; do + bind_umount "$i" + done +} + +test $# -eq 1 || exit 1 + +case $1 in + setup) setup;; + teardown) teardown;; +esac |