def test_proxy_login_with_kerberos_forbidden(self): """ Test that the proxy login fail when proxy role is not granted """ # Set up users for proxy login test self._setup_for_proxy(False) query = "select * from testkrbproxy.testproxy" # Try normal login with Charlie self.refresh_kerberos_tickets(self.bob_keytab, "*****@*****.**", self.krb_conf) auth_provider = DSEGSSAPIAuthProvider( service='dse', qops=["auth"], principal="*****@*****.**", authorization_id='*****@*****.**') self.assertRaises(NoHostAvailable, self.connect_and_query, auth_provider, query=query) self.refresh_kerberos_tickets(self.bob_keytab, "*****@*****.**", self.krb_conf) auth_provider = DSEGSSAPIAuthProvider(service='dse', qops=["auth"], principal="*****@*****.**") self.assertRaises(Unauthorized, self.connect_and_query, auth_provider, query=query) self._remove_proxy_setup()
def test_connect_with_explicit_principal(self): """ This tests will attempt to authenticate using valid and invalid user principals @since 1.0.0 @jira_ticket PYTHON-574 @test_category dse auth @expected_result Client principals should be used by the underlying mechanism """ # Connect with valid principal self.refresh_kerberos_tickets(self.cassandra_keytab, "*****@*****.**", self.krb_conf) auth_provider = DSEGSSAPIAuthProvider( service='dse', qops=["auth"], principal="*****@*****.**") rs = self.connect_and_query(auth_provider) connections = [ c for holders in self.cluster.get_connection_holders() for c in holders.get_connections() ] # Check to make sure our server_authenticator class is being set appropriate for connection in connections: self.assertTrue('DseAuthenticator' in connection.authenticator. server_authenticator_class) # Use invalid principal auth_provider = DSEGSSAPIAuthProvider( service='dse', qops=["auth"], principal="*****@*****.**") self.assertRaises(NoHostAvailable, self.connect_and_query, auth_provider)
def test_proxy_login_with_kerberos(self): """ Test that the proxy login works with kerberos. """ # Set up users for proxy login test self._setup_for_proxy() query = "select * from testkrbproxy.testproxy" # Try normal login with Charlie self.refresh_kerberos_tickets(self.charlie_keytab, "*****@*****.**", self.krb_conf) auth_provider = DSEGSSAPIAuthProvider(service='dse', qops=["auth"], principal="*****@*****.**") self.connect_and_query(auth_provider, query=query) # Try proxy login with bob self.refresh_kerberos_tickets(self.bob_keytab, "*****@*****.**", self.krb_conf) auth_provider = DSEGSSAPIAuthProvider(service='dse', qops=["auth"], principal="*****@*****.**", authorization_id='*****@*****.**') self.connect_and_query(auth_provider, query=query) #Try loging with bob without mentioning charlie self.refresh_kerberos_tickets(self.bob_keytab, "*****@*****.**", self.krb_conf) auth_provider = DSEGSSAPIAuthProvider(service='dse', qops=["auth"], principal="*****@*****.**") self.assertRaises(Unauthorized, self.connect_and_query, auth_provider, query=query) self._remove_proxy_setup()
def test_host_resolution(self): # resolves by default provider = DSEGSSAPIAuthProvider(service='test', qops=QOP.all) authenticator = provider.new_authenticator('127.0.0.1') self.assertEqual(authenticator.sasl.host, 'localhost') # numeric fallback okay authenticator = provider.new_authenticator('0.0.0.1') self.assertEqual(authenticator.sasl.host, '0.0.0.1') # disable explicitly provider = DSEGSSAPIAuthProvider(service='test', qops=QOP.all, resolve_host_name=False) authenticator = provider.new_authenticator('127.0.0.1') self.assertEqual(authenticator.sasl.host, '127.0.0.1')
def _setup_for_proxy(self, grant=True): os.environ['KRB5_CONFIG'] = self.krb_conf self.refresh_kerberos_tickets(self.cassandra_keytab, "*****@*****.**", self.krb_conf) auth_provider = DSEGSSAPIAuthProvider(service='dse', qops=["auth"], principal='*****@*****.**') cluster = Cluster(auth_provider=auth_provider) session = cluster.connect() session.execute("CREATE ROLE IF NOT EXISTS '{0}' WITH LOGIN = TRUE;".format('*****@*****.**')) session.execute("CREATE ROLE IF NOT EXISTS '{0}' WITH LOGIN = TRUE;".format('*****@*****.**')) session.execute("GRANT EXECUTE ON ALL AUTHENTICATION SCHEMES to '*****@*****.**'") session.execute("CREATE ROLE IF NOT EXISTS '{0}' WITH LOGIN = TRUE;".format('*****@*****.**')) session.execute("GRANT EXECUTE ON ALL AUTHENTICATION SCHEMES to '*****@*****.**'") # Create a keyspace and allow only charlie to query it. session.execute( "CREATE KEYSPACE testkrbproxy WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}") session.execute("CREATE TABLE testkrbproxy.testproxy (id int PRIMARY KEY, value text)") session.execute("GRANT ALL PERMISSIONS ON KEYSPACE testkrbproxy to '{0}'".format('*****@*****.**')) if grant: session.execute("GRANT PROXY.LOGIN ON ROLE '{0}' to '{1}'".format('*****@*****.**', '*****@*****.**')) cluster.shutdown()
def test_should_not_athenticate_without_ticket(self): """ This tests will attempt to authenticate with a user that is valid but has no ticket @since 1.0.0 @jira_ticket PYTHON-457 @test_category dse auth @expected_result NoHostAvailable exception should be thrown """ auth_provider = DSEGSSAPIAuthProvider(service='dse', qops=["auth"]) self.assertRaises(NoHostAvailable, self.connect_and_query, auth_provider)
def test_should_not_authenticate_with_bad_user_ticket(self): """ This tests will attempt to authenticate with a user that has a valid ticket, but is not a valid dse user. @since 1.0.0 @jira_ticket PYTHON-457 @test_category dse auth @expected_result NoHostAvailable exception should be thrown """ self.refresh_kerberos_tickets(self.dseuser_keytab, "*****@*****.**", self.krb_conf) auth_provider = DSEGSSAPIAuthProvider(service='dse', qops=["auth"]) self.assertRaises(NoHostAvailable, self.connect_and_query, auth_provider)
def test_connect_with_kerberos_host_not_resolved(self): """ This tests will attempt to authenticate with IP, this will fail on osx. The success or failure of this test is dependent on a reverse dns lookup which can be impacted by your environment if it fails don't panic. @since 1.0.0 @jira_ticket PYTHON-566 @test_category dse auth @expected_result Client should error when ip is used """ self.refresh_kerberos_tickets(self.cassandra_keytab, "*****@*****.**", self.krb_conf) auth_provider = DSEGSSAPIAuthProvider(service='dse', qops=["auth"], resolve_host_name=False)
def get_auth_provider(config_file, env, username=None, password=None, options=None): def print_debug(message): if options and hasattr(options, "debug") and options.debug: sys.stderr.write(message) if username: print_debug("Using DSEPlainTextAuthProvider\n") return DSEPlainTextAuthProvider(username=username, password=password) """ Kerberos auth provider can be configured in the cqlshrc file [kerberos] section or with environment variables: Config option Environment Variable Description ------------- -------------------- ----------- service KRB_SERVICE Service to authenticate with qops QOPS Comma separated list of QOP values (default: auth) """ configs = ConfigParser.SafeConfigParser() configs.read(config_file) def get_option(section, option, env_variable, default=None): value = env.get(env_variable) if value is None: try: value = configs.get(section, option) except ConfigParser.Error: value = default return value krb_service = get_option('kerberos', 'service', 'KRB_SERVICE', 'dse') krb_qop_value = get_option('kerberos', 'qops', 'QOPS', 'auth') try: provider = DSEGSSAPIAuthProvider(service=krb_service, qops=krb_qop_value.split(',')) print_debug("Using DSEGSSAPIAuthProvider(service=%s, qops=%s)\n" % (krb_service, krb_qop_value)) print_debug( " This will only be used if the server requests kerberos authentication\n" ) return provider except ImportError as e: print_debug( "Attempted to use DSEGSSAPIAuthProvider(service=%s, qops=%s)\n" % (krb_service, krb_qop_value)) print_debug(" Attempt failed because: %s\n" % str(e)) return None
def test_connect_with_kerberos_host_not_resolved(self): """ This tests will attempt to authenticate with IP, this will fail. @since 1.0.0 @jira_ticket PYTHON-566 @test_category dse auth @expected_result Client should error when ip is used """ self.refresh_kerberos_tickets(self.cassandra_keytab, "*****@*****.**", self.krb_conf) auth_provider = DSEGSSAPIAuthProvider(service='dse', qops=["auth"], resolve_host_name=False) self.assertRaises(NoHostAvailable, self.connect_and_query, auth_provider)
def _remove_proxy_setup(self): os.environ['KRB5_CONFIG'] = self.krb_conf self.refresh_kerberos_tickets(self.cassandra_keytab, "*****@*****.**", self.krb_conf) auth_provider = DSEGSSAPIAuthProvider(service='dse', qops=["auth"], principal='*****@*****.**') cluster = Cluster(auth_provider=auth_provider) session = cluster.connect() session.execute("REVOKE PROXY.LOGIN ON ROLE '{0}' FROM '{1}'".format('*****@*****.**', '*****@*****.**')) session.execute("DROP ROLE IF EXISTS '{0}';".format('*****@*****.**')) session.execute("DROP ROLE IF EXISTS '{0}';".format('*****@*****.**')) # Create a keyspace and allow only charlie to query it. session.execute("DROP KEYSPACE testkrbproxy") cluster.shutdown()
def test_connect_with_kerberos(self): """ This tests will attempt to authenticate with a user that is valid and has a ticket @since 1.0.0 @jira_ticket PYTHON-457 @test_category dse auth @expected_result Client should be able to connect and run a basic query """ self.refresh_kerberos_tickets(self.cassandra_keytab, "*****@*****.**", self.krb_conf) auth_provider = DSEGSSAPIAuthProvider() rs = self.connect_and_query(auth_provider) self.assertIsNotNone(rs) connections = [c for holders in self.cluster.get_connection_holders() for c in holders.get_connections()] # Check to make sure our server_authenticator class is being set appropriate for connection in connections: self.assertTrue('DseAuthenticator' in connection.authenticator.server_authenticator_class)
def test_host_resolution(self): # resolves by default provider = DSEGSSAPIAuthProvider(service='test', qops=QOP.all) authenticator = provider.new_authenticator('127.0.0.1') self.assertEqual(authenticator.sasl.host, 'localhost') # numeric fallback okay authenticator = provider.new_authenticator('0.0.0.1') self.assertEqual(authenticator.sasl.host, '0.0.0.1') # disable explicitly provider = DSEGSSAPIAuthProvider(service='test', qops=QOP.all, resolve_host_name=False) authenticator = provider.new_authenticator('127.0.0.1') self.assertEqual(authenticator.sasl.host, '127.0.0.1')
def test_connect_with_kerberos_and_graph(self): """ This tests will attempt to authenticate with a user and execute a graph query @since 1.0.0 @jira_ticket PYTHON-457 @test_category dse auth @expected_result Client should be able to connect and run a basic graph query with authentication """ self.refresh_kerberos_tickets(self.cassandra_keytab, "*****@*****.**", self.krb_conf) auth_provider = DSEGSSAPIAuthProvider(service='dse', qops=["auth"]) rs = self.connect_and_query(auth_provider) self.assertIsNotNone(rs) reset_graph(self.session, self._testMethodName.lower()) profiles = self.cluster.profile_manager.profiles profiles[EXEC_PROFILE_GRAPH_DEFAULT].graph_options.graph_name = self._testMethodName.lower() generate_classic(self.session) rs = self.session.execute_graph('g.V()') self.assertIsNotNone(rs)