| 31 | } |
| 32 | |
| 33 | func handleServerConn(keyID string, chans <-chan ssh.NewChannel) { |
| 34 | for newChan := range chans { |
| 35 | if newChan.ChannelType() != "session" { |
| 36 | _ = newChan.Reject(ssh.UnknownChannelType, "unknown channel type") |
| 37 | continue |
| 38 | } |
| 39 | |
| 40 | ch, reqs, err := newChan.Accept() |
| 41 | if err != nil { |
| 42 | log.Error("Error accepting channel: %v", err) |
| 43 | continue |
| 44 | } |
| 45 | |
| 46 | go func(in <-chan *ssh.Request) { |
| 47 | defer func() { |
| 48 | _ = ch.Close() |
| 49 | }() |
| 50 | for req := range in { |
| 51 | payload := cleanCommand(string(req.Payload)) |
| 52 | switch req.Type { |
| 53 | case "env": |
| 54 | // We only need to accept the request and do nothing since whatever environment |
| 55 | // variables being set here won't be used in subsequent commands anyway. |
| 56 | |
| 57 | case "exec": |
| 58 | cmdName := strings.TrimLeft(payload, "'()") |
| 59 | log.Trace("SSH: Payload: %v", cmdName) |
| 60 | |
| 61 | args := []string{"serv", "key-" + keyID, "--config=" + conf.CustomConf} |
| 62 | log.Trace("SSH: Arguments: %v", args) |
| 63 | cmd := exec.Command(conf.AppPath(), args...) |
| 64 | cmd.Env = append(os.Environ(), "SSH_ORIGINAL_COMMAND="+cmdName) |
| 65 | |
| 66 | stdout, err := cmd.StdoutPipe() |
| 67 | if err != nil { |
| 68 | log.Error("SSH: StdoutPipe: %v", err) |
| 69 | return |
| 70 | } |
| 71 | stderr, err := cmd.StderrPipe() |
| 72 | if err != nil { |
| 73 | log.Error("SSH: StderrPipe: %v", err) |
| 74 | return |
| 75 | } |
| 76 | input, err := cmd.StdinPipe() |
| 77 | if err != nil { |
| 78 | log.Error("SSH: StdinPipe: %v", err) |
| 79 | return |
| 80 | } |
| 81 | |
| 82 | // FIXME: check timeout |
| 83 | if err = cmd.Start(); err != nil { |
| 84 | log.Error("SSH: Start: %v", err) |
| 85 | return |
| 86 | } |
| 87 | |
| 88 | _ = req.Reply(true, nil) |
| 89 | go func() { |
| 90 | _, _ = io.Copy(input, ch) |