Esempio n. 1
0
    def post(self, request, *args, **kwargs):
        user_agent, ip = user_agent_and_ip_address_from_request(request)
        try:
            request_json = json.loads(request.body.decode("utf-8"))
            secret = request_json["secret"]
            serial_number = request_json["serial_number"]
            uuid = request_json["uuid"]
            es_request = verify_enrollment_secret("munki_enrollment", secret,
                                                  user_agent, ip,
                                                  serial_number, uuid)
        except (KeyError, ValueError, EnrollmentSecretVerificationFailed):
            raise SuspiciousOperation
        else:
            # get or create enrolled machine
            enrolled_machine, enrolled_machine_created = EnrolledMachine.objects.get_or_create(
                enrollment=es_request.enrollment_secret.munki_enrollment,
                serial_number=serial_number,
                defaults={"token": get_random_string(64)})

            # apply enrollment secret tags
            for tag in es_request.enrollment_secret.tags.all():
                MachineTag.objects.get_or_create(serial_number=serial_number,
                                                 tag=tag)

            # post event
            post_munki_enrollment_event(
                serial_number, user_agent, ip, {
                    'action':
                    "enrollment"
                    if enrolled_machine_created else "re-enrollment"
                })
            return JsonResponse({"token": enrolled_machine.token})
Esempio n. 2
0
def login(request):
    """
    Displays the login form and handles the login action.
    """
    redirect_to = request.POST.get(REDIRECT_FIELD_NAME,
                                   request.GET.get(REDIRECT_FIELD_NAME, ''))

    if request.method == "POST":
        form = ZentralAuthenticationForm(request, data=request.POST)
        if form.is_valid():
            user = form.get_user()

            # Ensure the user-originating redirection url is safe.
            if not is_safe_url(url=redirect_to,
                               allowed_hosts={request.get_host()},
                               require_https=request.is_secure()):
                redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)

            if user.has_verification_device:
                # Redirect to verification page
                token = signing.dumps(
                    {
                        "auth_backend": user.backend,
                        "redirect_to": redirect_to,
                        "user_id": user.id
                    },
                    salt="zentral_verify_token",
                    key=settings.SECRET_KEY)
                request.session["verification_token"] = token
                user_agent, _ = user_agent_and_ip_address_from_request(request)
                try:
                    verification_device = user.get_prioritized_verification_devices(
                        user_agent)[0]
                except ValueError:
                    form.add_error(
                        None,
                        "No configured verification devices compatible with your current browser."
                    )
                else:
                    return HttpResponseRedirect(
                        verification_device.get_verification_url())
            else:
                # Okay, security check complete. Log the user in.
                auth_login(request, form.get_user())

                return HttpResponseRedirect(redirect_to)
    else:
        form = ZentralAuthenticationForm(request)

    context = {
        'form':
        form,
        'login_realms':
        [(r, reverse("realms:zentral_login", args=(r.pk, )))
         for r in Realm.objects.filter(enabled_for_login=True)],
        REDIRECT_FIELD_NAME:
        redirect_to,
    }

    return TemplateResponse(request, "registration/login.html", context)
Esempio n. 3
0
 def post(self, request, *args, **kwargs):
     self.enrollment_secret_secret = kwargs["enrollment_secret"]
     try:
         self.hardware_uuid = str(UUID(kwargs["machine_id"]))
     except ValueError:
         raise PermissionDenied("Invalid machine id")
     try:
         self.enrolled_machine = EnrolledMachine.objects.select_related(
             "enrollment__secret", "enrollment__configuration").get(
                 enrollment__secret__secret=self.enrollment_secret_secret,
                 hardware_uuid=self.hardware_uuid)
     except EnrolledMachine.DoesNotExist:
         if self.require_enrolled_machine:
             raise PermissionDenied("Unknown machine")
         self.enrolled_machine = None
     else:
         if self.enrolled_machine.enrollment.configuration.client_certificate_auth and \
            self.get_client_cert() is None:
             raise PermissionDenied("Missing client certificate")
         self.machine_serial_number = self.enrolled_machine.serial_number
         self.business_unit = self.enrolled_machine.enrollment.secret.get_api_enrollment_business_unit(
         )
     data = self._get_json_data(request)
     self.user_agent, self.ip = user_agent_and_ip_address_from_request(
         request)
     return JsonResponse(self.do_post(data))
Esempio n. 4
0
    def dispatch(self, request, *args, **kwargs):
        try:
            token = request.META['HTTP_X_MONOLITH_TOKEN'].strip()
            api_data = verify_secret(token, 'zentral.contrib.monolith')
        except (KeyError, ValueError, APIAuthError):
            return HttpResponseForbidden("No no no!")

        # machine serial number
        h_msn = request.META.get("HTTP_X_ZENTRAL_SERIAL_NUMBER")  # new way
        t_msn = api_data.get("machine_serial_number")  # old way
        if h_msn and t_msn and h_msn != t_msn:
            logger.warning("Serial number mismatch. header: %s, token: %s",
                           h_msn, t_msn)
        self.machine_serial_number = h_msn or t_msn  # priority to h_msn because set in preflight script

        # business unit, manifest
        self.meta_business_unit = api_data['business_unit'].meta_business_unit
        self.manifest = get_object_or_404(
            Manifest, meta_business_unit=self.meta_business_unit)

        self.user_agent, self.ip = user_agent_and_ip_address_from_request(
            request)

        # machine extra infos
        self.machine = MetaMachine(self.machine_serial_number)
        self.tags = self.machine.tags

        if not self.machine_serial_number:
            logger.warning("Missing serial number. mbu: %s %s",
                           self.meta_business_unit, self.meta_business_unit.pk)

        return super().dispatch(request, *args, **kwargs)
Esempio n. 5
0
    def post(self, request, *args, **kwargs):
        self.user_agent, self.ip = user_agent_and_ip_address_from_request(request)
        try:
            request_json = json.loads(request.body.decode("utf-8"))
            secret = request_json["secret"]
            serial_number = request_json["serial_number"]
            es_request = verify_enrollment_secret(
                "filebeat_enrollment", secret,
                self.user_agent, self.ip,
                serial_number
            )
        except (ValueError, KeyError, EnrollmentSecretVerificationFailed):
            raise SuspiciousOperation
        else:
            enrollment_session = EnrollmentSession.objects.create_from_enrollment(
                enrollment=es_request.enrollment_secret.filebeat_enrollment,
                serial_number=serial_number
            )
            # response
            response = {
                "scep": {
                    "cn": enrollment_session.get_common_name(),
                    "org": enrollment_session.get_organization(),
                    "challenge": enrollment_session.get_challenge(),
                    "url": "{}/scep".format(settings["api"]["tls_hostname"]),  # TODO: hardcoded scep url
                },
                "secret": enrollment_session.enrollment_secret.secret,
            }

            # post event
            post_enrollment_event(serial_number, self.user_agent, self.ip, enrollment_session.serialize_for_event())
        return JsonResponse(response)
Esempio n. 6
0
 def get_form_kwargs(self):
     kwargs = super().get_form_kwargs()
     request = self.request
     user_agent, _ = user_agent_and_ip_address_from_request(request)
     kwargs["session"] = request.session
     kwargs["user_agent"] = user_agent
     return kwargs
Esempio n. 7
0
 def post(self, request, *args, **kwargs):
     try:
         if request.META.get("HTTP_CONTENT_ENCODING") == "gzip":
             self.data = json.load(GzipFile(fileobj=request))
         else:
             self.data = json.loads(request.body)
     except ValueError:
         raise SuspiciousOperation("Could not read JSON data")
     self.user_agent, self.ip = user_agent_and_ip_address_from_request(request)
     self.authenticate()
     return JsonResponse(self.do_post())
Esempio n. 8
0
 def dispatch(self, request, *args, **kwargs):
     try:
         token = request.META['HTTP_X_MONOLITH_TOKEN'].strip()
         api_data = verify_secret(token, 'zentral.contrib.monolith')
     except (KeyError, ValueError, APIAuthError):
         return HttpResponseForbidden("No no no!")
     self.machine_serial_number = api_data.get("machine_serial_number", None)
     self.user_agent, self.ip = user_agent_and_ip_address_from_request(request)
     self.machine = MetaMachine(self.machine_serial_number)
     self.tags = self.machine.tags
     self.meta_business_unit = api_data['business_unit'].meta_business_unit
     self.manifest = get_object_or_404(Manifest, meta_business_unit=self.meta_business_unit)
     return super().dispatch(request, *args, **kwargs)
Esempio n. 9
0
 def post(self, request, *args, **kwargs):
     try:
         instance = puppet_conf.get_instance_with_secret(kwargs["secret"])
     except APIAuthError:
         return HttpResponseForbidden("Forbidden")
     except KeyError:
         return HttpResponseNotFound("Unknown puppet instance")
     user_agent, ip = user_agent_and_ip_address_from_request(request)
     if not request.encoding or request.encoding.lower() != "utf-8":
         return HttpResponse("Unsupported encoding", status=415)
     payload = request.body.decode(request.encoding)
     post_puppet_report(instance, user_agent, ip, payload)
     return HttpResponse("OK")
Esempio n. 10
0
    def post(self, request, *args, **kwargs):
        # DN => serial_number + meta_business_unit
        dn = request.META.get("HTTP_X_SSL_CLIENT_S_DN")
        if not dn:
            raise SuspiciousOperation("missing DN in request headers")

        dn_d = parse_dn(dn)

        cn = dn_d.get("CN")
        try:
            cn_prefix, enrollment_secret_secret = cn.split("$")
        except (AttributeError, ValueError):
            raise SuspiciousOperation("missing or bad CN in client certificate DN")

        # verify prefix
        if cn_prefix != "FLBT":
            raise SuspiciousOperation("bad CN prefix in client certificate")

        self.user_agent, self.ip = user_agent_and_ip_address_from_request(request)
        try:
            request_json = json.loads(request.body.decode("utf-8"))
            secret = request_json["secret"]
            serial_number = request_json["serial_number"]
            es_request = verify_enrollment_secret(
                "filebeat_enrollment_session", secret,
                self.user_agent, self.ip,
                serial_number,
                filebeat_enrollment_session__status__in=(EnrollmentSession.STARTED, EnrollmentSession.SCEP_VERIFIED)
            )
            certificate = request_json["certificate"]
            key = request_json["key"]
            certificate_authority = request_json["certificate_authority"]
        except (ValueError, KeyError, EnrollmentSecretVerificationFailed):
            raise SuspiciousOperation("Could not verify enrollment session secret")
        else:
            # update enrollment session
            enrollment_session = es_request.enrollment_secret.filebeat_enrollment_session
            enrolled_machine, _ = EnrolledMachine.objects.get_or_create(serial_number=serial_number)
            enrollment_session.set_completed(enrolled_machine)
            # apply enrollment secret tags
            for tag in es_request.enrollment_secret.tags.all():
                MachineTag.objects.get_or_create(serial_number=serial_number, tag=tag)
            # post event
            post_enrollment_event(serial_number, self.user_agent, self.ip, enrollment_session.serialize_for_event())
            # response
            response = {
                "filebeat.yml": build_filebeat_yml(enrollment_session.enrollment.configuration,
                                                   certificate=certificate, key=key,
                                                   certificate_authority=certificate_authority)
            }
            return JsonResponse(response)
Esempio n. 11
0
 def post(self, request, *args, **kwargs):
     self.user_agent, self.ip = user_agent_and_ip_address_from_request(
         request)
     self.load_token(request)
     self.load_event(request)
     try:
         self.enrolled_machine = EnrolledMachine.objects.select_related(
             "enrollment__secret__meta_business_unit").get(
                 enrollment__secret__secret=self.token,
                 serial_number=self.serial_number)
     except EnrolledMachine.DoesNotExist:
         self.enroll_machine()
     self.commit_machine_snapshot()
     post_event(self.serial_number, self.user_agent, self.ip, self.event)
     return HttpResponse("OK")
Esempio n. 12
0
    def post(self, request, *args, **kwargs):
        self.user_agent, self.ip = user_agent_and_ip_address_from_request(
            request)
        try:
            request_json = json.loads(request.body.decode("utf-8"))
            secret = request_json["secret"]
            serial_number = request_json["serial_number"]
            uuid = request_json["uuid"]
            es_request = verify_enrollment_secret("santa_enrollment", secret,
                                                  self.user_agent, self.ip,
                                                  serial_number, uuid)
        except (ValueError, KeyError, EnrollmentSecretVerificationFailed):
            raise SuspiciousOperation
        else:
            # get or create enrolled machine
            enrolled_machine, enrolled_machine_created = EnrolledMachine.objects.get_or_create(
                enrollment=es_request.enrollment_secret.santa_enrollment,
                serial_number=serial_number,
                defaults={"machine_id": get_random_string(64)})

            # apply enrollment secret tags
            for tag in es_request.enrollment_secret.tags.all():
                MachineTag.objects.get_or_create(serial_number=serial_number,
                                                 tag=tag)

            # response
            response = {"machine_id": enrolled_machine.machine_id}
            cp_name, cp_content = build_configuration_profile(enrolled_machine)
            cp_content = base64.b64encode(cp_content).decode("utf-8")
            response["configuration_profile"] = {
                "name": cp_name,
                "content": cp_content
            }
            cpl_name, cpl_content = build_config_plist(enrolled_machine)
            response["config_plist"] = {
                "name": cpl_name,
                "content": cpl_content
            }

            # post event
            post_enrollment_event(
                serial_number, self.user_agent, self.ip, {
                    'action':
                    "enrollment"
                    if enrolled_machine_created else "re-enrollment"
                })
        return JsonResponse(response)
Esempio n. 13
0
 def post(self, request, *args, **kwargs):
     manifest = get_object_or_404(Manifest, pk=kwargs["pk"])
     serializer = CacheServerSerializer(data=request.data)
     try:
         serializer.is_valid(raise_exception=True)
     except ValidationError as e:
         post_monolith_cache_server_update_request(request, errors=e.detail)
         raise
     defaults = serializer.data.copy()
     name = defaults.pop("name")
     _, public_ip_address = user_agent_and_ip_address_from_request(request)
     defaults["public_ip_address"] = public_ip_address
     cache_server, _ = CacheServer.objects.update_or_create(
         manifest=manifest, name=name, defaults=defaults)
     post_monolith_cache_server_update_request(request,
                                               cache_server=cache_server)
     return Response({"status": 0})
Esempio n. 14
0
    def post(self, request, *args, **kwargs):
        # URL kwargs
        self.enrollment_secret_secret = kwargs["enrollment_secret"]
        try:
            self.hardware_uuid = str(UUID(kwargs["machine_id"]))
        except ValueError:
            raise PermissionDenied("Invalid machine id")

        self.client_cert_dn = self._get_client_cert_dn()

        self.user_agent, self.ip = user_agent_and_ip_address_from_request(
            request)

        self.request_data = self._get_json_data(request)

        self.cache_key = f"tests/santa/fixtures/{self.enrollment_secret_secret}{self.hardware_uuid}"
        self.enrolled_machine = None
        self.tag_ids = []
        if self.use_enrolled_machine_cache:
            try:
                self.enrolled_machine, self.tag_ids = cache.get(self.cache_key)
            except TypeError:
                pass
            else:
                if self.enrolled_machine.enrollment.configuration.client_certificate_auth and not self.client_cert_dn:
                    raise PermissionDenied("Missing client certificate")
        if not self.enrolled_machine:
            self.enrolled_machine = self.get_enrolled_machine()
            if not self.enrolled_machine:
                raise PermissionDenied("Machine not enrolled")
            meta_machine = MetaMachine(self.enrolled_machine.serial_number)
            self.tag_ids = [t.id for t in meta_machine.tags]
            cache.set(self.cache_key, (self.enrolled_machine, self.tag_ids),
                      600)  # TODO cache timeout hardcoded

        return JsonResponse(self.do_post())
Esempio n. 15
0
 def build_from_request(cls, request):
     user_agent, ip = user_agent_and_ip_address_from_request(request)
     user = EventRequestUser.build_from_user(request.user)
     if user_agent or ip or user:
         return EventRequest(user_agent, ip, user)
Esempio n. 16
0
 def dispatch(self, request, *args, **kwargs):
     self.user_agent, self.ip = user_agent_and_ip_address_from_request(
         request)
     self.serial_number = self.udid = None
     return super().dispatch(request, *args, **kwargs)
Esempio n. 17
0
 def setup_with_request(self, request):
     if not self._setup_done:
         self.user_agent, self.ip = user_agent_and_ip_address_from_request(request)
         self.serial_number = self.udid = None
         self.realm_user = None
         self._setup_done = True