Esempio n. 1
0
 def __check_entry(self, entry, allow_group):
     """ Checks an entry is in a valid format and expands groups.
         If groups are allowed, then inputting a group entry will
         result in the expanded group entries on the output.
         entry - The entry string to check.
         allow_group - Boolean, on whether to allow group names.
         Raises a ValueError if it isn't valid.
         Returns a list of entries.
         Each returned entry is a tuple of (auth_mode, auth_data).
     """
     if entry == "TOKEN":
         return [(ACLManager.AUTH_MODE_TOKEN, None)]
     elif entry == "CERT":
         return [(ACLManager.AUTH_MODE_X509, None)]
     elif entry == "SESSION":
         return [(ACLManager.AUTH_MODE_SESSION, None)]
     elif entry == "ALL":
         return [(ACLManager.AUTH_MODE_ALLOW_ALL, None)]
     elif entry.startswith("CERT:"):
         raw_dn = entry.split(':', 1)[1]
         if not "=" in raw_dn:
             raise ValueError("Bad CERT DN in ACL rule: '%s'" % entry)
         return [(ACLManager.AUTH_MODE_X509, X509Utils.normalise_dn(raw_dn))
                 ]
     elif allow_group and entry.startswith("@"):
         group_name = entry[1:]
         if not group_name in self.__groups:
             raise ValueError("Unrecognised group used in ACL rule: %s" % \
                              group_name)
         return deepcopy(self.__groups[group_name])
     raise ValueError("Invalid auth entry '%s'." % entry)
Esempio n. 2
0
 def __gen_req(self,
               path,
               method="GET",
               auth_mode=ACLManager.AUTH_MODE_NONE,
               auth_data=None,
               cert_ok=True,
               token_ok=True):
     """ Call self.__inst.check_request while generating a fake request
         with the given parameters (without using test_mode on the 
         ACLManager).
         Returns True if the request was successful (i.e. access would
         have been allowed).
     """
     app = Flask("ACLManagertest")
     app.secret_key = "TestKey"  # Required for session support
     token_svc = FakeTokenSVC(token_ok)
     try:
         headers = {}
         enable_session = False
         if auth_mode == ACLManager.AUTH_MODE_X509:
             if cert_ok:
                 headers['Ssl-Client-Verify'] = 'SUCCESS'
             else:
                 headers['Ssl-Client-Verify'] = 'FAILED'
             headers['Ssl-Client-S-Dn'] = auth_data
         elif auth_mode == ACLManager.AUTH_MODE_TOKEN:
             headers['X-Token'] = json.dumps(auth_data)
         elif auth_mode == ACLManager.AUTH_MODE_SESSION:
             enable_session = True
         with app.test_request_context(path=path,
                                       method=method,
                                       headers=headers):
             if enable_session:
                 set_session_state(True)
             # Prepare a standard looking request
             current_app.log = self.__log
             current_app.token_svc = token_svc
             request.uuid = "Test-Test-Test"
             # Call the check function
             self.__inst.check_request()
             # Check that request info was correctly propagated
             if auth_mode == ACLManager.AUTH_MODE_X509:
                 norm_dn = X509Utils.normalise_dn(auth_data)
                 self.assertEqual(request.dn, norm_dn)
             elif auth_mode == ACLManager.AUTH_MODE_TOKEN:
                 if token_ok:
                     self.assertEqual(request.token, auth_data)
                     self.assertEqual(request.raw_token,
                                      json.dumps(auth_data))
                     self.assertTrue(request.token_ok)
                 else:
                     self.assertFalse(request.token_ok)
             elif auth_mode == ACLManager.AUTH_MODE_SESSION:
                 self.assertTrue(request.session_ok)
         # Access was allowed (no exception raised)
         return True
     except Forbidden:
         # Access was denied (Forbidden exception thrown)
         return False
Esempio n. 3
0
 def __get_fake_request_auth(self):
     """ Fills the request object with te test (fake) authentication
         details.
     """
     if self.__test_mode == ACLManager.AUTH_MODE_X509:
         request.dn = X509Utils.normalise_dn(self.__test_data)
     elif self.__test_mode == ACLManager.AUTH_MODE_TOKEN:
         request.token = self.__test_data
         request.raw_token = self.__test_data
         request.token_ok = True
     elif self.__test_mode == ACLManager.AUTH_MODE_SESSION:
         request.session_ok = True
Esempio n. 4
0
 def __check_test_mode(self, auth_mode, auth_data):
     """ Helper function for testing test_mode.
     """
     self.__inst.test_mode(auth_mode, auth_data)
     app = Flask("ACLManagertest")
     with app.test_request_context(path="/test", method="GET"):
         request.uuid = "Test-Test-Test"
         # Call the check function
         self.__inst.check_request()
         # Check that request info was correctly propagated
         if auth_mode == ACLManager.AUTH_MODE_X509:
             norm_dn = X509Utils.normalise_dn(auth_data)
             self.assertEqual(request.dn, norm_dn)
         elif auth_mode == ACLManager.AUTH_MODE_TOKEN:
             self.assertEqual(request.token, auth_data)
             self.assertEqual(request.raw_token, auth_data)
             self.assertTrue(request.token_ok)
         elif auth_mode == ACLManager.AUTH_MODE_SESSION:
             self.assertTrue(request.session_ok)
Esempio n. 5
0
 def __get_real_request_auth():
     """ Fills the details of the presented credentials into the
         request object.
     """
     # Cert auth
     if 'Ssl-Client-Verify' in request.headers \
         and 'Ssl-Client-S-Dn' in request.headers:
         # Request has client cert
         if request.headers['Ssl-Client-Verify'] == 'SUCCESS':
             raw_dn = request.headers['Ssl-Client-S-Dn']
             request.dn = X509Utils.normalise_dn(raw_dn)
     # Token Auth
     if 'X-Token' in request.headers:
         raw_token = request.headers['X-Token']
         try:
             token_value = current_app.token_svc.check(raw_token)
             # Check if this looks like a standard token with an expiry value
             if isinstance(token_value, dict):
                 if 'expiry' in token_value:
                     exp_str = token_value['expiry']
                     exp_value = datetime.strptime(exp_str,
                                                   '%Y-%m-%dT%H:%M:%S.%f')
                     if exp_value < datetime.utcnow():
                         # Token has already expired
                         current_app.log.info(
                             "Request %s token has expired (at %s)",
                             request.uuid, exp_str)
                         return "403 Expired Token", 403
             request.token = token_value
             request.raw_token = raw_token
             request.token_ok = True
         except ValueError:
             # Token decoding failed, it is probably corrupt or has been
             # tampered with.
             current_app.log.info("Request %s token validation failed.",
                                  request.uuid)
             return "403 Invalid Token", 403
     if 'logged_in' in session:
         if session['logged_in']:
             request.session_ok = True
Esempio n. 6
0
 def test_dn_normalisation(self):
     """ Test the X509 DN normalisation function. """
     # Test DN in expected output format
     TEST_DN = "C=XX, L=YY, CN=Test CA"
     # Test both RFC and OpenSSL style DNs with increasing amounts of space
     # All should match the TEST_DN after normalisation.
     self.assertEqual(X509Utils.normalise_dn(TEST_DN), TEST_DN)
     self.assertEqual(X509Utils.normalise_dn("/C=XX/L=YY/CN=Test CA"),
                      TEST_DN)
     self.assertEqual(
         X509Utils.normalise_dn("/C=XX / L =  YY /  CN = Test CA  "),
         TEST_DN)
     # Check that leading space doesn't upset the algorithm
     self.assertEqual(
         X509Utils.normalise_dn("   / C =XX / L =  YY /  CN = Test CA  "),
         TEST_DN)
     self.assertEqual(
         X509Utils.normalise_dn("C = XX, L = YY, CN = Test CA"), TEST_DN)
     self.assertEqual(
         X509Utils.normalise_dn("C  =  XX,   L  =  YY,    CN = Test CA   "),
         TEST_DN)
     self.assertEqual(
         X509Utils.normalise_dn(
             "     C  =  XX,   L  =  YY,    CN = Test CA"), TEST_DN)