예제 #1
0
def token_update(plist_data):
    current_app.logger.debug('TokenUpdate (UDID %s)',
                             plist_data.get('UDID', None))
    try:
        device = db.session.query(Device).filter(
            Device.udid == plist_data['UDID']).one()
    except NoResultFound:
        current_app.logger.debug(
            'Device (UDID: %s) will be unenrolled because the database has no record of this device.',
            plist_data['UDID'])
        return abort(
            410
        )  # Ask the device to unenroll itself because we dont seem to have any records.

    # TODO: a TokenUpdate can either be for a device or a user (per OS X extensions)
    if 'UserID' in plist_data:
        device_user = DeviceUser()
        return 'OK'

    if not device.token:  # First contact
        device.is_enrolled = True

        if hasattr(g, 'signers'):
            device_certificate = DeviceIdentityCertificate.from_crypto(
                g.signers[0])
            db.session.add(device_certificate)
            device.certificate = device_certificate
        else:
            pass  # TODO: if in debug mode this should not throw an exception to deal with cert troubleshooting

        device_enrolled.send(device)
        queue_full_inventory(device)

    device.tokenupdate_at = datetime.utcnow()
    device.push_magic = plist_data['PushMagic']
    device.topic = plist_data['Topic']
    device.token = plist_data['Token']
    device.unlock_token = plist_data.get('UnlockToken', None)
    device.last_seen = datetime.now()
    db.session.commit()

    try:
        response = push_to_device(device)
    except ssl.SSLError:
        return abort(
            jsonify(error=True, message="The push certificate has expired"))

    current_app.logger.info(
        "[APNS2 Response] Status: %d, Reason: %s, APNS ID: %s, Timestamp",
        response.status_code, response.reason,
        response.apns_id.decode('utf-8'))
    device.last_push_at = datetime.utcnow()
    if response.status_code == 200:
        device.last_apns_id = response.apns_id

    db.session.commit()

    # TODO: macOS can chain commands from TokenUpdate but iOS will not process any response data from TokenUpdate.
    # Therefore, it is necessary to issue a Push here instead of simply responding with the next command.
    return 'OK'
예제 #2
0
def token_update(plist_data):
    current_app.logger.debug('TokenUpdate (UDID %s)',
                             plist_data.get('UDID', None))
    try:
        device = db.session.query(Device).filter(
            Device.udid == plist_data['UDID']).one()
    except NoResultFound:
        current_app.logger.debug(
            'Device (UDID: %s) will be unenrolled because the database has no record of this device.',
            plist_data['UDID'])
        return abort(
            410
        )  # Ask the device to unenroll itself because we dont seem to have any records.

    # TODO: a TokenUpdate can either be for a device or a user (per OS X extensions)
    if 'UserID' in plist_data:
        device_user = DeviceUser()
        return 'OK'

    if not device.token:  # First contact
        device.is_enrolled = True

        if hasattr(g, 'signers'):
            device_certificate = DeviceIdentityCertificate.from_crypto(
                g.signers[0])
            db.session.add(device_certificate)
            device.certificate = device_certificate
        else:
            pass  # TODO: if in debug mode this should not throw an exception to deal with cert troubleshooting

        device_enrolled.send(device)
        queue_full_inventory(device)

    device.tokenupdate_at = datetime.utcnow()
    device.push_magic = plist_data.get('PushMagic', None)
    device.topic = plist_data.get('Topic', None)
    device.token = plist_data.get('Token', None)
    device.unlock_token = plist_data.get('UnlockToken', None)
    device.last_seen = datetime.now()
    db.session.commit()

    # TODO: DRY
    command = DBCommand.next_command(device)

    if not command:
        current_app.logger.info('no further MDM commands for device=%d',
                                device.id)
        return ''

    # mark this command as being in process right away to (try) to avoid
    # any race conditions with mutliple MDM commands from the same device
    # at a time

    #command.set_processing()
    #db.session.commit()

    # Re-hydrate the command class based on the persisted model containing the request type and the parameters
    # that were given to generate the command
    cmd = Command.new_request_type(command.request_type, command.parameters,
                                   command.uuid)

    # get command dictionary representation (e.g. the full command to send)
    output_dict = cmd.to_dict()

    current_app.logger.info('sending %s MDM command class=%s to device=%d',
                            cmd.request_type, command.request_type, device.id)

    current_app.logger.debug(output_dict)

    command.status = CommandStatus.Sent
    command.sent_at = datetime.utcnow()
    db.session.commit()

    return plistify(output_dict)
예제 #3
0
def token_update(plist_data):
    current_app.logger.info('TokenUpdate received')
    # TODO: check to make sure device == UDID == cert, etc.
    device = db.session.query(Device).filter(
        Device.udid == plist_data['UDID']).one()

    # TODO: a TokenUpdate can either be for a device or a user (per OS X extensions)
    if 'UserID' in plist_data:
        device_user = DeviceUser()
        return 'OK'

    if not device.token:  # First contact
        device.is_enrolled = True
        device_certificate = DeviceIdentityCertificate.from_crypto(
            g.signers[0])
        db.session.add(device_certificate)
        device.certificate = device_certificate
        device_enrolled.send(device)
        queue_full_inventory(device)

    device.tokenupdate_at = datetime.utcnow()

    if 'PushMagic' in plist_data:
        device.push_magic = plist_data['PushMagic']

    if 'Topic' in plist_data:
        device.topic = plist_data['Topic']

    if 'Token' in plist_data:
        device.token = plist_data['Token']
    else:
        current_app.logger.error('TokenUpdate message missing Token')
        abort(400, 'invalid data supplied')

    if 'UnlockToken' in plist_data:
        device.unlock_token = plist_data['UnlockToken']

    device.last_seen = datetime.now()
    db.session.commit()

    # TODO: DRY
    while True:
        command = DBCommand.get_next_device_command(device)

        if not command:
            break

        # mark this command as being in process right away to (try) to avoid
        # any race conditions with mutliple MDM commands from the same device
        # at a time

        #command.set_processing()
        #db.session.commit()

        # Re-hydrate the command class based on the persisted model containing the request type and the parameters
        # that were given to generate the command
        cmd = Command.new_request_type(command.request_type,
                                       command.parameters, command.uuid)

        # get command dictionary representation (e.g. the full command to send)
        output_dict = cmd.to_dict()

        current_app.logger.info('sending %s MDM command class=%s to device=%d',
                                cmd.request_type, command.request_type,
                                device.id)

        current_app.logger.debug(output_dict)
        # convert to plist and send
        plist_data = plistlib.dumps(output_dict)
        current_app.logger.debug(plist_data)
        resp = make_response(plist_data)
        resp.headers['Content-Type'] = 'application/xml'

        # finally set as sent
        command.status = CommandStatus.Sent.value
        command.sent_at = datetime.utcnow()
        db.session.commit()

        return resp