func (s *Server) dispatch(ch ssh.Channel, req *ssh.Request, ctx *ctx) error {
	ctx.Debugf("[SSH] ssh.dispatch(req=%v, wantReply=%v)", req.Type, req.WantReply)

	// if this SSH server is configured to only proxy, we do not support anything other
	// than our own custom "subsystems" and environment manipulation
	if s.proxyMode {
		switch req.Type {
		case "subsystem":
			return s.handleSubsystem(ch, req, ctx)
		case "env":
			// we currently ignore setting any environment variables via SSH for security purposes
			return s.handleEnv(ch, req, ctx)
		default:
			return trace.BadParameter(
				"proxy doesn't support request type '%v'", req.Type)
		}
	}

	switch req.Type {
	case "exec":
		// exec is a remote execution of a program, does not use PTY
		return s.handleExec(ch, req, ctx)
	case sshutils.PTYReq:
		// SSH client asked to allocate PTY
		return s.handlePTYReq(ch, req, ctx)
	case "shell":
		// SSH client asked to launch shell, we allocate PTY and start shell session
		ctx.exec = &execResponse{ctx: ctx}
		if err := s.reg.openSession(ch, req, ctx); err != nil {
			log.Error(err)
			return trace.Wrap(err)
		}
		return nil
	case "env":
		return s.handleEnv(ch, req, ctx)
	case "subsystem":
		// subsystems are SSH subsystems defined in http://tools.ietf.org/html/rfc4254 6.6
		// they are in essence SSH session extensions, allowing to implement new SSH commands
		return s.handleSubsystem(ch, req, ctx)
	case sshutils.WindowChangeReq:
		return s.handleWinChange(ch, req, ctx)
	case "auth-agent-req@openssh.com":
		// This happens when SSH client has agent forwarding enabled, in this case
		// client sends a special request, in return SSH server opens new channel
		// that uses SSH protocol for agent drafted here:
		// https://tools.ietf.org/html/draft-ietf-secsh-agent-02
		// the open ssh proto spec that we implement is here:
		// http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.agent
		return s.handleAgentForward(ch, req, ctx)
	default:
		return trace.BadParameter(
			"proxy doesn't support request type '%v'", req.Type)
	}
}
// dispatch receives an SSH request for a subsystem and disptaches the request to the
// appropriate subsystem implementation
dispatch receives an SSH request for a subsystem and disptaches the request to the
appropriate subsystem implementation
// dispatch receives an SSH request for a subsystem and disptaches the request to the // appropriate subsystem implementation
func (s *Server) dispatch(ch ssh.Channel, req *ssh.Request, ctx *ctx) error {
	ctx.Debugf("[SSH] ssh.dispatch(req=%v, wantReply=%v)", req.Type, req.WantReply)
	if s.proxyMode {
		switch req.Type {
		case "subsystem":
			return s.handleSubsystem(ch, req, ctx)
		case "env":
			return s.handleEnv(ch, req, ctx)
		default:
			return trace.BadParameter(
				"proxy doesn't support request type '%v'", req.Type)
		}
	}
	switch req.Type {
	case "exec":
		return s.handleExec(ch, req, ctx)
	case sshutils.PTYReq:
		return s.handlePTYReq(ch, req, ctx)
	case "shell":
		ctx.exec = &execResponse{ctx: ctx}
		if err := s.reg.openSession(ch, req, ctx); err != nil {
			log.Error(err)
			return trace.Wrap(err)
		}
		return nil
	case "env":
		return s.handleEnv(ch, req, ctx)
	case "subsystem":
		return s.handleSubsystem(ch, req, ctx)
	case sshutils.WindowChangeReq:
		return s.handleWinChange(ch, req, ctx)
	case "auth-agent-req@openssh.com":
		return s.handleAgentForward(ch, req, ctx)
	default:
		return trace.BadParameter(
			"proxy doesn't support request type '%v'", req.Type)
	}
}
func ( s * Server ) dispatch ( ch ssh . Channel , req * ssh . Request , ctx * ctx ) error { ctx . Debugf ( " " , req . Type , req . WantReply ) if s . proxyMode { switch req . Type { case " " : return s . handleSubsystem ( ch , req , ctx ) case " " : return s . handleEnv ( ch , req , ctx ) default : return trace . BadParameter ( " " , req . Type ) } } switch req . Type { case " " : return s . handleExec ( ch , req , ctx ) case sshutils . PTYReq : return s . handlePTYReq ( ch , req , ctx ) case " " : ctx . exec = & execResponse { ctx : ctx } if err := s . reg . openSession ( ch , req , ctx ) ; err != nil { log . Error ( err ) return trace . Wrap ( err ) } return nil case " " : return s . handleEnv ( ch , req , ctx ) case " " : return s . handleSubsystem ( ch , req , ctx ) case sshutils . WindowChangeReq : return s . handleWinChange ( ch , req , ctx ) case " " : return s . handleAgentForward ( ch , req , ctx ) default : return trace . BadParameter ( " " , req . Type ) } }
dispatch receives an SSH request for a subsystem and disptaches the request to the
appropriate subsystem implementation
dispatch receives an SSH request for a subsystem and disptaches the request to the appropriate subsystem implementation
// if this SSH server is configured to only proxy, we do not support anything other // than our own custom "subsystems" and environment manipulation // we currently ignore setting any environment variables via SSH for security purposes // exec is a remote execution of a program, does not use PTY // SSH client asked to allocate PTY // SSH client asked to launch shell, we allocate PTY and start shell session // subsystems are SSH subsystems defined in http://tools.ietf.org/html/rfc4254 6.6 // they are in essence SSH session extensions, allowing to implement new SSH commands // This happens when SSH client has agent forwarding enabled, in this case // client sends a special request, in return SSH server opens new channel // that uses SSH protocol for agent drafted here: // https://tools.ietf.org/html/draft-ietf-secsh-agent-02 // the open ssh proto spec that we implement is here: // http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.agent