From f44b5a028dc19e1508a8e5be8c64e0818acef9f2 Mon Sep 17 00:00:00 2001
From: =?utf8?q?Am=C3=A9lia=20Coutard-Sander?= <git@ameliathe1st.gay>
Date: Wed, 4 Dec 2024 22:33:05 +0100
Subject: [PATCH] Better check for path correctness, allows subdirectories

---
 README.txt        |  2 +-
 git-remote-gnunet |  4 ++--
 handle-request.sh | 22 +++++++++++-----------
 3 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/README.txt b/README.txt
index 59e784f..12ba422 100644
--- a/README.txt
+++ b/README.txt
@@ -37,7 +37,7 @@ TODO:
 How it works:
 Client:
 	- Uses a git remote helper to give git the ability to interpet the gnunet:// scheme.
-	- Gets the VPN record associated with the GNS name given in gnunet://<gns-name>/<repo-name>.
+	- Gets the VPN record associated with the GNS name given in gnunet://<gns-name>/<repo-path>.
 	- Connects to the exit service, give it the name of the repo and the command required (e.g. `git-upload-pack`).
 Server:
 	- Reads the path and the command.
diff --git a/git-remote-gnunet b/git-remote-gnunet
index 59d1bcd..796a88c 100755
--- a/git-remote-gnunet
+++ b/git-remote-gnunet
@@ -7,11 +7,11 @@ if [[ "$2" = gnunet://* ]]; then
 else
 	echo "$2"
 fi | awk '
-match($0, /(([^@]*)@)?([^/]*)(\/(.*))?/, a) { printf "%s\n%s\n%s\n", a[2], a[3], a[5] }
+match($0, /(([^@]*)@)?([^/]*)(\/.*)?/, a) { printf "%s\n%s\n%s\n", a[2], a[3], a[4] }
 ' | { read -r username && read -r gnsname && read -r path && ! grep '.'; }
 if test "$?" != "0"; then
 	echo >&2 "Invalid address: \`$2'."
-	echo >&2 "URI format: \`[gnunet://][user@]gns.name/path/to/repo'."
+	echo >&2 "URI format: \`[gnunet://][user@]gns.name[/path/to/repo]'."
 	exit 1
 fi
 
diff --git a/handle-request.sh b/handle-request.sh
index 97d8f4c..743a99e 100755
--- a/handle-request.sh
+++ b/handle-request.sh
@@ -4,26 +4,26 @@ if test -z $1 || ! test -z $2; then
 	echo >&2 "Usage: $0 /base/path"
 	exit 1
 fi
-base_path="$1/"
+base_path="$1"
 
 read -r path || { echo "No path specified." | tee /dev/stderr; exit 1; }
 read -r comm || { echo "No command specified." | tee /dev/stderr; exit 1; }
 
-if echo "$path" | grep -q '/'; then
-	echo "Path \`$path' contains a '/'." | tee /dev/stderr
-	exit 1
-fi
-if test "$path" = '..'; then
-	echo "Path cannot be \`..'." | tee /dev/stderr
-	exit 1
-fi
+full_path="$(realpath -sm "$base_path$path")"
+case "$full_path" in
+	"$base_path") ;;
+	"$base_path/"*) ;;
+	*)	echo "Invalid path: \`$full_path'." | tee /dev/stderr
+		exit 1
+		;;
+esac
 
 if test "$comm" != "git-upload-pack"; then
 	echo "Command \`$comm' has to be git-upload-pack." | tee /dev/stderr
 	exit 1
 fi
 
-git -C "$base_path$path" rev-parse --git-dir >/dev/null 2>/dev/null || { echo "Not a git repository." | tee /dev/stderr; exit 1; }
+git_dir="$(git -C "$full_path" rev-parse --path-format=absolute --git-dir)" || { echo "Not a git repository: \`$full_path'." | tee /dev/stderr; exit 1; }
 
 echo ''
-exec "$comm" "$base_path$path"
+exec "$comm" "$git_dir"
-- 
2.46.0