Exemplo n.º 1
0
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}
Exemplo n.º 2
0
def trust_mobileconfig():
    """Generate a trust profile, if one is required.

    :resheader Content-Type: application/x-apple-aspen-config
    :statuscode 200:
    :statuscode 500: The system has not been configured, so we can't produce anything.
    """
    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')

    profile = Profile(
        identifier=org.payload_prefix + '.trust',
        uuid=uuid4(),
        display_name='Commandment Trust Profile',
        description='Allows your device to trust the MDM server',
        organization=org.name,
        version=1,
        scope=PayloadScope.System,
    )

    if 'CA_CERTIFICATE' in current_app.config:
        # If you specified a CA certificate, we assume it isn't a CA trusted by Apple devices.
        ca_payload = ca_trust_payload_from_configuration()
        profile.payloads.append(ca_payload)

    if 'SSL_CERTIFICATE' in current_app.config:
        basepath = os.path.dirname(__file__)
        certpath = os.path.join(basepath,
                                current_app.config['SSL_CERTIFICATE'])
        with open(certpath, 'rb') as fd:
            pem_payload = PEMCertificatePayload(
                uuid=uuid4(),
                identifier=org.payload_prefix + '.ssl',
                payload_content=fd.read(),
                display_name='Web Server Certificate',
                description='Required for your device to trust the server',
                type='com.apple.security.pkcs1',
                version=1)
            profile.payloads.append(pem_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,
        'Content-Disposition': 'attachment; filename="trust.mobileconfig"'
    }
Exemplo n.º 3
0
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}
Exemplo n.º 4
0
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}