func (s *sessionRegistry) openSession(ch ssh.Channel, req *ssh.Request, ctx *ctx) error {
	if ctx.session != nil {
		// emit "joined session" event:
		s.srv.EmitAuditEvent(events.SessionJoinEvent, events.EventFields{
			events.SessionEventID:  string(ctx.session.id),
			events.EventLogin:      ctx.login,
			events.EventUser:       ctx.teleportUser,
			events.LocalAddr:       ctx.conn.LocalAddr().String(),
			events.RemoteAddr:      ctx.conn.RemoteAddr().String(),
			events.SessionServerID: ctx.srv.ID(),
		})
		ctx.Infof("[SESSION] joining session: %v", ctx.session.id)
		_, err := ctx.session.join(ch, req, ctx)
		return trace.Wrap(err)
	}
	// session not found? need to create one. start by getting/generating an ID for it
	sid, found := ctx.getEnv(sshutils.SessionEnvVar)
	if !found {
		sid = string(rsession.NewID())
		ctx.setEnv(sshutils.SessionEnvVar, sid)
	}
	// This logic allows concurrent request to create a new session
	// to fail, what is ok because we should never have this condition
	sess, err := newSession(rsession.ID(sid), s, ctx)
	if err != nil {
		return trace.Wrap(err)
	}
	ctx.session = sess
	s.addSession(sess)
	ctx.Infof("[SESSION] new session %v", sid)

	if err := sess.start(ch, ctx); err != nil {
		sess.Close()
		return trace.Wrap(err)
	}
	return nil
}
// joinShell either joins an existing session or starts a new shell
joinShell either joins an existing session or starts a new shell
// joinShell either joins an existing session or starts a new shell
func (s *sessionRegistry) openSession(ch ssh.Channel, req *ssh.Request, ctx *ctx) error {
	if ctx.session != nil {
		s.srv.EmitAuditEvent(events.SessionJoinEvent, events.EventFields{
			events.SessionEventID:  string(ctx.session.id),
			events.EventLogin:      ctx.login,
			events.EventUser:       ctx.teleportUser,
			events.LocalAddr:       ctx.conn.LocalAddr().String(),
			events.RemoteAddr:      ctx.conn.RemoteAddr().String(),
			events.SessionServerID: ctx.srv.ID(),
		})
		ctx.Infof("[SESSION] joining session: %v", ctx.session.id)
		_, err := ctx.session.join(ch, req, ctx)
		return trace.Wrap(err)
	}
	sid, found := ctx.getEnv(sshutils.SessionEnvVar)
	if !found {
		sid = string(rsession.NewID())
		ctx.setEnv(sshutils.SessionEnvVar, sid)
	}
	sess, err := newSession(rsession.ID(sid), s, ctx)
	if err != nil {
		return trace.Wrap(err)
	}
	ctx.session = sess
	s.addSession(sess)
	ctx.Infof("[SESSION] new session %v", sid)
	if err := sess.start(ch, ctx); err != nil {
		sess.Close()
		return trace.Wrap(err)
	}
	return nil
}
func ( s * sessionRegistry ) openSession ( ch ssh . Channel , req * ssh . Request , ctx * ctx ) error { if ctx . session != nil { s . srv . EmitAuditEvent ( events . SessionJoinEvent , events . EventFields { events . SessionEventID : string ( ctx . session . id ) , events . EventLogin : ctx . login , events . EventUser : ctx . teleportUser , events . LocalAddr : ctx . conn . LocalAddr ( ) . String ( ) , events . RemoteAddr : ctx . conn . RemoteAddr ( ) . String ( ) , events . SessionServerID : ctx . srv . ID ( ) , } ) ctx . Infof ( " " , ctx . session . id ) _ , err := ctx . session . join ( ch , req , ctx ) return trace . Wrap ( err ) } sid , found := ctx . getEnv ( sshutils . SessionEnvVar ) if ! found { sid = string ( rsession . NewID ( ) ) ctx . setEnv ( sshutils . SessionEnvVar , sid ) } sess , err := newSession ( rsession . ID ( sid ) , s , ctx ) if err != nil { return trace . Wrap ( err ) } ctx . session = sess s . addSession ( sess ) ctx . Infof ( " " , sid ) if err := sess . start ( ch , ctx ) ; err != nil { sess . Close ( ) return trace . Wrap ( err ) } return nil }
joinShell either joins an existing session or starts a new shell
joinShell either joins an existing session or starts a new shell
// emit "joined session" event: // session not found? need to create one. start by getting/generating an ID for it // This logic allows concurrent request to create a new session // to fail, what is ok because we should never have this condition