aboutsummaryrefslogtreecommitdiff
path: root/ssh.go
diff options
context:
space:
mode:
authorRunxi Yu <me@runxiyu.org>2025-02-12 17:08:27 +0800
committerRunxi Yu <me@runxiyu.org>2025-02-12 17:08:27 +0800
commit78ef3b19d40aa6f63412ba961ab5c8bf0939237e (patch)
treed7758dc2071a8cedf02eeba9d731af4ea8ad5c3b /ssh.go
parentrouter.go: Fix out-of-bounds read on /: (diff)
downloadforge-78ef3b19d40aa6f63412ba961ab5c8bf0939237e.tar.gz
forge-78ef3b19d40aa6f63412ba961ab5c8bf0939237e.tar.zst
forge-78ef3b19d40aa6f63412ba961ab5c8bf0939237e.zip
ssh.go: Add anonymous SSH cloning
Diffstat (limited to 'ssh.go')
-rw-r--r--ssh.go82
1 files changed, 82 insertions, 0 deletions
diff --git a/ssh.go b/ssh.go
new file mode 100644
index 0000000..e1b9ff1
--- /dev/null
+++ b/ssh.go
@@ -0,0 +1,82 @@
+package main
+
+import (
+ "fmt"
+ "net"
+ "os"
+ "os/exec"
+
+ glider_ssh "github.com/gliderlabs/ssh"
+ "go.lindenii.runxiyu.org/lindenii-common/clog"
+ go_ssh "golang.org/x/crypto/ssh"
+)
+
+func serve_ssh() error {
+ hostKeyBytes, err := os.ReadFile(config.SSH.Key)
+ if err != nil {
+ return err
+ }
+
+ hostKey, err := go_ssh.ParsePrivateKey(hostKeyBytes)
+ if err != nil {
+ return err
+ }
+
+ server := &glider_ssh.Server{
+ Handler: func(session glider_ssh.Session) {
+ client_public_key := session.PublicKey()
+ var client_public_key_string string
+ if client_public_key != nil {
+ client_public_key_string = string(go_ssh.MarshalAuthorizedKey(client_public_key))
+ }
+ _ = client_public_key_string
+
+ cmd := session.Command()
+
+ if len(cmd) < 2 {
+ fmt.Fprintln(session.Stderr(), "Insufficient arguments")
+ return
+ }
+
+ if cmd[0] != "git-upload-pack" {
+ fmt.Fprintln(session.Stderr(), "Unsupported command")
+ return
+ }
+
+ proc := exec.CommandContext(session.Context(), cmd[0], "/home/runxiyu/git/forge.git")
+ proc.Stdin = session
+ proc.Stdout = session
+ proc.Stderr = session.Stderr()
+
+ err := proc.Start()
+ if err != nil {
+ fmt.Fprintln(session.Stderr(), "Error while starting process:", err)
+ return
+ }
+ err = proc.Wait()
+ if exitError, ok := err.(*exec.ExitError); ok {
+ fmt.Fprintln(session.Stderr(), "Process exited with error", exitError.ExitCode())
+ } else if err != nil {
+ fmt.Fprintln(session.Stderr(), "Error while waiting for process:", err)
+ }
+ },
+ PublicKeyHandler: func(ctx glider_ssh.Context, key glider_ssh.PublicKey) bool { return true },
+ KeyboardInteractiveHandler: func(ctx glider_ssh.Context, challenge go_ssh.KeyboardInteractiveChallenge) bool { return true },
+ }
+
+ server.AddHostKey(hostKey)
+
+ listener, err := net.Listen("tcp", ":2222")
+ if err != nil {
+ return err
+ }
+
+ go func() {
+ err = server.Serve(listener)
+ if err != nil {
+ clog.Fatal(1, "Serving SSH: "+err.Error())
+ }
+ }()
+
+ return nil
+}