#!/bin/sh
# gitgud-ssh — SSH command shim invoked by OpenSSH's authorized_keys.
#
# Layout in authorized_keys (one line per key):
# command="/usr/local/bin/gitgud-ssh <key_id>",no-port-forwarding,... <ssh-ed25519 AAAA... user@host>
#
# When the user runs:
# ssh git@host 'git-upload-pack '"'"'owner/repo.git'"'"''
# OpenSSH sets $SSH_ORIGINAL_COMMAND to that string and execs this
# script with the key_id as $1.
set -eu
KEY_ID="${1:-}"
CMD="${SSH_ORIGINAL_COMMAND:-}"
if [ -z "$KEY_ID" ]; then
echo "gitgud-ssh: missing key id" >&2
exit 2
fi
if [ -z "$CMD" ]; then
echo "gitgud-ssh: interactive shell not allowed for key #${KEY_ID}" >&2
exit 1
fi
# Resolve repo on disk via the helper Phoenix exposes.
# Override via env in tests.
GITGUD_AUTH_URL="${GITGUD_AUTH_URL:-http://127.0.0.1:4000/_ssh/resolve}"
case "$CMD" in
git-upload-pack\ * | git-receive-pack\ * | git-upload-archive\ *)
GIT_CMD=$(printf '%s' "$CMD" | awk '{print $1}')
REPO_ARG=$(printf '%s' "$CMD" | sed -e "s/^${GIT_CMD} //" -e "s/^'//" -e "s/'$//")
;;
*)
echo "gitgud-ssh: command not allowed: ${CMD}" >&2
exit 1
;;
esac
# Ask the running Phoenix node to resolve (key_id, repo_arg, git_cmd)
# → on-disk path + authorization decision. Response is a single line:
# OK <absolute_repo_path>
# or:
# DENY <reason>
RESP=$(curl -sf -X POST \
-H 'content-type: application/json' \
--data-binary "{\"key_id\":\"${KEY_ID}\",\"repo\":\"${REPO_ARG}\",\"cmd\":\"${GIT_CMD}\"}" \
"${GITGUD_AUTH_URL}") || {
echo "gitgud-ssh: auth backend unreachable" >&2
exit 1
}
STATUS=$(printf '%s' "$RESP" | awk '{print $1}')
PAYLOAD=$(printf '%s' "$RESP" | cut -d' ' -f2-)
if [ "$STATUS" != "OK" ]; then
echo "gitgud-ssh: ${PAYLOAD}" >&2
exit 1
fi
exec "$GIT_CMD" "$PAYLOAD"
1.8 KiB · text
5af55d9