diff --git a/examples/forward/main.go b/examples/forward/main.go new file mode 100644 index 00000000..a40196c1 --- /dev/null +++ b/examples/forward/main.go @@ -0,0 +1,71 @@ +package main + +import ( + "context" + "errors" + "fmt" + "os" + "os/signal" + "syscall" + "time" + + "github.com/charmbracelet/log" + "github.com/charmbracelet/ssh" + "github.com/charmbracelet/wish" + "github.com/charmbracelet/wish/logging" +) + +const ( + host = "localhost" + port = 23234 +) + +// example usage: ssh -N -R 23236:localhost:23235 -p 23234 localhost +func main() { + forwardHandler := &ssh.ForwardedTCPHandler{} + s, err := wish.NewServer( + wish.WithAddress(fmt.Sprintf("%s:%d", host, port)), + wish.WithHostKeyPath(".ssh/term_info_ed25519"), + func(s *ssh.Server) error { + s.ReversePortForwardingCallback = func(_ ssh.Context, bindHost string, bindPort uint32) bool { + log.Info("reverse port forwarding allowed", "host", bindHost, "port", bindPort) + return true + } + s.RequestHandlers = map[string]ssh.RequestHandler{ + "tcpip-forward": forwardHandler.HandleSSHRequest, + "cancel-tcpip-forward": forwardHandler.HandleSSHRequest, + } + return nil + }, + wish.WithMiddleware( + func(h ssh.Handler) ssh.Handler { + return func(s ssh.Session) { + wish.Println(s, "remote port forwarding available") + h(s) + } + }, + logging.Middleware(), + ), + ) + if err != nil { + log.Error("could not start server", "error", err) + } + + done := make(chan os.Signal, 1) + signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + log.Info("Starting SSH server", "host", host, "port", port) + go func() { + if err = s.ListenAndServe(); err != nil && !errors.Is(err, ssh.ErrServerClosed) { + log.Error("could not start server", "error", err) + done <- nil + } + }() + + <-done + log.Info("Stopping SSH server") + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + defer func() { cancel() }() + if err := s.Shutdown(ctx); err != nil && !errors.Is(err, ssh.ErrServerClosed) { + log.Error("could not stop server", "error", err) + } +} diff --git a/examples/go.sum b/examples/go.sum index 4ded81db..426a0373 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -24,6 +24,7 @@ github.com/charmbracelet/lipgloss v0.9.1/go.mod h1:1mPmG4cxScwUQALAAnacHaigiiHB9 github.com/charmbracelet/log v0.3.1 h1:TjuY4OBNbxmHWSwO3tosgqs5I3biyY8sQPny/eCMTYw= github.com/charmbracelet/log v0.3.1/go.mod h1:OR4E1hutLsax3ZKpXbgUqPtTjQfrh1pG3zwHGWuuq8g= github.com/charmbracelet/ssh v0.0.0-20240104172912-e11ae277b249 h1:M1Q/UIbi9Cfla0HK3A9puhQhb8ZPkA5HQxeSYcVrGpo= +github.com/charmbracelet/ssh v0.0.0-20240104172912-e11ae277b249/go.mod h1:A1H384KV/cJcSKofWjdSIb+dfbikXiW6449EluL3qJI= github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY=