Ejemplo n.º 1
0
    def finalize_log(self):
        """
        This method is used to log the data.
        It should hash the data and do a hash chain and sign the data
        """
        try:
            self.audit_data["policies"] = ",".join(self.audit_data.get("policies",[]))
            if self.config.get("PI_AUDIT_SQL_TRUNCATE"):
                self._truncate_data()
            le = LogEntry(action=self.audit_data.get("action"),
                          success=int(self.audit_data.get("success", 0)),
                          serial=self.audit_data.get("serial"),
                          token_type=self.audit_data.get("token_type"),
                          user=self.audit_data.get("user"),
                          realm=self.audit_data.get("realm"),
                          resolver=self.audit_data.get("resolver"),
                          administrator=self.audit_data.get("administrator"),
                          action_detail=self.audit_data.get("action_detail"),
                          info=self.audit_data.get("info"),
                          privacyidea_server=self.audit_data.get("privacyidea_server"),
                          client=self.audit_data.get("client", ""),
                          loglevel=self.audit_data.get("log_level"),
                          clearance_level=self.audit_data.get("clearance_level"),
                          policies=self.audit_data.get("policies")
                          )
            self.session.add(le)
            self.session.commit()
            # Add the signature
            if self.sign_data and self.sign_object:
                s = self._log_to_string(le)
                sign = self.sign_object.sign(s)
                le.signature = sign
                self.session.merge(le)
                self.session.commit()
        except Exception as exx:  # pragma: no cover
            # in case of a Unicode Error in _log_to_string() we won't have
            # a signature, but the log entry is available
            log.error("exception {0!r}".format(exx))
            log.error("DATA: {0!s}".format(self.audit_data))
            log.debug("{0!s}".format(traceback.format_exc()))
            self.session.rollback()

        finally:
            self.session.close()
            # clear the audit data
            self.audit_data = {}
Ejemplo n.º 2
0
    def test_03_get_allowed_audit_realm(self):
        # Check than an internal admin is allowed to see all realms
        # A helpdesk user in "adminrealm" is only allowerd to see realm1A
        Audit(action="enroll", success=1, realm="realm1a").save()
        Audit(action="enroll", success=1, realm="realm1a").save()
        Audit(action="enroll", success=1, realm="realm2b").save()
        Audit(action="enroll", success=1, realm="realm2b").save()
        Audit(action="enroll", success=1, realm="realm2b").save()

        # check, that we see all audit entries
        with self.app.test_request_context('/audit/',
                                           method='GET',
                                           data={"realm": "realm1a"},
                                           headers={'Authorization': self.at}):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            json_response = res.json
            self.assertTrue(json_response.get("result").get("status"), res)
            self.assertEqual(
                json_response.get("result").get("value").get("count"), 5)

        with self.app.test_request_context('/audit/',
                                           method='GET',
                                           data={"realm": "realm2b"},
                                           headers={'Authorization': self.at}):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            json_response = res.json
            self.assertTrue(json_response.get("result").get("status"), res)
            self.assertEqual(
                json_response.get("result").get("value").get("count"), 7)

        # set policy: helpdesk users in adminrealm are only allowed to
        # view "realm1A".
        set_policy("audit01",
                   scope=SCOPE.ADMIN,
                   action=ACTION.AUDIT,
                   adminrealm="adminrealm",
                   realm="realm1a")
        # Test admin is allowed to view unrestricted logs!
        set_policy("audit02",
                   scope=SCOPE.ADMIN,
                   action=ACTION.AUDIT,
                   user="******")

        rid = save_resolver({
            "resolver": self.resolvername1,
            "type": "passwdresolver",
            "fileName": PWFILE
        })
        self.assertTrue(rid > 0, rid)

        (added, failed) = set_realm("adminrealm", [self.resolvername1])
        self.assertTrue(len(failed) == 0)
        self.assertTrue(len(added) == 1)

        helpdesk_authorization = None
        with self.app.test_request_context('/auth',
                                           method='POST',
                                           data={
                                               'username':
                                               '******',
                                               'password': '******'
                                           }):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            json_response = res.json
            value = json_response.get("result").get("value")
            # Helpdesk user is allowed to view the audit log.
            self.assertTrue("auditlog" in value.get("rights"))
            helpdesk_authorization = value.get("token")

        # check, that we only see allowed audit realms
        with self.app.test_request_context(
                '/audit/',
                method='GET',
                headers={'Authorization': helpdesk_authorization}):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            json_response = res.json
            self.assertTrue(json_response.get("result").get("status"), res)
            # We now have 3 entries, as we added one by the search in line #43
            count = json_response.get("result").get("value").get("count")
            auditdata = json_response.get("result").get("value").get(
                "auditdata")
            self.assertEqual(count, 6)
            # All entries are in realm1A!
            for ad in auditdata:
                self.assertEqual(ad.get("realm"), "realm1a")

        # Now check, that the testadmin (self.at) sees all entries!
        with self.app.test_request_context('/audit/',
                                           method='GET',
                                           headers={'Authorization': self.at}):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            json_response = res.json
            self.assertTrue(json_response.get("result").get("status"), res)
            # We now have 3 entries, as we added one by the search in line #43
            count = json_response.get("result").get("value").get("count")
            auditdata = json_response.get("result").get("value").get(
                "auditdata")
            self.assertEqual(count, 20)

        # delete policy
        delete_policy("audit01")
        delete_policy("audit02")
Ejemplo n.º 3
0
    def test_02_get_allowed_audit_realm(self):
        # Check that an administrator is only allowed to see log entries of
        # the defined realms.
        # fill some audit entries
        Audit(action="enroll", success=1, realm=self.realm1a).save()
        Audit(action="enroll", success=1, realm=self.realm1a).save()
        Audit(action="enroll", success=1, realm=self.realm2b).save()
        Audit(action="enroll", success=1, realm=self.realm2b).save()
        Audit(action="enroll", success=1, realm=self.realm2b).save()

        # check, that we see all audit entries
        with self.app.test_request_context('/audit/',
                                           method='GET',
                                           data={"realm": self.realm1a},
                                           headers={'Authorization': self.at}):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            json_response = res.json
            self.assertTrue(json_response.get("result").get("status"), res)
            self.assertEqual(
                json_response.get("result").get("value").get("count"), 2)

        with self.app.test_request_context('/audit/',
                                           method='GET',
                                           headers={'Authorization': self.at}):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            json_response = res.json
            self.assertTrue(json_response.get("result").get("status"), res)
            self.assertGreaterEqual(
                json_response.get("result").get("value").get("count"), 7)
            audit_list = json_response.get("result").get("value").get(
                "auditdata")
            audit_actions = [
                a for a in audit_list if a.get("action") == "GET /audit/"
            ]
            self.assertGreaterEqual(len(audit_actions), 1)

        with self.app.test_request_context('/audit/',
                                           method='GET',
                                           data={"realm": self.realm2b},
                                           headers={'Authorization': self.at}):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            json_response = res.json
            self.assertTrue(json_response.get("result").get("status"), res)
            self.assertEqual(
                json_response.get("result").get("value").get("count"), 3)

        # set policy for audit realms
        set_policy("audit01",
                   scope=SCOPE.ADMIN,
                   action=ACTION.AUDIT,
                   realm=self.realm1a)

        # check, that we only see allowed audit realms
        with self.app.test_request_context('/audit/',
                                           method='GET',
                                           headers={'Authorization': self.at}):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            json_response = res.json
            self.assertTrue(json_response.get("result").get("status"), res)
            # We now have 3 entries, as we added one by the search in line #43
            audit_list = json_response.get("result").get("value").get(
                "auditdata")
            audit_realms = [
                a for a in audit_list if a.get("realm") == self.realm1a
            ]
            self.assertEqual(len(audit_realms), 3)
            self.assertEqual(
                json_response.get("result").get("value").get("count"), 3)

        # delete policy
        delete_policy("audit01")
Ejemplo n.º 4
0
    def test_04_get_user_audit_log(self):
        # Test that the user only sees audit log entries with his own data
        self.setUp_user_realms()
        # prepare some log entries for the normal user to try to fetch
        Audit(action="enroll",
              success=1,
              user="******",
              administrator=None,
              resolver="resolver1",
              realm=self.realm1a).save()
        Audit(action="enroll",
              success=1,
              user="******",
              administrator=None,
              resolver="resolver1",
              realm=self.realm1a).save()
        Audit(action="enroll",
              success=1,
              user="******",
              administrator=None,
              resolver="resolver1",
              realm=self.realm2b).save()
        Audit(action="enroll",
              success=1,
              user="******",
              administrator=None,
              resolver="resolver1",
              realm=self.realm2b).save()
        Audit(action="enroll",
              success=1,
              user="******",
              administrator=None,
              resolver="resolver1",
              realm=self.realm2b).save()

        # set policy: normal users in realm1a are allowed to view audit log
        set_policy("audit01",
                   scope=SCOPE.USER,
                   action=ACTION.AUDIT,
                   realm=self.realm1a)

        user_authorization = None
        with self.app.test_request_context('/auth',
                                           method='POST',
                                           data={
                                               'username':
                                               '******'.format(
                                                   self.realm1a),
                                               'password':
                                               '******'
                                           }):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            json_response = res.json
            value = json_response.get("result").get("value")
            self.assertTrue("auditlog" in value.get("rights"))
            user_authorization = value.get("token")

        # check, that the normal user only sees his own entries
        with self.app.test_request_context(
                '/audit/',
                method='GET',
                data={
                    "action": "**",
                    "action_detail": "**",
                    "administrator": "**",
                    "client": "**",
                    "date": "**",
                    "info": "**",
                    "page": "1",
                    "page_size": "10",
                    "policies": "**",
                    "privacyidea_server": "**",
                    "realm": "**",
                    "resolver": "**",
                    "serial": "**",
                    "sortorder": "desc",
                    "success": "**",
                    "tokentype": "**",
                    "user": "******"
                },
                headers={'Authorization': user_authorization}):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            json_response = res.json
            self.assertTrue(json_response.get("result").get("status"), res)
            # We now have 3 entries, as we added one by the search in line #43
            count = json_response.get("result").get("value").get("count")
            auditdata = json_response.get("result").get("value").get(
                "auditdata")
            self.assertGreaterEqual(count, 3)
            # All entries are in realm1A!
            for ad in auditdata:
                self.assertEqual(ad.get("realm"), self.realm1a)

        # try to explicitly query another realm
        with self.app.test_request_context(
                '/audit/',
                method='GET',
                data={
                    "action": "**",
                    "action_detail": "**",
                    "administrator": "**",
                    "client": "**",
                    "date": "**",
                    "info": "**",
                    "page": "1",
                    "page_size": "10",
                    "policies": "**",
                    "privacyidea_server": "**",
                    "realm": self.realm2b,
                    "resolver": "**",
                    "serial": "**",
                    "sortorder": "desc",
                    "success": "**",
                    "tokentype": "**",
                    "user": "******"
                },
                headers={'Authorization': user_authorization}):
            res = self.app.full_dispatch_request()
            self.assertTrue(res.status_code == 200, res)
            json_response = res.json
            self.assertTrue(json_response.get("result").get("status"), res)
            # The normal user can not fetch audit entries, that do not belong to him!
            count = json_response.get("result").get("value").get("count")
            self.assertGreaterEqual(count, 0)

        # delete policy
        delete_policy("audit01")
Ejemplo n.º 5
0
    def finalize_log(self):
        """
        This method is used to log the data.
        It should hash the data and do a hash chain and sign the data
        """
        try:
            self.audit_data["policies"] = ",".join(
                self.audit_data.get("policies", []))
            if self.config.get("PI_AUDIT_SQL_TRUNCATE"):
                self._truncate_data()
            if "tokentype" in self.audit_data:
                log.warning(
                    "We have a wrong 'tokentype' key. This should not happen. Fix it!. "
                    "Error occurs in action: {0!r}.".format(
                        self.audit_data.get("action")))
                if not "token_type" in self.audit_data:
                    self.audit_data["token_type"] = self.audit_data.get(
                        "tokentype")
            if self.audit_data.get("startdate"):
                duration = datetime.datetime.now() - self.audit_data.get(
                    "startdate")
            else:
                duration = None
            le = LogEntry(
                action=self.audit_data.get("action"),
                success=int(self.audit_data.get("success", 0)),
                serial=self.audit_data.get("serial"),
                token_type=self.audit_data.get("token_type"),
                user=self.audit_data.get("user"),
                realm=self.audit_data.get("realm"),
                resolver=self.audit_data.get("resolver"),
                administrator=self.audit_data.get("administrator"),
                action_detail=self.audit_data.get("action_detail"),
                info=self.audit_data.get("info"),
                privacyidea_server=self.audit_data.get("privacyidea_server"),
                client=self.audit_data.get("client", ""),
                loglevel=self.audit_data.get("log_level"),
                clearance_level=self.audit_data.get("clearance_level"),
                policies=self.audit_data.get("policies"),
                startdate=self.audit_data.get("startdate"),
                duration=duration)
            self.session.add(le)
            self.session.commit()
            # Add the signature
            if self.sign_data and self.sign_object:
                s = self._log_to_string(le)
                sign = self.sign_object.sign(s)
                le.signature = sign
                self.session.merge(le)
                self.session.commit()
        except Exception as exx:  # pragma: no cover
            # in case of a Unicode Error in _log_to_string() we won't have
            # a signature, but the log entry is available
            log.error("exception {0!r}".format(exx))
            log.error("DATA: {0!s}".format(self.audit_data))
            log.debug("{0!s}".format(traceback.format_exc()))
            self.session.rollback()

        finally:
            self.session.close()
            # clear the audit data
            self.audit_data = {}