Allow locking a desktop

Prior to this change, desktop access only respected locks
on users or roles. This introduces a desktop as a lock target,
preventing new connections and terminating existing connections
to a locked desktop.

Note: when a lock is created, connection attempts will fail
with the generic "websocket connection failed" error.
This will be addressed with #8584.

Updates #8742
This commit is contained in:
Zac Bergquist 2021-12-22 09:02:18 -07:00 committed by Zac Bergquist
parent 9edf72b86f
commit 7c96ba9177
7 changed files with 719 additions and 660 deletions

View file

@ -217,6 +217,9 @@ func (t LockTarget) Match(lock Lock) bool {
if t.MFADevice != "" && lockTarget.MFADevice != t.MFADevice {
return false
}
if t.WindowsDesktop != "" && lockTarget.WindowsDesktop != t.WindowsDesktop {
return false
}
return true
}

File diff suppressed because it is too large Load diff

View file

@ -2558,6 +2558,9 @@ message LockTarget {
// MFADevice specifies the UUID of a user MFA device.
string MFADevice = 5 [ (gogoproto.jsontag) = "mfa_device,omitempty" ];
// WindowsDesktop specifies the name of a Windows desktop.
string WindowsDesktop = 6 [ (gogoproto.jsontag) = "windows_desktop,omitempty" ];
}
// AddressCondition represents a set of addresses. Presently the addresses are specfied

View file

@ -149,6 +149,7 @@ func (process *TeleportProcess) initWindowsDesktopServiceRegistered(log *logrus.
ResourceWatcherConfig: services.ResourceWatcherConfig{
Component: teleport.ComponentWindowsDesktop,
Log: log,
Clock: cfg.Clock,
Client: conn.Client,
},
})

View file

@ -444,6 +444,9 @@ func (s *WindowsService) Serve(plainLis net.Listener) error {
}
}
// handleConnection handles TLS connections from a Teleport proxy.
// It authenticates and authorizes the connection, and then begins
// translating the TDP messages from the proxy into native RDP.
func (s *WindowsService) handleConnection(con net.Conn) {
defer con.Close()
log := s.cfg.Log
@ -548,7 +551,8 @@ func (s *WindowsService) connectRDP(ctx context.Context, log logrus.FieldLogger,
Entry: log,
Emitter: s.cfg.Emitter,
LockWatcher: s.cfg.LockWatcher,
LockTargets: services.LockTargetsFromTLSIdentity(identity),
LockingMode: authCtx.Checker.LockingMode(authPref.GetLockingMode()),
LockTargets: append(services.LockTargetsFromTLSIdentity(identity), types.LockTarget{WindowsDesktop: desktop.GetName()}),
Tracker: rdpc,
TeleportUser: identity.Username,
ServerID: s.cfg.Heartbeat.HostUUID,

View file

@ -223,8 +223,9 @@ func (w *Monitor) start(lockWatch types.Watcher) {
lock, ok := lockEvent.Resource.(types.Lock)
if !ok {
w.Entry.Warnf("Skipping unexpected lock event resource type %T.", lockEvent.Resource)
} else {
lockErr = services.LockInForceAccessDenied(lock)
}
lockErr = services.LockInForceAccessDenied(lock)
case types.OpDelete:
// Lock deletion can be ignored.
case types.OpUnreliable:

View file

@ -49,6 +49,7 @@ func (c *LockCommand) Initialize(app *kingpin.Application, config *service.Confi
c.mainCmd.Flag("login", "Name of a local UNIX user to disable.").StringVar(&c.spec.Target.Login)
c.mainCmd.Flag("node", "UUID of a Teleport node to disable.").StringVar(&c.spec.Target.Node)
c.mainCmd.Flag("mfa-device", "UUID of a user MFA device to disable.").StringVar(&c.spec.Target.MFADevice)
c.mainCmd.Flag("windows-desktop", "Name of a Windows desktop to disable.").StringVar(&c.spec.Target.WindowsDesktop)
c.mainCmd.Flag("message", "Message to display to locked-out users.").StringVar(&c.spec.Message)
c.mainCmd.Flag("expires", "Time point (RFC3339) when the lock expires.").StringVar(&c.expires)
c.mainCmd.Flag("ttl", "Time duration after which the lock expires.").DurationVar(&c.ttl)