def profile(): """Accept a CMS Signed DER encoded XML data containing device information. This starts the DEP enrollment process. The absolute url to this endpoint should be present in the DEP profile's enrollment URL. The signed data contains a plist with the following keys: :UDID: The device’s UDID. :SERIAL: The device's Serial Number. :PRODUCT: The device’s product type: e.g., iPhone5,1. :VERSION: The OS version installed on the device: e.g., 7A182. :IMEI: The device’s IMEI (if available). :MEID: The device’s MEID (if available). :LANGUAGE: The user’s currently-selected language: e.g., en. See Also: - `Mobile Device Management Protocol: Request to a Profile URL <https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/MobileDeviceManagementProtocolRef/4-Profile_Management/ProfileManagement.html#//apple_ref/doc/uid/TP40017387-CH7-SW242>`_. """ g.plist_data = plistlib.loads(g.signed_data) profile = generate_enroll_profile() schema = ProfileSchema() result = schema.dump(profile) plist_data = dumps_none(result.data, skipkeys=True) return plist_data, 200, {'Content-Type': PROFILE_CONTENT_TYPE}
def enroll(): """Generate an enrollment profile.""" profile = generate_enroll_profile() schema = profile_schema.ProfileSchema() result = schema.dump(profile) plist_data = dumps_none(result.data, skipkeys=True) return plist_data, 200, {'Content-Type': PROFILE_CONTENT_TYPE}
def enroll(): """Generate an enrollment profile.""" ca = get_ca() key, csr = ca.create_device_csr('device-identity') device_certificate = ca.sign(csr) pkcs12_payload = identity_payload(key, device_certificate, 'sekret') profile = generate_enroll_profile(pkcs12_payload) schema = profile_schema.ProfileSchema() result = schema.dump(profile) plist_data = dumps_none(result.data, skipkeys=True) return plist_data, 200, {'Content-Type': PROFILE_CONTENT_TYPE}
def profile(): """Accept a CMS Signed DER encoded XML data containing device information. This starts the DEP enrollment process. See Also: - **Request to a Profile URL** in the MDM Protocol Reference. """ # TODO: Do something with signed request data??? #g.plist_data = plistlib.loads(g.signed_data) profile = generate_enroll_profile() schema = ProfileSchema() result = schema.dump(profile) plist_data = dumps_none(result.data, skipkeys=True) return plist_data, 200, {'Content-Type': PROFILE_CONTENT_TYPE}
def ota_authenticate(): """Over-The-Air Profile Delivery Phase 3 and 4. This endpoint represents the OTA Phase 3 and 4, "/profile" endpoint as specified in apples document "Over-The-Air Profile Delivery". There are two types of requests made here: - The first request is signed by the iPhone Device CA and contains the challenge in the `Profile Service` payload, we respond with the SCEP detail. - The second request is signed by the issued SCEP certificate. We should respond with an enrollment profile. It also contains the same device attributes sent in the previous step, but this time they are authenticated by our SCEP CA. Examples: Signed plist given in the first request:: { 'CHALLENGE': '<CHALLENGE FROM PROFILE HERE>', 'IMEI': 'empty if macOS', 'MEID': 'empty if macOS', 'NotOnConsole': False, 'PRODUCT': 'MacPro6,1', 'SERIAL': 'C020000000000', 'UDID': '00000000-0000-0000-0000-000000000000', 'UserID': '00000000-0000-0000-0000-000000000000', 'UserLongName': 'Joe User', 'UserShortName': 'juser', 'VERSION': '16F73' } See Also: - `Over-the-Air Profile Delivery and Configuration <https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/iPhoneOTAConfiguration/Introduction/Introduction.html#//apple_ref/doc/uid/TP40009505-CH1-SW1>`_. """ signed_data = g.signed_data signers = g.signers # TODO: This should Validate to iPhone Device CA but we can't because: # http://www.openradar.me/31423312 device_attributes = plistlib.loads(signed_data) current_app.logger.debug(device_attributes) try: org = db.session.query(Organization).one() except NoResultFound: abort(500, 'No organization is configured, cannot generate enrollment profile.') except MultipleResultsFound: abort(500, 'Multiple organizations, backup your database and start again') # TODO: Behold, the stupidest thing ever just to get this working, theres no way this should be prod: # Phase 4 does not send a challenge but phase 3 does if 'CHALLENGE' in device_attributes: # Reply SCEP profile = Profile( identifier=org.payload_prefix + '.ota.phase3', uuid=uuid4(), display_name='Commandment OTA SCEP Enrollment', description='Retrieves a SCEP Certificate to complete OTA Enrollment', organization=org.name, version=1, scope=PayloadScope.System, ) scep_payload = scep_payload_from_configuration() profile.payloads.append(scep_payload) else: profile = generate_enroll_profile() # profile = generate_enroll_profile() schema = profile_schema.ProfileSchema() result = schema.dump(profile) plist_data = dumps_none(result.data, skipkeys=True) return plist_data, 200, {'Content-Type': PROFILE_CONTENT_TYPE}