func handleChannel(s *Stream, ch ssh.Channel, reqs <-chan *ssh.Request, handle func(*Stream)) { // handle requests receive for this Channel go func(in <-chan *ssh.Request) { for req := range in { logrus.Debugln("AdminTool -> Request of type:", req.Type, "len:", len(req.Type)) logrus.Debugln("AdminTool -> Request payload:", string(req.Payload), "len:", len(req.Payload)) if req.WantReply { req.Reply(false, nil) } } logrus.Debugln("AdminTool -> End of request GO chan") }(reqs) // read data from channel go func() { for { buffer := make([]byte, 64) n, err := ch.Read(buffer) if err != nil { if err.Error() == "EOF" { handleData(s, []byte{}, true) // all data received: handle Stream message handle(s) break } else { logrus.Fatalln("failed to read channel : " + err.Error()) } } handleData(s, buffer[:n], false) } }() }
func (s *scpRequest) ParseSCPRequest(channel ssh.Channel, req *ssh.Request) error { var err error // Parse the payload received from the scp client if s.original, err = parsePayload(req.Payload); err != nil { return err } log.Println("being sent file:", s.original) // Acknowledge payload. if _, err = channel.Write(zeroByte); err != nil { return errors.Wrap(err, "failed to write") } // Receive SCP Header scpHeader := make([]byte, 2048) // size of buf in openssh if _, err = channel.Read(scpHeader); err != nil { return errors.Wrap(err, "failed to retrieve header") } if _, s.size, _, err = parseHeader(scpHeader); err != nil { return errors.Wrap(err, "failed to parse scp header") } // Acknowledge We have received the SCP Header if _, err = channel.Write(zeroByte); err != nil { return errors.Wrap(err, "failed to reply to scp header") } return nil }
func HandleTcpReading(channel ssh.Channel, term *terminal.Terminal, perms *ssh.Permissions) { defer channel.Close() //http := map[string]string{} for { // read up to 1MB of data b := make([]byte, 1024*1024) _, err := channel.Read(b) if err != nil { if err.Error() == "EOF" { return } } read := bufio.NewReader(strings.NewReader(string(b))) toReq, err := http.ReadRequest(read) // TODO: https will panic atm - need to figure this out if err != nil { log.Println("Error parsing request: ", err) return } err = toReq.ParseForm() if err != nil { log.Println("Error parsing form: ", err) return } url := fmt.Sprintf("%s%s", toReq.Host, toReq.URL) httpReq := &HttpRequest{ Headers: toReq.Header, URL: url, FormData: toReq.Form, Method: toReq.Method, Guid: perms.Extensions["guid"], Hostname: toReq.Host, } client := &http.Client{} resp, err := client.Get(fmt.Sprintf("http://%s", url)) if err != nil { log.Fatalf("Body read error: %s", err) } defer resp.Body.Close() body, err2 := ioutil.ReadAll(resp.Body) if err2 != nil { log.Fatalf("Body read error: %s", err2) } httpReq.Response = string(body) httpReq.Save() log.Printf("[ http://%s ] %s", url, body) channel.Write(body) // make the http request //if resp, ok := httpHandler[url]; ok { // channel.Write(resp) //} else { // channel.Write([]byte("45.4.5.6")) //} channel.Close() } }
func (e *EchoHandler) Handle(parentTomb tomb.Tomb, sshConn *ssh.ServerConn, channel ssh.Channel, requests <-chan *ssh.Request) error { defer channel.Close() // Create tomb for terminal goroutines var t tomb.Tomb type msg struct { length uint32 data []byte } in := make(chan msg) defer close(in) // Sessions have out-of-band requests such as "shell", // "pty-req" and "env". Here we handle only the // "shell" request. t.Go(func() error { var buffer bytes.Buffer // Read channel t.Go(func() error { length := make([]byte, 4) for { n, err := channel.Read(length) if err != nil { return err } else if n != 4 { return errors.New("Invalid message length") } // Decode length l, err := xbinary.LittleEndian.Uint32(length, 0) if err != nil { return err } // Read data n64, err := buffer.ReadFrom(io.LimitReader(channel, int64(l))) if err != nil { return err } else if n64 != int64(l) { return errors.New("error: reading message") } select { case <-parentTomb.Dying(): return nil case <-t.Dying(): return nil case in <- msg{l, buffer.Bytes()}: } } }) length := make([]byte, 4) OUTER: for { select { case <-parentTomb.Dying(): t.Kill(nil) break OUTER case m := <-in: if m.length == 0 { return nil } // Encode length _, err := xbinary.LittleEndian.PutUint32(length, 0, m.length) if err != nil { t.Kill(err) return nil } // Write echo response channel.Write(length) channel.Write(m.data) } } return nil }) return t.Wait() }