Esempio n. 1
0
 def get(self, request, *args, **kwargs):
     ota_enrollment = get_object_or_404(OTAEnrollment,
                                        pk=kwargs["pk"],
                                        realm__isnull=False)
     if not ota_enrollment.enrollment_secret.is_valid():
         # should not happen
         raise SuspiciousOperation
     # check the auth
     try:
         realm_user_pk = self.request.session.pop(
             "_ota_{}_realm_user_pk".format(ota_enrollment.pk))
         realm_user = RealmUser.objects.get(realm=ota_enrollment.realm,
                                            pk=realm_user_pk)
     except (KeyError, RealmUser.DoesNotExist):
         # start realm auth session, do redirect
         callback = "zentral.contrib.mdm.views.management.ota_enroll_callback"
         callback_kwargs = {"ota_enrollment_pk": ota_enrollment.pk}
         return HttpResponseRedirect(
             ota_enrollment.realm.backend_instance.initialize_session(
                 request, callback, **callback_kwargs))
     else:
         ota_enrollment_session = OTAEnrollmentSession.objects.create_from_realm_user(
             ota_enrollment, realm_user)
         # start OTAEnrollmentSession, build config profile, return config profile
         return build_configuration_profile_response(
             build_profile_service_configuration_profile(
                 ota_enrollment_session), "zentral_profile_service")
Esempio n. 2
0
 def post(self, request, *args, **kwargs):
     self.verify_enrollment_secret()
     authorization = request.headers.get("Authorization")
     if not authorization:
         user_enrollment_session = UserEnrollmentSession.objects.create_from_user_enrollment(
             self.user_enrollment)
         url = "https://{}{}".format(
             settings["api"]["fqdn"],
             reverse(
                 "mdm:authenticate_user",
                 args=(user_enrollment_session.enrollment_secret.secret, )))
         response = HttpResponse("Unauthorized", status=401)
         response[
             "WWW-Authenticate"] = f'Bearer method="apple-as-web" url="{url}"'
         self.post_event("success",
                         **user_enrollment_session.serialize_for_event())
         return response
     else:
         access_token = authorization.replace("Bearer", "").strip()
         try:
             user_enrollment_session = UserEnrollmentSession.objects.get(
                 user_enrollment=self.user_enrollment,
                 access_token=access_token)
         except UserEnrollmentSession.DoesNotExist:
             self.abort("Invalid access token")
         user_enrollment_session.set_started_status()
         configuration_profile = build_mdm_configuration_profile(
             user_enrollment_session, self.user_enrollment.push_certificate)
         configuration_profile_filename = "zentral_mdm"
         self.post_event("success",
                         **user_enrollment_session.serialize_for_event())
         return build_configuration_profile_response(
             configuration_profile, configuration_profile_filename)
Esempio n. 3
0
 def form_valid(self, form):
     managed_apple_id = form.cleaned_data["managed_apple_id"]
     user_enrollment_session = UserEnrollmentSession.objects.create_from_user_enrollment(
         self.user_enrollment, managed_apple_id)
     return build_configuration_profile_response(
         build_mdm_configuration_profile(
             user_enrollment_session,
             self.user_enrollment.push_certificate),
         "zentral_user_enrollment")
Esempio n. 4
0
 def build_mdm_configuration_profile_response(self, dep_enrollment_session):
     configuration_profile = build_mdm_configuration_profile(
         dep_enrollment_session,
         dep_enrollment_session.dep_enrollment.push_certificate)
     configuration_profile_filename = "zentral_mdm"
     self.post_event("success",
                     **dep_enrollment_session.serialize_for_event())
     return build_configuration_profile_response(
         configuration_profile, configuration_profile_filename)
Esempio n. 5
0
 def get(self, request, *args, **kwargs):
     ota_enrollment = get_object_or_404(OTAEnrollment,
                                        pk=kwargs["pk"],
                                        realm__isnull=True)
     if not ota_enrollment.enrollment_secret.is_valid():
         # should not happen
         raise SuspiciousOperation
     return build_configuration_profile_response(
         build_profile_service_configuration_profile(ota_enrollment),
         "zentral_profile_service")
Esempio n. 6
0
    def build_mdm_configuration_profile_response(self, dep_enrollment_session):
        # Get the MDM push certificate
        push_certificate = (
            dep_enrollment_session.enrollment_secret.meta_business_unit.
            metabusinessunitpushcertificate.push_certificate)

        configuration_profile = build_mdm_configuration_profile(
            dep_enrollment_session, push_certificate)
        configuration_profile_filename = "zentral_mdm"
        self.post_event("success",
                        **dep_enrollment_session.serialize_for_event())
        return build_configuration_profile_response(
            configuration_profile, configuration_profile_filename)
Esempio n. 7
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)

        configuration_profile = build_mdm_configuration_profile(
            dep_enrollment_session, push_certificate)
        configuration_profile_filename = "zentral_mdm"
        self.post_event("success",
                        **dep_enrollment_session.serialize_for_event())
        return build_configuration_profile_response(
            configuration_profile, configuration_profile_filename)
Esempio n. 8
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
        for certificate_i_cn, certificate_bytes, signing_certificate in certificates:
            if verify_apple_iphone_device_ca_issuer(certificate_bytes):
                phase = 2
                break
            elif verify_zentral_scep_ca_issuer(certificate_bytes):
                phase = 3
                break
        else:
            self.abort(
                f"Unknown signing certificate issuer: {certificate_i_cn}")

        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)

            # Pre-authenticated session ?
            session_enrollment = kwargs.pop("session")
            if session_enrollment:
                # running off a realm user authenticated existing ota enrollment session
                try:
                    es_request = verify_enrollment_secret(
                        "ota_enrollment_session", 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)

                ota_enrollment_session = es_request.enrollment_secret.ota_enrollment_session

                # for PostEventMixin
                self.realm_user = ota_enrollment_session.realm_user

                # update the OTA enrollment session
                ota_enrollment_session.set_phase2_status(
                    es_request, self.serial_number, self.udid)

            else:
                # running off a simple ota enrollment
                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)

                ota_enrollment = es_request.enrollment_secret.ota_enrollment
                if ota_enrollment.realm:
                    self.abort(
                        "cannot use ota enrollment secret on ota enrollment with realm",
                        phase=phase)

                # Start an OTA enrollment session directly in phase 2
                ota_enrollment_session = OTAEnrollmentSession.objects.create_from_machine_info(
                    ota_enrollment, self.serial_number, self.udid)

            configuration_profile = build_ota_scep_configuration_profile(
                ota_enrollment_session)
            configuration_profile_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)

            # for PostEventMixin
            self.realm_user = ota_enrollment_session.realm_user

            # 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.ota_enrollment.push_certificate

            configuration_profile = build_mdm_configuration_profile(
                ota_enrollment_session, push_certificate)
            configuration_profile_filename = "zentral_mdm"

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

        return build_configuration_profile_response(
            configuration_profile, configuration_profile_filename)
Esempio n. 9
0
 def get(self, request, *args, **kwargs):
     return build_configuration_profile_response(
         build_root_ca_configuration_profile(), "zentral_root_ca")