From f3cbd9012af27bec597c82f20150ee525b080d24 Mon Sep 17 00:00:00 2001
From: Erik Brakkee <erik@brakkee.org>
Date: Sat, 20 Jul 2024 10:43:38 +0200
Subject: [PATCH] First agent version, passing in external listener fo ssh so
 it can be used later with yamux as well.

---
 cmd/agent/agent.go | 102 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)
 create mode 100755 cmd/agent/agent.go

diff --git a/cmd/agent/agent.go b/cmd/agent/agent.go
new file mode 100755
index 0000000..cd00d59
--- /dev/null
+++ b/cmd/agent/agent.go
@@ -0,0 +1,102 @@
+package main
+
+import (
+	"fmt"
+	"io"
+	"log"
+	"net"
+	"os"
+	"os/exec"
+	"syscall"
+	"unsafe"
+
+	"github.com/creack/pty"
+	"github.com/gliderlabs/ssh"
+	"github.com/pkg/sftp"
+)
+
+func SftpHandler(sess ssh.Session) {
+	debugStream := io.Discard
+	serverOptions := []sftp.ServerOption{
+		sftp.WithDebug(debugStream),
+	}
+	server, err := sftp.NewServer(
+		sess,
+		serverOptions...,
+	)
+	if err != nil {
+		log.Printf("sftp tcpserver init error: %s\n", err)
+		return
+	}F
+	if err := server.Serve(); err == io.EOF {
+		server.Close()
+		fmt.Println("sftp client exited session.")
+	} else if err != nil {
+		fmt.Println("sftp tcpserver completed with error:", err)
+	}
+}
+
+func passwordAuth(ctx ssh.Context, password string) bool {
+	// Replace with your own logic to validate username and password
+	return ctx.User() == "abc" && password == "123"
+}
+
+func setWinsize(f *os.File, w, h int) {
+	syscall.Syscall(syscall.SYS_IOCTL, f.Fd(), uintptr(syscall.TIOCSWINSZ),
+		uintptr(unsafe.Pointer(&struct{ h, w, x, y uint16 }{uint16(h), uint16(w), 0, 0})))
+}
+
+func main() {
+	ssh.Handle(func(s ssh.Session) {
+		cmd := exec.Command("bash")
+		ptyReq, winCh, isPty := s.Pty()
+		if isPty {
+			cmd.Env = append(os.Environ(), fmt.Sprintf("TERM=%s", ptyReq.Term))
+			f, err := pty.Start(cmd)
+			if err != nil {
+				panic(err)
+			}
+			go func() {
+				for win := range winCh {
+					setWinsize(f, win.Width, win.Height)
+				}
+			}()
+			go func() {
+				io.Copy(f, s) // stdin
+			}()
+			io.Copy(s, f) // stdout
+			cmd.Wait()
+		} else {
+			io.WriteString(s, "No PTY requested.\n")
+			s.Exit(1)
+		}
+	})
+
+	log.Println("starting ssh tcpserver on port 2222...")
+	server := ssh.Server{
+		Addr:            ":2222",
+		PasswordHandler: passwordAuth,
+		SubsystemHandlers: map[string]ssh.SubsystemHandler{
+			"sftp": SftpHandler,
+		},
+	}
+
+	listener, err := net.Listen("tcp", ":2222")
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	server.Serve(listener)
+
+	//for {
+	//	conn, err := listener.Accept()
+	//	if err != nil {
+	//		log.Println("Failed to accept connection:", err)
+	//		continue
+	//	}
+	//	log.Println("Got connection")
+	//	go server.HandleConn(conn)
+	//}
+
+	//log.Fatal(server.ListenAndServe())
+}