コード例 #1
0
ファイル: server.go プロジェクト: robinmonjo/dockpack
func (s *server) handleChanReq(chanReq ssh.NewChannel, authInfo map[string]string) {
	if chanReq.ChannelType() != "session" {
		chanReq.Reject(ssh.Prohibited, "channel type is not a session")
		return
	}

	ch, reqs, err := chanReq.Accept()
	if err != nil {
		log.Errorf("fail to accept channel request %v", err)
		return
	}

	for {
		req := <-reqs

		switch req.Type {
		case "env":
		case "exec":
			s.handleExec(ch, req, authInfo)
			return
		default:
			ch.Write([]byte(fmt.Sprintf("request type %q not allowed\r\n", req.Type)))
			ch.Close()
			return
		}
	}
}
コード例 #2
0
ファイル: channel.go プロジェクト: magisterquis/sshhipot
/* logChannel returns a logger which can be used to log channel activities to a
file in the directory ldir.  The logger as well as the filename are
returned. */
func logChannel(
	ldir string,
	nc ssh.NewChannel,
) (*log.Logger, *os.File, string, error) {
	/* Log file is named after the channel time and type */
	logName := filepath.Join(
		ldir,
		time.Now().Format(LOGFORMAT)+"-"+nc.ChannelType(),
	)
	/* Open the file */
	lf, err := os.OpenFile(
		logName,
		os.O_WRONLY|os.O_APPEND|os.O_CREATE|os.O_EXCL,
		0600,
	)
	if nil != err {
		return nil, nil, "", err
	}
	return log.New(
		//lf,
		io.MultiWriter(lf, os.Stderr), /* DEBUG */
		"",
		log.LstdFlags|log.Lmicroseconds,
	), lf, logName, nil
}
コード例 #3
0
ファイル: server.go プロジェクト: Lanzafame/butter
func handleChannel(chanRequest ssh.NewChannel) {
	handle, err := NewHandle(chanRequest.ChannelType())
	if err != nil {
		config.Log.Debug("wrong handler %v", err)
		chanRequest.Reject(ssh.UnknownChannelType, err.Error())
		return
	}

	ch, reqs, err := chanRequest.Accept()
	if err != nil {
		config.Log.Debug("fail to accept channel request %v", err)
		return
	}

	defer ch.Close()

	for req := range reqs {
		done, err := handle.Request(ch, req)
		if err != nil {
			config.Log.Debug("request errored out %v", err)
			_, err := ch.Write([]byte(fmt.Sprintf("%v\r\n", err)))
			if err != nil {
				config.Log.Debug(err.Error())
			}
		}
		if done {
			return
		}
	}
}
コード例 #4
0
ファイル: client.go プロジェクト: moul/ssh2docker
// HandleChannel handles one SSH channel
func (c *Client) HandleChannel(newChannel ssh.NewChannel) error {
	if newChannel.ChannelType() != "session" {
		log.Debugf("Unknown channel type: %s", newChannel.ChannelType())
		newChannel.Reject(ssh.UnknownChannelType, "unknown channel type")
		return nil
	}

	channel, requests, err := newChannel.Accept()
	if err != nil {
		log.Errorf("newChannel.Accept failed: %v", err)
		return err
	}
	c.ChannelIdx++
	log.Debugf("HandleChannel.channel (client=%d channel=%d)", c.Idx, c.ChannelIdx)

	log.Debug("Creating pty...")
	c.Pty, c.Tty, err = pty.Open()
	if err != nil {
		log.Errorf("pty.Open failed: %v", err)
		return nil
	}

	c.HandleChannelRequests(channel, requests)

	return nil
}
コード例 #5
0
ファイル: session.go プロジェクト: ziyan/gatewaysshd
func (s *Session) HandleDirectChannel(newChannel ssh.NewChannel) (bool, ssh.RejectionReason) {

	data, err := UnmarshalTunnelData(newChannel.ExtraData())
	if err != nil {
		return false, ssh.UnknownChannelType
	}

	// look up session by name
	session, host, port := s.Gateway().LookupSessionService(data.Host, uint16(data.Port))
	if session == nil {
		return false, ssh.ConnectionFailed
	}

	// found the service, attempt to open a channel
	data.Host = host
	data.Port = uint32(port)

	c2, err := session.OpenChannel("forwarded-tcpip", MarshalTunnelData(data))
	if err != nil {
		return false, ssh.ConnectionFailed
	}
	defer func() {
		if c2 != nil {
			c2.Close()
		}
	}()

	// accept the channel
	channel, requests, err := newChannel.Accept()
	if err != nil {
		return false, ssh.ResourceShortage
	}

	// cannot return false from this point on
	// also need to accepted close the channel
	defer func() {
		if channel != nil {
			if err := channel.Close(); err != nil {
				glog.Warningf("failed to close accepted channel: %s", err)
			}
		}
	}()

	c, err := NewChannel(s, channel, newChannel.ChannelType(), newChannel.ExtraData())
	if err != nil {
		glog.Errorf("failed to create accepted channel: %s", err)
		return true, 0
	}
	s.AddChannel(c)

	// no failure
	go c.HandleRequests(requests)
	go c.HandleTunnelChannel(c2)

	// do not close channel on exit
	channel = nil
	c2 = nil
	return true, 0
}
コード例 #6
0
ファイル: ssh.go プロジェクト: cdshann/minimega
func sshHandleChannel(conn net.Conn, newChannel ssh.NewChannel) {
	// Channels have a type, depending on the application level protocol
	// intended. In the case of a shell, the type is "session" and ServerShell
	// may be used to present a simple terminal interface.
	if newChannel.ChannelType() != "session" {
		newChannel.Reject(ssh.UnknownChannelType, "unknown channel type")
		return
	}
	channel, requests, err := newChannel.Accept()
	if err != nil {
		log.Errorln(err)
		return
	}

	// Sessions have out-of-band requests such as "shell", "pty-req" and "env".
	// Here we handle only the "shell" request.
	go func(in <-chan *ssh.Request) {
		for req := range in {
			ok := false
			switch req.Type {
			case "shell":
				ok = true
				if len(req.Payload) > 0 {
					// We don't accept any commands, only the default shell.
					ok = false
				}
			case "pty-req":
				ok = true
			}
			req.Reply(ok, nil)
		}
	}(requests)

	term := terminal.NewTerminal(channel, "> ")

	go func() {
		defer channel.Close()

		for {
			line, err := term.ReadLine()
			start := time.Now().UnixNano()
			if err != nil {
				if err != io.EOF {
					log.Errorln(err)
				}
				return
			}
			sshReportChan <- uint64(len(line))
			// just echo the message
			log.Debugln("ssh received: ", line)
			term.Write([]byte(line))
			term.Write([]byte{'\r', '\n'})

			stop := time.Now().UnixNano()
			log.Info("ssh %v %vns", conn.RemoteAddr(), uint64(stop-start))
		}
	}()
}
コード例 #7
0
func (sshClient *sshClient) rejectNewChannel(newChannel ssh.NewChannel, reason ssh.RejectionReason, message string) {
	// TODO: log more details?
	log.WithContextFields(
		LogFields{
			"channelType":   newChannel.ChannelType(),
			"rejectMessage": message,
			"rejectReason":  reason,
		}).Warning("reject new channel")
	newChannel.Reject(reason, message)
}
コード例 #8
0
ファイル: server.go プロジェクト: boazy/sshmux
func (s *Server) HandleNewChannel(session *Session, newChannel ssh.NewChannel) {
	log.Printf("New Channel: %s", newChannel)
	switch newChannel.ChannelType() {
	case "direct-tcpip":
		s.ChannelForward(session, newChannel)
	default:
		log.Printf("Unknown SSH channel type: %s", newChannel.ChannelType())
		newChannel.Reject(ssh.UnknownChannelType, "connection flow not supported by sshmux")
	}
}
コード例 #9
0
ファイル: sshserver.go プロジェクト: d-dorazio/gork
func (server *SshServer) handleChannel(user string, newChannel ssh.NewChannel) {
	if t := newChannel.ChannelType(); t != "session" {
		newChannel.Reject(ssh.UnknownChannelType, fmt.Sprintf("unknown channel type: %s", t))
		return
	}

	connection, requests, err := newChannel.Accept()
	if err != nil {
		fmt.Printf("Could not accept channel (%s)", err)
		return
	}
	defer connection.Close()

	logfile, err := os.Create(fmt.Sprintf("%s_%s", user, storyLogFilename(server.story)))
	if err != nil {
		panic(err)
	}
	defer logfile.Close()

	logger := log.New(logfile, "", log.LstdFlags)

	terminal := terminal.NewTerminal(connection, "")
	zsshterm := &gork.ZSshTerminal{Term: terminal}

	zm, err := gork.NewZMachine(server.mem, server.header, zsshterm, logger)
	if err != nil {
		fmt.Println(err)
		return
	}

	go func() {
		for req := range requests {
			switch req.Type {
			case "shell":
				if len(req.Payload) == 0 {
					req.Reply(true, nil)
				}
			case "pty-req":
				termLen := req.Payload[3]
				w, h := parseDims(req.Payload[termLen+4:])
				terminal.SetSize(w, h)
			case "window-change":
				w, h := parseDims(req.Payload)
				terminal.SetSize(w, h)
			}
		}
	}()

	defer func() {
		recover()
	}()

	zm.InterpretAll()

}
コード例 #10
0
ファイル: auc-console.go プロジェクト: gourytch/gowowuction
func handleChannel(c ssh.NewChannel) {
	if t := c.ChannelType(); t != "session" {
		log.Println("rejected unknown channel type:", t)
		c.Reject(ssh.UnknownChannelType, "unknown channel type")
	}
	connection, requests, err := c.Accept()
	if err != nil {
		log.Println("channel not accepted:", err)
		return
	}
	bash := exec.Command("/bin/bash")
	close := func() {
		connection.Close()
		_, err := bash.Process.Wait()
		if err != nil {
			log.Println("bash not exited:", err)
		}
		log.Println("session closed")
	}
	bashf, err := pty.Start(bash)
	if err != nil {
		log.Println("pty not started:", err)
		close()
		return
	}
	var once sync.Once
	go func() {
		io.Copy(connection, bashf)
		once.Do(close)
	}()
	go func() {
		io.Copy(bashf, connection)
		once.Do(close)
	}()
	go func() {
		for req := range requests {
			log.Println("got request:", req.Type, "want reply:", req.WantReply)
			switch req.Type {
			case "shell":
				if len(req.Payload) == 0 {
					req.Reply(true, nil)
				}
			case "pty-req":
				termLen := req.Payload[3]
				w, h := parseDims(req.Payload[termLen+4:])
				SetWinsize(bashf.Fd(), w, h)
				req.Reply(true, nil)
			case "window-change":
				w, h := parseDims(req.Payload)
				SetWinsize(bashf.Fd(), w, h)
			}
		}
	}()
}
コード例 #11
0
ファイル: dispatcher.go プロジェクト: blacklabeldata/sshh
func (u *UrlDispatcher) Dispatch(c context.Context, conn *ssh.ServerConn, ch ssh.NewChannel) {
	defer conn.Close()

	// Get channel type
	chType := ch.ChannelType()

	// Parse channel URI
	uri, err := url.ParseRequestURI(chType)
	if err != nil {
		u.Logger.Warn("Error parsing channel type", "type", chType, "err", err)
		ch.Reject(InvalidChannelType, "invalid channel URI")
		return
	} else if reject(chType, uri, ch, u.Logger) {
		return
	}
	chType = uri.Path

	// Parse query params
	values, err := url.ParseQuery(uri.RawQuery)
	if err != nil {
		u.Logger.Warn("Error parsing query params", "values", values, "err", err)
		ch.Reject(InvalidQueryParams, "invalid query params in channel type")
		return
	}

	// Determine if channel is acceptable (has a registered handler)
	if !u.Router.HasRoute(chType) {
		u.Logger.Info("UnknownChannelType", "type", chType)
		ch.Reject(ssh.UnknownChannelType, chType)
		return
	}

	// Otherwise, accept the channel
	channel, requests, err := ch.Accept()
	if err != nil {
		u.Logger.Warn("Error creating channel", "type", chType, "err", err)
		ch.Reject(ChannelAcceptError, chType)
		return
	}

	// Handle the channel
	err = u.Router.Handle(&router.UrlContext{
		Path:     uri.Path,
		Context:  c,
		Values:   values,
		Channel:  channel,
		Requests: requests,
	})
	if err != nil {
		u.Logger.Warn("Error handling channel", "type", chType, "err", err)
		ch.Reject(ChannelHandleError, fmt.Sprintf("error handling channel: %s", err.Error()))
		return
	}
}
コード例 #12
0
func (s *sshServer) handleChannel(newChannel ssh.NewChannel) error {
	if newChannel.ChannelType() != "session" {
		newChannel.Reject(ssh.UnknownChannelType, "unknown channel type")
		return nil
	}

	channel, requests, err := newChannel.Accept()
	if err != nil {
		log.Println("newChannel accept failed: ", err)
		return nil
	}

	return s.handleRequests(channel, requests)
}
コード例 #13
0
ファイル: main.go プロジェクト: raumzeitlabor/rzl-repaircafe
func handleChanReq(chanReq ssh.NewChannel) {
	if chanReq.ChannelType() != "session" {
		chanReq.Reject(ssh.UnknownChannelType, "unknown channel type")
		return
	}

	channel, requests, err := chanReq.Accept()
	if err != nil {
		return
	}

	exitloop := false
	for {
		select {
		case req := <-requests:
			if req == nil {
				continue
			}
			if req.Type == "exec" {
				handleExec(channel, req)
				if req.WantReply {
					req.Reply(true, nil)
				}
				exitloop = true
			}
			req.Reply(false, nil)
		case <-time.After(3 * time.Second):
			log.Println("no exec chanreq received, time out")
			exitloop = true
			break
		}
		if exitloop {
			break
		}
	}

	/*
	   todo: return exit status:

	   byte      SSH_MSG_CHANNEL_REQUEST
	   uint32    recipient channel
	   string    "exit-status"
	   boolean   FALSE
	   uint32    exit_status
	*/
	channel.Close()
}
コード例 #14
0
func (svr *sshServer) handleChanReq(chanReq ssh.NewChannel) {
	fmt.Fprintf(sshServerDebugStream, "channel request: %v, extra: '%v'\n", chanReq.ChannelType(), hex.EncodeToString(chanReq.ExtraData()))
	switch chanReq.ChannelType() {
	case "session":
		if ch, reqs, err := chanReq.Accept(); err != nil {
			fmt.Fprintf(sshServerDebugStream, "fail to accept channel request: %v\n", err)
			chanReq.Reject(ssh.ResourceShortage, "channel accept failure")
		} else {
			chsvr := &sshSessionChannelServer{
				sshChannelServer: &sshChannelServer{svr, chanReq, ch, reqs},
				env:              append([]string{}, os.Environ()...),
			}
			chsvr.handle()
		}
	default:
		chanReq.Reject(ssh.UnknownChannelType, "channel type is not a session")
	}
}
コード例 #15
0
ファイル: sshd.go プロジェクト: bachue/pages
func (server *Server) handleChannel(newChannel ssh.NewChannel, conn *ssh.ServerConn) {
	channelType := newChannel.ChannelType()
	if channelType != "session" {
		newChannel.Reject(ssh.UnknownChannelType,
			fmt.Sprintf("Unknown SSH Channel Type: %s, only `session` is supported", channelType))
		server.Logger.Errorf("Rejected SSH Channel Request from %s due to unknown channel type: %s",
			conn.RemoteAddr().String(), newChannel.ChannelType())
		return
	}
	channel, requests, err := newChannel.Accept()
	if err != nil {
		newChannel.Reject(ssh.ConnectionFailed, "Failed to accept SSH Channel Request, developers are working on it.")
		server.Logger.Errorf("Rejected SSH Channel Request from %s due to accept request failure: %s",
			conn.RemoteAddr().String(), err)
		return
	}
	server.Logger.Debugf("Accepted new SSH Channel Request from %s", conn.RemoteAddr().String())

	server.handleRequest(channel, requests, conn)
}
コード例 #16
0
ファイル: session.go プロジェクト: ziyan/gatewaysshd
func (s *Session) HandleChannel(newChannel ssh.NewChannel) {
	glog.V(9).Infof("new channel: type = %s, data = %v", newChannel.ChannelType(), newChannel.ExtraData())

	ok := false
	rejection := ssh.UnknownChannelType

	switch newChannel.ChannelType() {
	case "session":
		ok, rejection = s.HandleSessionChannel(newChannel)
	case "direct-tcpip":
		ok, rejection = s.HandleDirectChannel(newChannel)
	}

	if !ok {
		// reject the channel
		if err := newChannel.Reject(rejection, ""); err != nil {
			glog.Warningf("failed to reject channel: %s", err)
		}
	}
}
コード例 #17
0
ファイル: server.go プロジェクト: psihodelik/go-ssh-examples
func handleChanReq(chanReq ssh.NewChannel) {
	if chanReq.ChannelType() != "session" {
		chanReq.Reject(ssh.Prohibited, "channel type is not a session")
		return
	}

	ch, reqs, err := chanReq.Accept()
	if err != nil {
		log.Println("fail to accept channel request", err)
		return
	}

	req := <-reqs
	if req.Type != "exec" {
		ch.Write([]byte("request type '" + req.Type + "' is not 'exec'\r\n"))
		ch.Close()
		return
	}

	handleExec(ch, req)
}
コード例 #18
0
ファイル: dispatcher.go プロジェクト: blacklabeldata/sshh
func (u *SimpleDispatcher) Dispatch(c context.Context, conn *ssh.ServerConn, ch ssh.NewChannel) {
	defer conn.Close()

	var ctx *Context
	if u.PanicHandler != nil {
		if rcv := recover(); rcv != nil {
			u.PanicHandler.Handle(ctx, rcv)
		}
	}

	// Get channel type
	chType := ch.ChannelType()

	handler, ok := u.Handlers[chType]
	if !ok {
		return
	}

	// Otherwise, accept the channel
	channel, requests, err := ch.Accept()
	if err != nil {
		u.Logger.Warn("Error creating channel", "type", chType, "err", err)
		ch.Reject(ChannelAcceptError, chType)
		return
	}

	// Handle the channel
	ctx = &Context{
		Context:  c,
		Channel:  channel,
		Requests: requests,
	}
	err = handler.Handle(ctx)
	if err != nil {
		u.Logger.Warn("Error handling channel", "type", chType, "err", err)
		ch.Reject(ChannelHandleError, fmt.Sprintf("error handling channel: %s", err.Error()))
		return
	}
}
コード例 #19
0
ファイル: main.go プロジェクト: smreed/test-ssh-server
func handleChannel(newChannel ssh.NewChannel) {
	// Since we're handling a shell, we expect a
	// channel type of "session". The also describes
	// "x11", "direct-tcpip" and "forwarded-tcpip"
	// channel types.
	if t := newChannel.ChannelType(); t != "session" {
		newChannel.Reject(ssh.UnknownChannelType, fmt.Sprintf("unknown channel type: %s", t))
		return
	}

	// At this point, we have the opportunity to reject the client's
	// request for another logical connection
	connection, _, err := newChannel.Accept()
	if err != nil {
		log.Printf("Could not accept channel (%s)", err)
		return
	}

	defer connection.Close()

	connection.Write([]byte("Hello!\n"))
}
コード例 #20
0
ファイル: ssh_server.go プロジェクト: pivotal-cf/cf-watch
func (s *SSHServer) handleChannel(newChannel ssh.NewChannel) {
	defer GinkgoRecover()

	Expect(newChannel.ChannelType()).To(Equal("session"))

	if s.RejectSession {
		Expect(newChannel.Reject(ssh.ConnectionFailed, "session rejected")).To(Succeed())
		return
	}

	channel, requests, err := newChannel.Accept()
	Expect(err).NotTo(HaveOccurred())

	go func() {
		defer GinkgoRecover()

		for request := range requests {
			switch request.Type {
			case "exec":
				payloadLen := binary.BigEndian.Uint32(request.Payload[:4])
				Expect(request.Payload).To(HaveLen(int(payloadLen) + 4))

				s.CommandChan <- string(request.Payload[4:])

				Expect(request.Reply(true, nil)).To(Succeed())

				_, err := channel.SendRequest("exit-status", false, []byte{0, 0, 0, s.CommandExitStatus})
				Expect(err).To(Succeed())

				channel.Close()
				break
			}
		}
	}()
	go func() {
		defer GinkgoRecover()
		io.Copy(s.Data, channel)
	}()
}
コード例 #21
0
ファイル: terminal.go プロジェクト: dream1986/ssh-chat
// Make new terminal from a session channel
func NewTerminal(conn *ssh.ServerConn, ch ssh.NewChannel) (*Terminal, error) {
	if ch.ChannelType() != "session" {
		return nil, errors.New("terminal requires session channel")
	}
	channel, requests, err := ch.Accept()
	if err != nil {
		return nil, err
	}
	term := Terminal{
		*terminal.NewTerminal(channel, "Connecting..."),
		sshConn{conn},
		channel,
	}

	go term.listen(requests)
	go func() {
		// FIXME: Is this necessary?
		conn.Wait()
		channel.Close()
	}()

	return &term, nil
}
コード例 #22
0
ファイル: session.go プロジェクト: ziyan/gatewaysshd
func (s *Session) HandleSessionChannel(newChannel ssh.NewChannel) (bool, ssh.RejectionReason) {
	if len(newChannel.ExtraData()) > 0 {
		// do not accept extra data in session channel request
		return false, ssh.Prohibited
	}

	// accept the channel
	channel, requests, err := newChannel.Accept()
	if err != nil {
		return false, ssh.ResourceShortage
	}

	// cannot return false from this point on
	// also need to accepted close the channel
	defer func() {
		if channel != nil {
			if err := channel.Close(); err != nil {
				glog.Warningf("failed to close accepted channel: %s", err)
			}
		}
	}()

	c, err := NewChannel(s, channel, newChannel.ChannelType(), newChannel.ExtraData())
	if err != nil {
		glog.Errorf("failed to create accepted channel: %s", err)
		return true, 0
	}
	s.AddChannel(c)

	// no failure
	go c.HandleRequests(requests)
	go c.HandleSessionChannel()

	// do not close channel on exit
	channel = nil
	return true, 0
}
コード例 #23
0
ファイル: scp.go プロジェクト: zqzca/back
func (s *Server) handleChannel(ch ssh.NewChannel) {
	id := rand.Int()
	s.Debug("Handling Channel", "id", id, "chan", ch.ChannelType())

	if ch.ChannelType() != "session" {
		s.Info("Received unknown channel type", "chan", ch.ChannelType())
		ch.Reject(ssh.UnknownChannelType, "unknown channel type")
		return
	}

	channel, requests, err := ch.Accept()
	if err != nil {
		s.Error("Failed to accept channe", "err", err)
		return
	}

	var closer sync.Once
	closeChannel := func() {
		s.Debug("Closed Channel", "id", id)
		channel.Close()
	}

	defer closer.Do(closeChannel)

	for req := range requests {
		spew.Dump(req.Type)
		switch req.Type {
		case "exec":
			// Let it through
		case "env":
			if req.WantReply {
				if err = req.Reply(true, nil); err != nil {
					s.Error("Failed to ignore env command", "err", err)
				}
			}
			continue
		default:
			s.Info("Received unhandled request type", "type", req.Type)
			continue
		}

		r := &scpRequest{db: s.DB}
		processors := []processor{
			r.ParseSCPRequest, r.DownloadFile, r.EndConnectionGracefully,
		}

		for _, proc := range processors {
			if err := proc(channel, req); err != nil {
				fmt.Fprintln(channel, "failed to process request:", err.Error())
				// log.Printf("%+v", err)
				break
			}
		}

		closer.Do(closeChannel)
	}
}
コード例 #24
0
ファイル: channel.go プロジェクト: magisterquis/sshhipot
/* rejectChannel tells the attacker the channel's been rejected by the real
server.  It requires the error from the channel request to the real server, the
channel request log string, the channel request from the attacker, and the
logger for the connection. */
func rejectChannel(nce error, crl string, nc ssh.NewChannel, lg *log.Logger) {
	/* Values to return to the attacker */
	reason := ssh.Prohibited
	message := nce.Error()
	/* Try and get the real story */
	if oce, ok := nce.(*ssh.OpenChannelError); ok {
		reason = oce.Reason
		message = oce.Message
	}
	lg.Printf(
		"Channel Rejection %v Reason:%v Message:%q",
		crl,
		reason,
		message,
	)
	/* Send the rejection */
	if err := nc.Reject(reason, message); nil != err {
		lg.Printf(
			"Unable to respond to channel request of type %q: %v",
			nc.ChannelType(),
			err,
		)
	}
}
コード例 #25
0
ファイル: daemon.go プロジェクト: Freeaqingme/SshReverseProxy
func handleChannel(newChannel ssh.NewChannel, rClient *ssh.Client) {
	if newChannel.ChannelType() != "session" {
		newChannel.Reject(ssh.UnknownChannelType, "unknown channel type: "+newChannel.ChannelType())
		return
	}
	psChannel, psRequests, err := newChannel.Accept()
	if err != nil {
		panic("could not accept channel.")
	}

	sChannel, sRequests, err := rClient.OpenChannel(newChannel.ChannelType(), nil)
	if err != nil {
		panic("Failed to create session: " + err.Error())
	}

	go pipeRequests(psChannel, sChannel, psRequests, sRequests)
	time.Sleep(50 * time.Millisecond)
	go pipe(sChannel, psChannel)
	go pipe(psChannel, sChannel)
}
コード例 #26
0
ファイル: forward.go プロジェクト: ksmaheshkumar/sshmux
// SessionForward performs a regular forward, providing the user with an
// interactive remote host selection if necessary. This forwarding type
// requires agent forwarding in order to work.
func (s *Server) SessionForward(session *Session, newChannel ssh.NewChannel, chans <-chan ssh.NewChannel) {

	// Okay, we're handling this as a regular session
	sesschan, sessReqs, err := newChannel.Accept()
	if err != nil {
		return
	}

	stderr := sesschan.Stderr()

	remote := ""
	switch len(session.Remotes) {
	case 0:
		sesschan.Close()
		return
	case 1:
		remote = session.Remotes[0]
	default:
		comm := rw{Reader: sesschan, Writer: stderr}
		if s.Interactive == nil {
			remote, err = DefaultInteractive(comm, session)
		} else {
			remote, err = s.Interactive(comm, session)
		}
		if err != nil {
			sesschan.Close()
			return
		}
	}

	fmt.Fprintf(stderr, "Connecting to %s\r\n", remote)

	// Set up the agent

	agentChan, agentReqs, err := session.Conn.OpenChannel("*****@*****.**", nil)
	if err != nil {
		fmt.Fprintf(stderr, "\r\n====== sshmux ======\r\n")
		fmt.Fprintf(stderr, "sshmux requires either agent forwarding or secure channel forwarding.\r\n")
		fmt.Fprintf(stderr, "Either enable agent forwarding (-A), or use a ssh -W proxy command.\r\n")
		fmt.Fprintf(stderr, "For more info, see the sshmux wiki.\r\n")
		sesschan.Close()
		return
	}
	defer agentChan.Close()
	go ssh.DiscardRequests(agentReqs)

	// Set up the client

	ag := agent.NewClient(agentChan)

	clientConfig := &ssh.ClientConfig{
		User: session.Conn.User(),
		Auth: []ssh.AuthMethod{
			ssh.PublicKeysCallback(ag.Signers),
		},
	}

	client, err := ssh.Dial("tcp", remote, clientConfig)
	if err != nil {
		fmt.Fprintf(stderr, "Connect failed: %v\r\n", err)
		sesschan.Close()
		return
	}

	// Handle all incoming channel requests
	go func() {
		for newChannel = range chans {
			if newChannel == nil {
				return
			}

			channel2, reqs2, err := client.OpenChannel(newChannel.ChannelType(), newChannel.ExtraData())
			if err != nil {
				x, ok := err.(*ssh.OpenChannelError)
				if ok {
					newChannel.Reject(x.Reason, x.Message)
				} else {
					newChannel.Reject(ssh.Prohibited, "remote server denied channel request")
				}
				continue
			}

			channel, reqs, err := newChannel.Accept()
			if err != nil {
				channel2.Close()
				continue
			}
			go proxy(reqs, reqs2, channel, channel2)
		}
	}()

	// Forward the session channel
	channel2, reqs2, err := client.OpenChannel("session", []byte{})
	if err != nil {
		fmt.Fprintf(stderr, "Remote session setup failed: %v\r\n", err)
		sesschan.Close()
		return
	}

	// Proxy the channel and its requests
	maskedReqs := make(chan *ssh.Request, 1)
	go func() {
		for req := range sessReqs {
			if req.Type == "*****@*****.**" {
				continue
			}
			maskedReqs <- req
		}
	}()
	proxy(maskedReqs, reqs2, sesschan, channel2)

}
コード例 #27
0
ファイル: ssh.go プロジェクト: influx6/proxies
func proxyChannel(c *ConnInsight, mcha ssh.Channel, mreq <-chan *ssh.Request, master ssh.NewChannel, client *SSHClient, killer <-chan struct{}) error {

	do := new(sync.Once)
	cochan, coreq, err := client.OpenChannel(master.ChannelType(), master.ExtraData())

	checkError(err, fmt.Sprintf("Creating Client Channel for %s", client.RemoteAddr().String()))

	if err != nil {
		return err
	}

	stop := make(chan struct{})
	endClose := func() { close(stop) }

	flux.GoDefer("proxyChannelCopy", func() {
		defer cochan.Close()
		defer mcha.Close()

		func() {
		ploop:
			for {
				select {
				case <-stop:
					break ploop
				case <-killer:
					break ploop
				case slx, ok := <-coreq:
					if !ok {
						return
					}

					Reply(slx, mcha, c)

					switch slx.Type {
					case "exit-status":
						break ploop
					}

				case mlx, ok := <-mreq:
					if !ok {
						return
					}

					Reply(mlx, cochan, c)

					switch mlx.Type {
					case "exit-status":
						break ploop
					}
				}
			}
		}()
	})

	mastercloser := io.ReadCloser(mcha)
	slavecloser := io.ReadCloser(cochan)

	wrapmaster := io.MultiWriter(mcha, c.Out())
	wrapsl := io.MultiWriter(cochan, c.In())

	flux.GoDefer("CopyToSlave", func() {
		defer do.Do(endClose)
		io.Copy(wrapsl, mastercloser)
	})

	flux.GoDefer("CopyToMaster", func() {
		defer do.Do(endClose)
		io.Copy(wrapmaster, slavecloser)
	})

	flux.GoDefer("CopyCloser", func() {
		defer c.Close()

		<-stop

		mx := mastercloser.Close()
		checkError(mx, "Master Writer Closer")

		sx := slavecloser.Close()
		checkError(sx, "Slave Writer Closer")

		ex := client.Close()
		checkError(ex, "Client Writer Closer")
	})

	return nil
}
コード例 #28
0
ファイル: ssht.go プロジェクト: xchapter7x/ssht
func handleChannel(newChannel ssh.NewChannel, config *SSHTestServer) {
	if t := newChannel.ChannelType(); t != "session" {
		newChannel.Reject(ssh.UnknownChannelType, fmt.Sprintf("unknown channel type: %s", t))
		return
	}
	connection, requests, err := newChannel.Accept()

	if err != nil {
		lo.G.Info("Could not accept channel (%s)", err)
		return
	}
	bash := exec.Command("bash")

	close := func() {
		connection.Close()
		_, err := bash.Process.Wait()

		if err != nil {
			lo.G.Info("Failed to exit bash (%s)", err)
		}
		lo.G.Info("Session closed")
	}
	lo.G.Info("Creating pty...")
	bashf, err := pty.Start(bash)

	if err != nil {
		lo.G.Info("Could not start pty (%s)", err)
		close()
		return
	}

	var once sync.Once
	var cmdBuffer = bytes.NewBufferString("")
	multiBashf := io.MultiWriter(cmdBuffer, bashf)

	go func() {
		io.Copy(multiBashf, connection)
		lo.G.Debug("done reading executor")
		once.Do(close)
	}()

	go func() {
		for {
			if strings.Contains(cmdBuffer.String(), config.SSHCommandMatch) {
				io.Copy(connection, bytes.NewBuffer(config.FakeResponseBytes))
				cmdBuffer.Reset()
			}
		}
	}()

	go func() {
		io.Copy(cmdBuffer, bashf)
		once.Do(close)
	}()

	go func() {
		for req := range requests {
			switch req.Type {
			case "shell":
				// We only accept the default shell
				// (i.e. no command in the Payload)
				if len(req.Payload) == 0 {
					req.Reply(true, nil)
				}
			case "pty-req":
				termLen := req.Payload[3]
				w, h := parseDims(req.Payload[termLen+4:])
				SetWinsize(bashf.Fd(), w, h)
				// Responding true (OK) here will let the client
				// know we have a pty ready for input
				req.Reply(true, nil)
			case "window-change":
				w, h := parseDims(req.Payload)
				SetWinsize(bashf.Fd(), w, h)
			}
		}
	}()
}
コード例 #29
0
ファイル: channel.go プロジェクト: magisterquis/sshhipot
/* handleChan handles a single channel request from sc, proxying it to the
client.  General logging messages will be written to lg, and channel-specific
data and messages will be written to a new file in ldir. */
func handleChan(
	nc ssh.NewChannel,
	client ssh.Conn,
	ldir string,
	lg *log.Logger,
	direction string,
) {
	/* Log the channel request */
	crl := fmt.Sprintf(
		"Type:%q Data:%q Direction:%q",
		nc.ChannelType(),
		nc.ExtraData(),
		direction,
	)

	/* Pass to server */
	cc, creqs, err := client.OpenChannel(
		nc.ChannelType(),
		nc.ExtraData(),
	)
	if nil != err {
		go rejectChannel(err, crl, nc, lg)
		return
	}

	defer cc.Close()

	/* Make channel to attacker, defer close */
	ac, areqs, err := nc.Accept()
	if nil != err {
		lg.Printf(
			"Unable to accept channel request of type %q: %v",
			nc.ChannelType(),
			err,
		)
		return
	}
	defer ac.Close()

	/* Channel worked, make a logger for it */
	clg, lf, clgn, err := logChannel(ldir, nc)
	if nil != err {
		lg.Printf(
			"Unable to open log file for channel of type %q:%v",
			nc.ChannelType(),
			err,
		)
		return
	}
	defer lf.Close()
	clg.Printf("Start of log")

	/* Proxy requests on channels */
	go handleReqs(areqs, Channel{oc: cc}, clg, "attacker->server")
	go handleReqs(creqs, Channel{oc: ac}, clg, "server->attacker")

	/* Log the channel */
	lg.Printf("Channel %s Log:%q", crl, clgn)

	/* Proxy comms */
	wg := make(chan int, 4)
	go ProxyChannel(
		ac,
		cc,
		clg,
		"server->attacker",
		wg,
		1,
	)
	go ProxyChannel(
		cc,
		ac,
		clg,
		"attacker->server",
		wg,
		1,
	)
	go ProxyChannel(
		cc.Stderr(),
		ac.Stderr(),
		clg,
		"attacker-(err)->server",
		wg,
		0,
	)
	go ProxyChannel(
		ac.Stderr(),
		cc.Stderr(),
		clg,
		"server-(err)->attacker",
		wg,
		0,
	)
	sum := 0
	for i := range wg {
		sum += i
		if 2 <= sum {
			break
		}
	}

	/* TODO: Proxy comms */
}
コード例 #30
0
ファイル: sshd.go プロジェクト: waltzofpearls/sftp-proxy
func handleChannel(newChannel ssh.NewChannel) {
	// Since we're handling a shell, we expect a
	// channel type of "session". The also describes
	// "x11", "direct-tcpip" and "forwarded-tcpip"
	// channel types.
	if t := newChannel.ChannelType(); t != "session" {
		newChannel.Reject(ssh.UnknownChannelType, fmt.Sprintf("unknown channel type: %s", t))
		return
	}

	// At this point, we have the opportunity to reject the client's
	// request for another logical connection
	connection, requests, err := newChannel.Accept()
	if err != nil {
		log.Printf("Could not accept channel (%s)", err)
		return
	}

	// Fire up bash for this session
	bash := exec.Command("bash")

	// Prepare teardown function
	close := func() {
		connection.Close()
		_, err := bash.Process.Wait()
		if err != nil {
			log.Printf("Failed to exit bash (%s)", err)
		}
		log.Printf("Session closed")
	}

	// Allocate a terminal for this channel
	log.Print("Creating pty...")
	bashf, err := pty.Start(bash)
	if err != nil {
		log.Printf("Could not start pty (%s)", err)
		close()
		return
	}

	//pipe session to bash and visa-versa
	var once sync.Once
	go func() {
		io.Copy(connection, bashf)
		once.Do(close)
	}()
	go func() {
		io.Copy(bashf, connection)
		once.Do(close)
	}()

	// Sessions have out-of-band requests such as "shell", "pty-req" and "env"
	go func() {
		for req := range requests {
			switch req.Type {
			case "shell":
				// We only accept the default shell
				// (i.e. no command in the Payload)
				if len(req.Payload) == 0 {
					req.Reply(true, nil)
				}
			case "pty-req":
				termLen := req.Payload[3]
				w, h := parseDims(req.Payload[termLen+4:])
				SetWinsize(bashf.Fd(), w, h)
				// Responding true (OK) here will let the client
				// know we have a pty ready for input
				req.Reply(true, nil)
			case "window-change":
				w, h := parseDims(req.Payload)
				SetWinsize(bashf.Fd(), w, h)
			}
		}
	}()
}