From 8eac57a95bd26ba722bb8ef5126ef740ec637259 Mon Sep 17 00:00:00 2001 From: Alan Parra Date: Thu, 17 Oct 2024 15:32:02 -0300 Subject: [PATCH] fix: Avoid needless user escalation during auto-enroll --- lib/devicetrust/enroll/auto_enroll.go | 19 ++++++++++--------- lib/devicetrust/enroll/auto_enroll_test.go | 1 - lib/devicetrust/enroll/enroll.go | 9 +++++++++ 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/lib/devicetrust/enroll/auto_enroll.go b/lib/devicetrust/enroll/auto_enroll.go index 4cc6663a8a9c..2d9db0214fa4 100644 --- a/lib/devicetrust/enroll/auto_enroll.go +++ b/lib/devicetrust/enroll/auto_enroll.go @@ -24,22 +24,18 @@ import ( "github.com/gravitational/trace" devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1" - "github.com/gravitational/teleport/lib/devicetrust/native" ) // AutoEnrollCeremony is the auto-enrollment version of [Ceremony]. type AutoEnrollCeremony struct { *Ceremony - - CollectDeviceData func(mode native.CollectDataMode) (*devicepb.DeviceCollectedData, error) } // NewAutoEnrollCeremony creates a new [AutoEnrollCeremony] based on the regular // ceremony provided by [NewCeremony]. func NewAutoEnrollCeremony() *AutoEnrollCeremony { return &AutoEnrollCeremony{ - Ceremony: NewCeremony(), - CollectDeviceData: native.CollectDeviceData, + Ceremony: NewCeremony(), } } @@ -53,18 +49,23 @@ func AutoEnroll(ctx context.Context, devicesClient devicepb.DeviceTrustServiceCl // [devicepb.DeviceTrustServiceClient.CreateDeviceEnrollToken] and enrolls the // device using a regular [Ceremony]. func (c *AutoEnrollCeremony) Run(ctx context.Context, devicesClient devicepb.DeviceTrustServiceClient) (*devicepb.Device, error) { - cd, err := c.CollectDeviceData(native.CollectedDataAlwaysEscalate) + // Creating the init message straight away aborts the process cleanly if the + // device cannot create the device key (for example, if it lacks a TPM). + // This avoids a situation where we ask for escalation, like a sudo prompt or + // admin credentials, then fail a few steps after the prompt. + init, err := c.EnrollDeviceInit() if err != nil { - return nil, trace.Wrap(err, "collecting device data") + return nil, trace.Wrap(err) } token, err := devicesClient.CreateDeviceEnrollToken(ctx, &devicepb.CreateDeviceEnrollTokenRequest{ - DeviceData: cd, + DeviceData: init.DeviceData, }) if err != nil { return nil, trace.Wrap(err, "creating auto-token") } + init.Token = token.Token - dev, err := c.Ceremony.Run(ctx, devicesClient, false, token.Token) + dev, err := c.run(ctx, devicesClient, false /* debug */, init) return dev, trace.Wrap(err) } diff --git a/lib/devicetrust/enroll/auto_enroll_test.go b/lib/devicetrust/enroll/auto_enroll_test.go index 4b29db639247..fc1853ec895c 100644 --- a/lib/devicetrust/enroll/auto_enroll_test.go +++ b/lib/devicetrust/enroll/auto_enroll_test.go @@ -59,7 +59,6 @@ func TestAutoEnrollCeremony_Run(t *testing.T) { SignChallenge: test.dev.SignChallenge, SolveTPMEnrollChallenge: test.dev.SolveTPMEnrollChallenge, }, - CollectDeviceData: test.dev.CollectDeviceData, } dev, err := c.Run(ctx, devices) diff --git a/lib/devicetrust/enroll/enroll.go b/lib/devicetrust/enroll/enroll.go index dd733aa39c0d..b7e8a18c662e 100644 --- a/lib/devicetrust/enroll/enroll.go +++ b/lib/devicetrust/enroll/enroll.go @@ -173,6 +173,15 @@ func (c *Ceremony) Run(ctx context.Context, devicesClient devicepb.DeviceTrustSe } init.Token = enrollToken + return c.run(ctx, devicesClient, debug, init) +} + +func (c *Ceremony) run(ctx context.Context, devicesClient devicepb.DeviceTrustServiceClient, debug bool, init *devicepb.EnrollDeviceInit) (*devicepb.Device, error) { + // Sanity check. + if init.GetToken() == "" { + return nil, trace.BadParameter("enroll init message lacks enrollment token") + } + stream, err := devicesClient.EnrollDevice(ctx) if err != nil { return nil, trace.Wrap(devicetrust.HandleUnimplemented(err))