1.8 KiB · text History cfa4a8b
#!/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"