1package ssh
2
3import (
4 "fmt"
5 "io"
6
7 "github.com/charmbracelet/log"
8 "github.com/charmbracelet/soft-serve/pkg/shell"
9 "github.com/charmbracelet/ssh"
10 "github.com/charmbracelet/wish"
11)
12
13// ShellMiddleware is a middleware for the SSH shell.
14func ShellMiddleware(sh ssh.Handler) ssh.Handler {
15 return func(s ssh.Session) {
16 ctx := s.Context()
17 logger := log.FromContext(ctx).WithPrefix("ssh")
18 envs := &sessionEnv{s}
19
20 ppty, _, isInteractive := s.Pty()
21
22 var (
23 in io.Reader = s
24 out io.Writer = s
25 er io.Writer = s.Stderr()
26 err error
27 )
28
29 if isInteractive {
30 in, out, er, err = ptyNew(ppty.Pty)
31 if err != nil {
32 logger.Errorf("could not create pty: %v", err)
33 // TODO: replace this err with a declared error
34 wish.Fatalln(s, fmt.Errorf("internal server error"))
35 return
36 }
37 }
38
39 args := s.Command()
40 if len(args) == 0 {
41 // XXX: args cannot be nil, otherwise cobra will use os.Args[1:]
42 args = []string{}
43 }
44
45 cmd := shell.Command(ctx, envs, isInteractive)
46 cmd.SetArgs(args)
47 cmd.SetIn(in)
48 cmd.SetOut(out)
49 cmd.SetErr(er)
50 cmd.SetContext(ctx)
51
52 if err := cmd.ExecuteContext(ctx); err != nil {
53 wish.Fatalln(s, err)
54 return
55 }
56
57 sh(s)
58 }
59}