func (ci *ConnInfo) serveChans(conn ssh.Conn, chans <-chan ssh.NewChannel) (err error) { defer ci.wg.Done() defer conn.Close() log.Debug("chans begin.") for newChan := range chans { chi := CreateChanInfo(ci) err = chi.Serve(conn, newChan) if err != nil { log.Error("%s", err.Error()) } } log.Debug("chans ends.") return }
func (ci *ConnInfo) serveReq(conn ssh.Conn, req *ssh.Request) (err error) { r, b, err := conn.SendRequest(req.Type, req.WantReply, req.Payload) if err != nil { log.Error("%s", err.Error()) req.Reply(false, nil) return err } log.Debug("send req ok: %s(result: %t)(payload: %d)", req.Type, r, len(b)) err = req.Reply(r, b) if err != nil { return err } log.Debug("reply req ok: %s(result: %t)", req.Type, r) return }
func (chi *ChanInfo) Serve(conn ssh.Conn, newChan ssh.NewChannel) (err error) { log.Info("new channel: %s (len: %d)", newChan.ChannelType(), len(newChan.ExtraData())) err = chi.onType(newChan.ChannelType(), newChan.ExtraData()) if err != nil { newChan.Reject(ssh.ResourceShortage, err.Error()) log.Error("reject channel: %s", err.Error()) return } chout, outreqs, err := conn.OpenChannel( newChan.ChannelType(), newChan.ExtraData()) if err != nil { newChan.Reject(ssh.UnknownChannelType, err.Error()) log.Error("reject channel: %s", err.Error()) return } log.Debug("open channel ok.") chin, inreqs, err := newChan.Accept() if err != nil { log.Error("could not accept channel.") return } log.Debug("accept channel ok.") go chi.serveReqs(chin, outreqs) go chi.serveReqs(chout, inreqs) _, ok := <-chi.ch if !ok { return } switch chi.Type { case "local", "remote": go MultiCopyClose(chin, chout, &DebugStream{"out"}) go MultiCopyClose(chout, chin, &DebugStream{"in"}) case "sshagent": go MultiCopyClose(chin, chout, &DebugStream{"out"}) go MultiCopyClose(chout, chin, &DebugStream{"in"}) case "shell": l, err := chi.prepareFile("") if err != nil { return err } go MultiCopyClose(chin, chout, l.CreateSubLogger(byte(0x01))) go MultiCopyClose(chout, chin, l.CreateSubLogger(byte(0x02))) case "exec": l, err := chi.prepareFile(strings.Join(chi.ExecCmds, "\r")) if err != nil { return err } go MultiCopyClose(chin, chout, l.CreateSubLogger(byte(0x01))) go MultiCopyClose(chout, chin, l.CreateSubLogger(byte(0x02))) case "scpto": go MultiCopyClose(chin, chout, CreateScpStream(chi)) go MultiCopyClose(chout, chin) case "scpfrom": go MultiCopyClose(chin, chout) go MultiCopyClose(chout, chin, CreateScpStream(chi)) default: log.Warning("redirect before setup") chin.Close() chout.Close() } return }