diff --git a/enroll/profile.go b/enroll/profile.go index df95d49e..f6d39bf6 100644 --- a/enroll/profile.go +++ b/enroll/profile.go @@ -1,8 +1,9 @@ package enroll import ( - "github.com/satori/go.uuid" "time" + + "github.com/satori/go.uuid" ) type Payload struct { @@ -65,10 +66,73 @@ type SCEPPayloadContent struct { URL string } +// AccessRights define the management rights of the MDM server over the device. +// May not be zero. If 2 is specified, 1 must also be specified. If 128 is specified, 64 must also be specified. +type AccessRights int + +const ( + // Allow inspection of installed configuration profiles. + ProfileInspection AccessRights = 1 << iota + + // Allow installation and removal of configuration profiles. + ProfileInstallAndRemoval + + // Allow device lock and passcode removal. + DeviceLock + + // Allow device erase. + DeviceErase + + // Allow query of Device Information (device capacity, serial number). + DeviceInformationQuery + + // Allow query of Network Information (phone/SIM numbers, MAC addresses). + NetworkInformationQuery + + // Allow inspection of installed provisioning profiles. + ProvisioningProfileInspection + + // Allow installation and removal of provisioning profiles. + ProvisioningProfileInstallAndRemoval + + // Allow inspection of installed applications. + ApplicationInspection + + // Allow restriction-related queries. + RestrictionQuery + + // Allow security-related queries. + SecurityQuery + + // Allow manipulation of settings. + // Availability: Available in iOS 5.0 and later. Available in macOS 10.9 for certain commands. + SettingsManipulation + + // Allow app management. + // Availability: Available in iOS 5.0 and later. Available in macOS 10.9 for certain commands. + AppManagement +) + +func allRights() AccessRights { + return ProfileInspection | + ProfileInstallAndRemoval | + DeviceLock | + DeviceErase | + DeviceInformationQuery | + NetworkInformationQuery | + ProvisioningProfileInspection | + ProvisioningProfileInstallAndRemoval | + ApplicationInspection | + RestrictionQuery | + SecurityQuery | + SettingsManipulation | + AppManagement +} + // TODO: Actually this is one of those non-nested payloads that doesnt respect the PayloadContent key. type MDMPayloadContent struct { Payload - AccessRights int + AccessRights AccessRights CheckInURL string CheckOutWhenRemoved bool IdentityCertificateUUID string diff --git a/enroll/profile_test.go b/enroll/profile_test.go new file mode 100644 index 00000000..b6c9db11 --- /dev/null +++ b/enroll/profile_test.go @@ -0,0 +1,35 @@ +package enroll + +import ( + "testing" +) + +func TestEnrollProfile(t *testing.T) { + svc := new(service) + profile, err := svc.MakeEnrollmentProfile() + if err != nil { + t.Fatal(err) + } + + var payloadContent MDMPayloadContent + for _, payload := range profile.PayloadContent { + if c, ok := payload.(MDMPayloadContent); ok { + payloadContent = c + } + } + + if have, want := payloadContent.AccessRights, AccessRights(8191); have != want { + t.Errorf("have %d, want %d", have, want) + } + + var hasPerUserConnections bool + for _, cap := range payloadContent.ServerCapabilities { + if cap == perUserConnections { + hasPerUserConnections = true + } + } + + if have, want := hasPerUserConnections, true; have != want { + t.Errorf("missing ServerCapabilities: macOS enrollment profile requires %s", perUserConnections) + } +} diff --git a/enroll/service.go b/enroll/service.go index 589e2842..213d5211 100644 --- a/enroll/service.go +++ b/enroll/service.go @@ -171,6 +171,8 @@ func (svc *service) Enroll(ctx context.Context) (profile.Mobileconfig, error) { return svc.findOrMakeMobileconfig(EnrollmentProfileId, svc.MakeEnrollmentProfile) } +const perUserConnections = "com.apple.mdm.per-user-connections" + func (svc *service) MakeEnrollmentProfile() (Profile, error) { profile := NewProfile() profile.PayloadIdentifier = EnrollmentProfileId @@ -191,13 +193,13 @@ func (svc *service) MakeEnrollmentProfile() (Profile, error) { mdmPayloadContent := MDMPayloadContent{ Payload: *mdmPayload, - AccessRights: 8191, + AccessRights: allRights(), CheckInURL: svc.URL + "/mdm/checkin", CheckOutWhenRemoved: true, ServerURL: svc.URL + "/mdm/connect", Topic: topic, SignMessage: true, - ServerCapabilities: []string{"com.apple.mdm.per-user-connections"}, + ServerCapabilities: []string{perUserConnections}, } payloadContent := []interface{}{}