func (s *Server) handleSessionRequests(sconn *ssh.ServerConn, ch ssh.Channel, in <-chan *ssh.Request) {
	// ctx holds the connection context and keeps track of the associated resources
	ctx := newCtx(s, sconn)
	ctx.isTestStub = s.isTestStub
	ctx.addCloser(ch)
	defer ctx.Close()

	// As SSH conversation progresses, at some point a session will be created and
	// its ID will be added to the environment
	updateContext := func() {
		ssid, found := ctx.getEnv(sshutils.SessionEnvVar)
		if !found {
			return
		}
		findSession := func() (*session, bool) {
			s.reg.Lock()
			defer s.reg.Unlock()
			return s.reg.findSession(rsession.ID(ssid))
		}
		// update ctx with a session ID
		ctx.session, _ = findSession()
		log.Debugf("[SSH] loaded session %v for SSH connection %v", ctx.session, sconn)
	}

	for {
		// update ctx with the session ID:
		if !s.proxyMode {
			updateContext()
		}
		select {
		case creq := <-ctx.subsystemResultC:
			// this means that subsystem has finished executing and
			// want us to close session and the channel
			ctx.Debugf("[SSH] close session request: %v", creq.err)
			return
		case req := <-in:
			if req == nil {
				// this will happen when the client closes/drops the connection
				ctx.Debugf("[SSH] client %v disconnected", sconn.RemoteAddr())
				return
			}
			if err := s.dispatch(ch, req, ctx); err != nil {
				replyError(ch, req, err)
				return
			}
			if req.WantReply {
				req.Reply(true, nil)
			}
		case result := <-ctx.result:
			ctx.Debugf("[SSH] ctx.result = %v", result)
			// pass back stderr output
			if len(result.stderr) != 0 {
				ch.Stderr().Write(result.stderr)
			}
			// this means that exec process has finished and delivered the execution result,
			// we send it back and close the session
			_, err := ch.SendRequest("exit-status", false, ssh.Marshal(struct{ C uint32 }{C: uint32(result.code)}))
			if err != nil {
				ctx.Infof("[SSH] %v failed to send exit status: %v", result.command, err)
			}
			return
		}
	}
}
// handleSessionRequests handles out of band session requests once the session channel has been created
// this function's loop handles all the "exec", "subsystem" and "shell" requests.
handleSessionRequests handles out of band session requests once the session channel has been created
this function's loop handles all the "exec", "subsystem" and "shell" requests.
// handleSessionRequests handles out of band session requests once the session channel has been created // this function ' s loop handles all the " exec " " subsystem " and " shell " requests .
func (s *Server) handleSessionRequests(sconn *ssh.ServerConn, ch ssh.Channel, in <-chan *ssh.Request) {
	ctx := newCtx(s, sconn)
	ctx.isTestStub = s.isTestStub
	ctx.addCloser(ch)
	defer ctx.Close()
	updateContext := func() {
		ssid, found := ctx.getEnv(sshutils.SessionEnvVar)
		if !found {
			return
		}
		findSession := func() (*session, bool) {
			s.reg.Lock()
			defer s.reg.Unlock()
			return s.reg.findSession(rsession.ID(ssid))
		}
		ctx.session, _ = findSession()
		log.Debugf("[SSH] loaded session %v for SSH connection %v", ctx.session, sconn)
	}
	for {
		if !s.proxyMode {
			updateContext()
		}
		select {
		case creq := <-ctx.subsystemResultC:
			ctx.Debugf("[SSH] close session request: %v", creq.err)
			return
		case req := <-in:
			if req == nil {
				ctx.Debugf("[SSH] client %v disconnected", sconn.RemoteAddr())
				return
			}
			if err := s.dispatch(ch, req, ctx); err != nil {
				replyError(ch, req, err)
				return
			}
			if req.WantReply {
				req.Reply(true, nil)
			}
		case result := <-ctx.result:
			ctx.Debugf("[SSH] ctx.result = %v", result)
			if len(result.stderr) != 0 {
				ch.Stderr().Write(result.stderr)
			}
			_, err := ch.SendRequest("exit-status", false, ssh.Marshal(struct{ C uint32 }{C: uint32(result.code)}))
			if err != nil {
				ctx.Infof("[SSH] %v failed to send exit status: %v", result.command, err)
			}
			return
		}
	}
}
func ( s * Server ) handleSessionRequests ( sconn * ssh . ServerConn , ch ssh . Channel , in <- chan * ssh . Request ) { ctx := newCtx ( s , sconn ) ctx . isTestStub = s . isTestStub ctx . addCloser ( ch ) defer ctx . Close ( ) updateContext := func ( ) { ssid , found := ctx . getEnv ( sshutils . SessionEnvVar ) if ! found { return } findSession := func ( ) ( * session , bool ) { s . reg . Lock ( ) defer s . reg . Unlock ( ) return s . reg . findSession ( rsession . ID ( ssid ) ) } ctx . session , _ = findSession ( ) log . Debugf ( " " , ctx . session , sconn ) } for { if ! s . proxyMode { updateContext ( ) } select { case creq := <- ctx . subsystemResultC : ctx . Debugf ( " " , creq . err ) return case req := <- in : if req == nil { ctx . Debugf ( " " , sconn . RemoteAddr ( ) ) return } if err := s . dispatch ( ch , req , ctx ) ; err != nil { replyError ( ch , req , err ) return } if req . WantReply { req . Reply ( true , nil ) } case result := <- ctx . result : ctx . Debugf ( " " , result ) if len ( result . stderr ) != 0 { ch . Stderr ( ) . Write ( result . stderr ) } _ , err := ch . SendRequest ( " " , false , ssh . Marshal ( struct { C uint32 } { C : uint32 ( result . code ) } ) ) if err != nil { ctx . Infof ( " " , result . command , err ) } return } } }
handleSessionRequests handles out of band session requests once the session channel has been created
this function's loop handles all the "exec", "subsystem" and "shell" requests.
handleSessionRequests handles out of band session requests once the session channel has been created this function ' s loop handles all the " exec " " subsystem " and " shell " requests .
// ctx holds the connection context and keeps track of the associated resources // As SSH conversation progresses, at some point a session will be created and // its ID will be added to the environment // update ctx with a session ID // update ctx with the session ID: // this means that subsystem has finished executing and // want us to close session and the channel // this will happen when the client closes/drops the connection // pass back stderr output // this means that exec process has finished and delivered the execution result, // we send it back and close the session