diff options
author | Runxi Yu <me@runxiyu.org> | 2025-02-17 21:57:09 +0800 |
---|---|---|
committer | Runxi Yu <me@runxiyu.org> | 2025-02-17 21:57:09 +0800 |
commit | eb1883a8e6241bf811de13a978ebb6af79210967 (patch) | |
tree | 190197e8eee3176d2677c82ac2e470aa6141f619 /ssh_handle_receive_pack.go | |
parent | go.mod: Bump lindenii-common (cmap split into ComparableMap and Map) (diff) | |
download | forge-eb1883a8e6241bf811de13a978ebb6af79210967.tar.gz forge-eb1883a8e6241bf811de13a978ebb6af79210967.tar.zst forge-eb1883a8e6241bf811de13a978ebb6af79210967.zip |
hooks, etc.: Authenticate hooks, and handle them in the spawning thread
Diffstat (limited to 'ssh_handle_receive_pack.go')
-rw-r--r-- | ssh_handle_receive_pack.go | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/ssh_handle_receive_pack.go b/ssh_handle_receive_pack.go index 58f99da..214fa2a 100644 --- a/ssh_handle_receive_pack.go +++ b/ssh_handle_receive_pack.go @@ -1,16 +1,27 @@ package main import ( + "crypto/rand" "errors" "fmt" + "net" "os" "os/exec" glider_ssh "github.com/gliderlabs/ssh" + "go.lindenii.runxiyu.org/lindenii-common/cmap" ) var err_unauthorized_push = errors.New("You are not authorized to push to this repository") +type hooks_cookie_deployer_return struct { + args []string + callback chan struct{} + conn net.Conn +} + +var hooks_cookie_deployer = cmap.ComparableMap[string, chan hooks_cookie_deployer_return]{} + func ssh_handle_receive_pack(session glider_ssh.Session, pubkey string, repo_identifier string) (err error) { repo_path, access, err := get_repo_path_perms_from_ssh_path_pubkey(session.Context(), repo_identifier, pubkey) if err != nil { @@ -20,8 +31,20 @@ func ssh_handle_receive_pack(session glider_ssh.Session, pubkey string, repo_ide return err_unauthorized_push } + cookie, err := random_urlsafe_string(16) + if err != nil { + fmt.Fprintln(session.Stderr(), "Error while generating cookie:", err) + } + + c := make(chan hooks_cookie_deployer_return) + hooks_cookie_deployer.Store(cookie, c) + defer hooks_cookie_deployer.Delete(cookie) + proc := exec.CommandContext(session.Context(), "git-receive-pack", repo_path) - proc.Env = append(os.Environ(), "LINDENII_FORGE_HOOKS_SOCKET_PATH="+config.Hooks.Socket) + proc.Env = append(os.Environ(), + "LINDENII_FORGE_HOOKS_SOCKET_PATH="+config.Hooks.Socket, + "LINDENII_FORGE_HOOKS_COOKIE="+cookie, + ) proc.Stdin = session proc.Stdout = session proc.Stderr = session.Stderr() @@ -32,6 +55,12 @@ func ssh_handle_receive_pack(session glider_ssh.Session, pubkey string, repo_ide return err } + deployer := <-c + + deployer.conn.Write([]byte{1}) + + deployer.callback <- struct{}{} + err = proc.Wait() if exitError, ok := err.(*exec.ExitError); ok { fmt.Fprintln(session.Stderr(), "Process exited with error", exitError.ExitCode()) @@ -41,3 +70,9 @@ func ssh_handle_receive_pack(session glider_ssh.Session, pubkey string, repo_ide return err } + +func random_string(sz int) (string, error) { + r := make([]byte, sz) + _, err := rand.Read(r) + return string(r), err +} |