func()

in pkg/sshd/ssh_exec.go [292:425]


func (sess *session) handleRequests(reqs <-chan *ssh.Request) {
	for req := range reqs {
		switch req.Type {
		case "shell", "exec":
			if sess.handled {
				req.Reply(false, nil)
				continue
			}

			var payload = struct{ Value string }{}
			ssh.Unmarshal(req.Payload, &payload)
			sess.rawCmd = payload.Value

			//// If there's a session policy callback, we need to confirm before
			//// accepting the session.
			//if sess.sessReqCb != nil && !sess.sessReqCb(sess, req.Type) {
			//	sess.rawCmd = ""
			//	req.Reply(false, nil)
			//	continue
			//}

			sess.handled = true
			req.Reply(true, nil)

			go func() {
				sess.srv.connectionHandler(sess)
				sess.Exit(0)
			}()
		case "subsystem":
			if sess.handled {
				req.Reply(false, nil)
				continue
			}

			var payload = struct{ Value string }{}
			ssh.Unmarshal(req.Payload, &payload)
			sess.subsystem = payload.Value

			//// If there's a session policy callback, we need to confirm before
			//// accepting the session.
			//if sess.sessReqCb != nil && !sess.sessReqCb(sess, req.Type) {
			//	sess.rawCmd = ""
			//	req.Reply(false, nil)
			//	continue
			//}

			if "sftp" == payload.Value {
				sess.handled = true
				req.Reply(true, nil)

				go func() {
					sftpHandler(sess)
					sess.Exit(0)
				}()
			} else {
				req.Reply(false, nil)
				continue
			}
		case "env":
			if sess.handled {
				req.Reply(false, nil)
				continue
			}
			var kv struct{ Key, Value string }
			ssh.Unmarshal(req.Payload, &kv)
			sess.env = append(sess.env, fmt.Sprintf("%s=%s", kv.Key, kv.Value))
			req.Reply(true, nil)
		case "signal":
			var payload struct{ Signal string }
			ssh.Unmarshal(req.Payload, &payload)
			sess.Lock()
			if sess.sigCh != nil {
				sess.sigCh <- Signal(payload.Signal)
			} else {
				if len(sess.sigBuf) < maxSigBufSize {
					sess.sigBuf = append(sess.sigBuf, Signal(payload.Signal))
				}
			}
			sess.Unlock()
		case "pty-req":
			if sess.handled || sess.pty != nil {
				req.Reply(false, nil)
				continue
			}
			ptyReq, ok := parsePtyRequest(req.Payload)
			if !ok {
				req.Reply(false, nil)
				continue
			}
			//if sess.ptyCb != nil {
			//	ok := sess.ptyCb(sess.ctx, ptyReq)
			//	if !ok {
			//		req.Reply(false, nil)
			//		continue
			//	}
			//}
			sess.pty = &ptyReq
			sess.winch = make(chan Window, 1)
			sess.winch <- ptyReq.Window
			defer func() {
				// when reqs is closed
				close(sess.winch)
			}()
			req.Reply(ok, nil)
		case "window-change":
			if sess.pty == nil {
				req.Reply(false, nil)
				continue
			}
			win, ok := parseWinchRequest(req.Payload)
			if ok {
				sess.pty.Window = win
				sess.winch <- win
			}
			req.Reply(ok, nil)
		//case agentRequestType:
		//	// TODO: option/callback to allow agent forwarding
		//	SetAgentRequested(sess.ctx)
		//	req.Reply(true, nil)
		case "break":
			ok := false
			sess.Lock()
			if sess.breakCh != nil {
				sess.breakCh <- true
				ok = true
			}
			req.Reply(ok, nil)
			sess.Unlock()
		default:
			// TODO: debug log
			req.Reply(false, nil)
		}
	}
}