Example #1
0
 def get(self, request, *args, **kwargs):
     ota_enrollment = get_object_or_404(OTAEnrollment, pk=kwargs["pk"])
     if not ota_enrollment.enrollment_secret.is_valid():
         # should not happen
         raise SuspiciousOperation
     return build_payload_response(sign_payload_openssl(build_profile_service_payload(ota_enrollment)),
                                   "zentral_profile_service")
Example #2
0
    def post(self, request, *args, **kwargs):
        # Verify payload signature, extract signed payload
        try:
            certificates, payload = verify_signed_payload(request.read())
        except ValueError as error:
            self.abort("posted data is not signed", signature_error=str(error))

        for certificate_i_cn, certificate_bytes, signing_certificate in certificates:
            if verify_apple_iphone_device_ca_issuer_openssl(certificate_bytes):
                break

        payload = plistlib.loads(payload)
        self.serial_number = payload["SERIAL"]
        self.udid = payload["UDID"]

        try:
            es_request = verify_enrollment_secret(
                "dep_profile", self.kwargs["dep_profile_secret"],
                self.user_agent, self.ip, self.serial_number, self.udid)
        except EnrollmentSecretVerificationFailed as e:
            self.abort("secret verification failed: '{}'".format(e.err_msg))

        # Start a DEP enrollment session
        dep_enrollment_session = DEPEnrollmentSession.objects.create_from_dep_profile(
            es_request.enrollment_secret.dep_profile, self.serial_number,
            self.udid, payload)

        # Get the MDM push certificate
        push_certificate = (
            dep_enrollment_session.enrollment_secret.meta_business_unit.
            metabusinessunitpushcertificate.push_certificate)

        payload = build_mdm_payload(dep_enrollment_session, push_certificate)
        filename = "zentral_mdm"
        self.post_event("success",
                        **dep_enrollment_session.serialize_for_event())
        return build_payload_response(sign_payload_openssl(payload), filename)
Example #3
0
 def get(self, request, *args, **kwargs):
     return build_payload_response(
         sign_payload_openssl(build_root_ca_configuration_profile()),
         "zentral_root_ca")
Example #4
0
    def post(self, request, *args, **kwargs):
        # Verify payload signature, extract signed payload
        try:
            certificates, payload = verify_signed_payload(request.read())
        except ValueError:
            self.abort("posted data is not signed")

        # find out which CA signed the certificate used to sign the payload
        # if iPhone CA: phase 2
        # if SCEP CA: phase 3
        # if unknown: phase 2  # TODO: verify. seen with self signed cert in 10.13 beta in VMWare.
        for certificate_i_cn, certificate_bytes, signing_certificate in certificates:
            if verify_apple_iphone_device_ca_issuer_openssl(certificate_bytes):
                phase = 2
                break
            elif verify_zentral_scep_ca_issuer_openssl(certificate_bytes):
                phase = 3
                break
            else:
                self.post_event(
                    "warning",
                    reason="unknown signing certificate issuer '{}'".format(
                        certificate_i_cn))
                phase = 2

        payload = plistlib.loads(payload)
        self.serial_number = payload["SERIAL"]
        self.udid = payload["UDID"]

        if phase == 2:
            # Verify the challenge
            challenge = payload.get("CHALLENGE")
            if not challenge:
                self.abort("missing challenge", phase=phase)
            try:
                es_request = verify_enrollment_secret("ota_enrollment",
                                                      challenge,
                                                      self.user_agent, self.ip,
                                                      self.serial_number,
                                                      self.udid)
            except EnrollmentSecretVerificationFailed as e:
                self.abort("secret verification failed: '{}'".format(
                    e.err_msg),
                           phase=phase)

            # Start an OTA enrollment session
            ota_enrollment_session = OTAEnrollmentSession.objects.create_from_ota_enrollment(
                es_request.enrollment_secret.ota_enrollment,
                self.serial_number, self.udid, payload)

            payload = build_ota_scep_payload(ota_enrollment_session)
            filename = "zentral_ota_scep"

        elif phase == 3:
            # get the serial number from the DN of the payload signing certificate
            serial_number = signing_certificate.subject.get_attributes_for_oid(
                NameOID.SERIAL_NUMBER)[0].value
            if self.serial_number != serial_number:
                self.abort(
                    "signing certificate DN serial number != payload serial number",
                    phase=phase)

            # get the ota enrollment session from the DN of the payload signing certificate
            cn = signing_certificate.subject.get_attributes_for_oid(
                NameOID.COMMON_NAME)[0].value
            _, ota_enrollment_session_secret = cn.split("$")
            try:
                ota_enrollment_session = (
                    OTAEnrollmentSession.objects.select_for_update(
                    ).select_related("ota_enrollment",
                                     "enrollment_secret__meta_business_unit").
                    get(enrollment_secret__secret=ota_enrollment_session_secret
                        ))
            except OTAEnrollmentSession.DoesNotExist:
                self.abort(
                    "could not find ota enrollment session from payload signing certificate",
                    phase=phase)

            # verify and update ota enrollment session status
            try:
                ota_enrollment_session.set_phase3_status()
            except EnrollmentSessionStatusError:
                self.abort("ota enrollment session has wrong status",
                           phase=phase)

            # verify DN mbu
            ota_enrollment_session_mbu = ota_enrollment_session.enrollment_secret.meta_business_unit
            o = signing_certificate.subject.get_attributes_for_oid(
                NameOID.ORGANIZATION_NAME)[0]
            if int(o.value.split("$")[-1]) != ota_enrollment_session_mbu.pk:
                self.abort("DN mbu doesn't match ota enrollment session mbu",
                           phase=phase)

            # Get the MDM push certificate
            push_certificate = ota_enrollment_session_mbu.metabusinessunitpushcertificate.push_certificate

            payload = build_mdm_payload(ota_enrollment_session,
                                        push_certificate)
            filename = "zentral_mdm"

        self.post_event("success", phase=phase)

        return build_payload_response(sign_payload_openssl(payload), filename)
        return HttpResponse()