git-restrict

simple utility for git repo permission management
git clone https://git.parazyd.org/git-restrict
Log | Files | Refs | README | LICENSE

commit 8afd2755b983911dbed4b06f1cd86eea4f14c42b
parent d7a8d9d61816d229b7d1fe9214c01f8b8794204b
Author: parazyd <parazyd@dyne.org>
Date:   Sun, 22 May 2022 14:12:04 +0200

Be fully C99 portable.

Diffstat:
MMakefile | 5++---
MREADME.md | 4++--
Mgit-restrict.c | 24++++++++++++++----------
3 files changed, 18 insertions(+), 15 deletions(-)

diff --git a/Makefile b/Makefile @@ -5,8 +5,7 @@ PREFIX = /usr/local MANPREFIX = ${PREFIX}/share/man # Use system flags -GR_CFLAGS = $(CFLAGS) -Wall -Werror -pedantic -std=c99 -GR_CPPFLAGS = $(CPPFLAGS) -D_GNU_SOURCE +GR_CFLAGS = $(CFLAGS) -Wall -Wextra -Werror -pedantic -std=c99 GR_LDFLAGS = $(LDFLAGS) -static -s BIN = git-restrict @@ -16,7 +15,7 @@ OBJ = $(BIN:=.o) all: $(BIN) .c.o: - $(CC) -c $(GR_CFLAGS) $(GR_CPPFLAGS) $< + $(CC) -c $(GR_CFLAGS) $< $(BIN): $(OBJ) $(CC) $(OBJ) $(GR_LDFLAGS) -o $@ diff --git a/README.md b/README.md @@ -10,8 +10,8 @@ file. If used, it will only allow `git-upload-pack` and `git-receive-pack` as the commands allowed to be ran by a specific user/SSH key. -git-restrict is also compiled as a static binary so it's easy to use it -in chroot environments. This is obviously intentional. +git-restrict is C99 portable and compiled as a static binary so it's +easy to use it in chroot environments. This is obviously intentional. Basic usage diff --git a/git-restrict.c b/git-restrict.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2021 Ivan J. <parazyd@dyne.org> +/* Copyright (c) 2021-2022 Ivan J. <parazyd@dyne.org> * * This file is part of git-restrict * @@ -14,7 +14,6 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -26,10 +25,18 @@ static void die(const char *msg) exit(1); } +static char *strdup(const char *s) +{ + size_t l = strlen(s); + char *d = malloc(l+1); + if (!d) return NULL; + return memcpy(d, s, l+1); +} + int main(int argc, char *argv[]) { char *orig_cmd, *cmd, *repo, *buf; - char git_cmd[PATH_MAX]; + char git_cmd[4096]; int i, authorized = 0; if (argc < 2) @@ -38,10 +45,9 @@ int main(int argc, char *argv[]) if ((orig_cmd = getenv("SSH_ORIGINAL_COMMAND")) == NULL) die("fatal: No $SSH_ORIGINAL_COMMAND in env."); - repo = strdup(orig_cmd); - - if ((cmd = strsep(&repo, " ")) == NULL) - die("fatal: Invalid command."); + if ((repo = strdup(orig_cmd)) == NULL) die("fatal: Internal error."); + if ((cmd = strtok(repo, " ")) == NULL) die("fatal: Invalid command."); + repo = strtok(NULL, " "); if (strcmp("git-upload-pack", cmd) && strcmp("git-receive-pack", cmd)) die("fatal: Unauthorized command."); @@ -51,9 +57,7 @@ int main(int argc, char *argv[]) die("fatal: Invalid repository name."); /* Remove ' and / prefix and ' suffix */ - repo++; - if (repo[0] == '/') repo++; - repo[strlen(repo) - 1] = 0; + repo++; if (repo[0] == '/') repo++; repo[strlen(repo) - 1] = 0; for (i = 1; i < argc; i++) { /* This is so both "foo" and "foo.git" are supported */