class TestClientAuth(TestCase): def setUp(self): self.port = VALID_PORT config = NuauthConf() # Userdb self.user = PlaintextUser("visiteur", "nopassword", 42, 42) self.userdb = PlaintextUserDB() self.userdb.addUser(self.user) self.userdb.install(config) self.acls = PlaintextAcl() self.acls.addAcl("web", self.port, self.user.gid) self.acls.install(config) # Load nuauth config["nuauth_do_ip_authentication"] = '1' config["nuauth_ip_authentication_module"] = '"ipauth_guest"' config["ipauth_guest_username"] = '******' % self.user.login self.nuauth = Nuauth(config) self.iptables = Iptables() self.nufw = startNufw() def tearDown(self): self.acls.desinstall() self.userdb.desinstall() self.nuauth.stop() self.iptables.flush() def testValid(self): self.iptables.filterTcp(self.port) self.assertEqual(connectTcp(HOST, self.port, TIMEOUT), True)
class TestConntrack(TestCase): def setUp(self): self.dst_host = socket.gethostbyname(HOST) self.config = NuauthConf() self.acls = PlaintextAcl() self.acls.addAclFull("web", self.dst_host, VALID_PORT, USERDB[0].gid, 1, period='10 secs' ) self.acls.install(self.config) self.period = PlainPeriodXML() self.period.addPeriod(Period("10 secs", duration = 10)) self.period.install(self.config) self.users = USERDB self.users.install(self.config) self.nuauth = Nuauth(self.config) self.nufw = startNufw() self.iptables = Iptables() self.iptables.flush() self.iptables.command('-I OUTPUT -d %s -p tcp --dport 80 --syn -m state --state NEW -j NFQUEUE' % self.dst_host) self.iptables.command('-I OUTPUT -d %s -p tcp --dport 80 ! --syn -m state --state NEW -j DROP' % self.dst_host) def tearDown(self): self.nuauth.stop() self.users.desinstall() self.acls.desinstall() self.period.desinstall() def testConnShutdown(self): user = USERDB[0] client = user.createClient() self.assert_(connectClient(client)) start = time.time() conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) conn.connect((self.dst_host, VALID_PORT)) src_port = conn.getsockname()[1] ct_before = len(get_conntrack_conn(src_port, self.dst_host, VALID_PORT)) ## Check that only one connection is opened to self.assert_(ct_before == 1) ## The connection should be killed 10 seconds after being opened time.sleep(15) ## Check that only one connection is opened to ct_after = len(get_conntrack_conn(src_port, self.dst_host, VALID_PORT)) self.assert_(ct_after == 0) conn.close() client.stop()
class TestConntrack(TestCase): def setUp(self): self.dst_host = socket.gethostbyname(HOST) self.config = NuauthConf() self.acls = PlaintextAcl() self.acls.addAclFull("web", self.dst_host, VALID_PORT, USERDB[0].gid, 1, period="10 secs") self.acls.install(self.config) self.period = PlainPeriodXML() self.period.addPeriod(Period("10 secs", duration=10)) self.period.install(self.config) self.users = USERDB self.users.install(self.config) self.nuauth = Nuauth(self.config) self.nufw = startNufw() self.iptables = Iptables() self.iptables.flush() self.iptables.command("-I OUTPUT -d %s -p tcp --dport 80 --syn -m state --state NEW -j NFQUEUE" % self.dst_host) self.iptables.command("-I OUTPUT -d %s -p tcp --dport 80 ! --syn -m state --state NEW -j DROP" % self.dst_host) def tearDown(self): self.nuauth.stop() self.users.desinstall() self.acls.desinstall() self.period.desinstall() def testConnShutdown(self): user = USERDB[0] client = user.createClient() self.assert_(connectClient(client)) start = time.time() conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) conn.connect((self.dst_host, VALID_PORT)) src_port = conn.getsockname()[1] ct_before = len(get_conntrack_conn(src_port, self.dst_host, VALID_PORT)) ## Check that only one connection is opened to self.assert_(ct_before == 1) ## The connection should be killed 10 seconds after being opened time.sleep(15) ## Check that only one connection is opened to ct_after = len(get_conntrack_conn(src_port, self.dst_host, VALID_PORT)) self.assert_(ct_after == 0) conn.close() client.stop()
class TestPlaintextAcl(TestCase): def setUp(self): self.iptables = Iptables() self.users = USERDB self.config = NuauthConf() self.config["xml_defs_periodfile"] = '"%s"' % os.path.abspath("../conf/periods.xml") self.acls = PlaintextAcl() # Start nuauth with new config self.users.install(self.config) self.nufw = startNufw(["-s"]) def tearDown(self): # Restore user DB and nuauth config self.users.desinstall() self.acls.desinstall() self.nuauth.stop() self.iptables.flush() def testPeriodDrop(self): self.acls.desinstall() self.acls = PlaintextAcl() if time.localtime().tm_hour >= 12: period = "0-12" else: period = "12-24" self.acls.addAcl("web", VALID_PORT, self.users[0].gid, 1, period=period ) self.acls.install(self.config) self.nuauth = Nuauth(self.config) user = self.users[0] client = user.createClientWithCerts() testPort(self, self.iptables, client, VALID_PORT, False) self.acls.desinstall() def testPeriodAccept(self): self.acls.desinstall() self.acls = PlaintextAcl() if time.localtime().tm_hour < 12: period = "0-12" else: period = "12-24" self.acls.addAcl("web", VALID_PORT, self.users[0].gid, 1, period=period) self.acls.install(self.config) self.nuauth = Nuauth(self.config) user = self.users[0] client = user.createClientWithCerts() testAllowPort(self, self.iptables, client) self.acls.desinstall()
class TestClientAuth(TestCase): def setUp(self): self.port = VALID_PORT self.mark = 1 self.shift = 8 config = NuauthConf() # Userdb self.user = PlaintextUser("guest", "nopassword", 42, 42) self.userdb = PlaintextUserDB() self.userdb.addUser(self.user) self.userdb.install(config) self.acls = PlaintextAcl() self.acls.addAcl("port", self.port, self.user.gid, flags=(self.mark << self.shift)) self.acls.install(config) # Load nuauth config["nuauth_finalize_packet_module"] = '"mark_flag"' config["mark_flag_mark_shift"] = 0 config["mark_flag_flag_shift"] = self.shift config["mark_flag_nbits"] = 16 self.nuauth = Nuauth(config) self.iptables = Iptables() self.nufw = startNufw(["-m"]) self.client = self.user.createClientWithCerts() def tearDown(self): self.acls.desinstall() self.userdb.desinstall() self.client.stop() self.nuauth.stop() self.iptables.flush() def testValid(self): # Connect client and filter port self.assert_(connectClient(self.client)) self.iptables.filterTcp(self.port) # Test connection without QoS (accept) self.assertEqual(connectTcp(HOST, self.port, TIMEOUT), True) # Test connection with QoS (drop) self.iptables.command( "-A POSTROUTING -t mangle -m mark --mark %s -j DROP" % self.mark) self.assertEqual(connectTcp(HOST, self.port, TIMEOUT), False)
class TestClientAuth(TestCase): def setUp(self): self.port = VALID_PORT self.mark = 1 self.shift = 8 config = NuauthConf() # Userdb self.user = PlaintextUser("guest", "nopassword", 42, 42) self.userdb = PlaintextUserDB() self.userdb.addUser(self.user) self.userdb.install(config) self.acls = PlaintextAcl() self.acls.addAcl("port", self.port, self.user.gid, flags=(self.mark << self.shift)) self.acls.install(config) # Load nuauth config["nuauth_finalize_packet_module"] = '"mark_flag"' config["mark_flag_mark_shift"] = 0 config["mark_flag_flag_shift"] = self.shift config["mark_flag_nbits"] = 16 self.nuauth = Nuauth(config) self.iptables = Iptables() self.nufw = startNufw(["-m"]) self.client = self.user.createClientWithCerts() def tearDown(self): self.acls.desinstall() self.userdb.desinstall() self.client.stop() self.nuauth.stop() self.iptables.flush() def testValid(self): # Connect client and filter port self.assert_(connectClient(self.client)) self.iptables.filterTcp(self.port) # Test connection without QoS (accept) self.assertEqual(connectTcp(HOST, self.port, TIMEOUT), True) # Test connection with QoS (drop) self.iptables.command("-A POSTROUTING -t mangle -m mark --mark %s -j DROP" % self.mark) self.assertEqual(connectTcp(HOST, self.port, TIMEOUT), False)
class TestICMPReject(TestCase): def setUp(self): self.iptables = Iptables() self.users = USERDB self.acls = PlaintextAcl() self.acls.addAcl("web", VALID_PORT, self.users[0].gid+1) self.config = NuauthConf() self.config["nuauth_packet_timeout"] = "1" self.users.install(self.config) self.acls.install(self.config) self.nufw = startNufw(["-s"]) def tearDown(self): # Restore user DB and nuauth config self.users.desinstall() self.acls.desinstall() self.nuauth.stop() self.iptables.flush() def testDrop(self): self.config["nuauth_reject_after_timeout"] = "0" self.config["nuauth_reject_authenticated_drop"] = "0" self.nuauth = Nuauth(self.config) user = self.users[0] client = user.createClientWithCerts() testPortFailure(self, self.iptables, client, VALID_PORT, ETIMEDOUT) client.stop() def testRejectTimedout(self): self.config["nuauth_reject_after_timeout"] = "1" self.config["nuauth_reject_authenticated_drop"] = "0" self.nuauth = Nuauth(self.config) testPortFailure(self, self.iptables, None, VALID_PORT, ECONNREFUSED) def testRejectAuthenticated(self): self.config["nuauth_reject_after_timeout"] = 0 self.config["nuauth_reject_authenticated_drop"] = 1 self.nuauth = Nuauth(self.config) user = self.users[0] client = user.createClientWithCerts() testPortFailure(self, self.iptables, client, VALID_PORT, ECONNREFUSED) client.stop()
class TestICMPReject(TestCase): def setUp(self): self.iptables = Iptables() self.users = USERDB self.acls = PlaintextAcl() self.acls.addAcl("web", VALID_PORT, self.users[0].gid + 1) self.config = NuauthConf() self.config["nuauth_packet_timeout"] = "1" self.users.install(self.config) self.acls.install(self.config) self.nufw = startNufw(["-s"]) def tearDown(self): # Restore user DB and nuauth config self.users.desinstall() self.acls.desinstall() self.nuauth.stop() self.iptables.flush() def testDrop(self): self.config["nuauth_reject_after_timeout"] = "0" self.config["nuauth_reject_authenticated_drop"] = "0" self.nuauth = Nuauth(self.config) user = self.users[0] client = user.createClientWithCerts() testPortFailure(self, self.iptables, client, VALID_PORT, ETIMEDOUT) client.stop() def testRejectTimedout(self): self.config["nuauth_reject_after_timeout"] = "1" self.config["nuauth_reject_authenticated_drop"] = "0" self.nuauth = Nuauth(self.config) testPortFailure(self, self.iptables, None, VALID_PORT, ECONNREFUSED) def testRejectAuthenticated(self): self.config["nuauth_reject_after_timeout"] = 0 self.config["nuauth_reject_authenticated_drop"] = 1 self.nuauth = Nuauth(self.config) user = self.users[0] client = user.createClientWithCerts() testPortFailure(self, self.iptables, client, VALID_PORT, ECONNREFUSED) client.stop()
class MysqlLog(TestCase): def setUp(self): startNufw(["-s"]) config = NuauthConf() config["nuauth_log_users"] = '9' config["mysql_prefix_version"] = '1' if POSTGRESQL: config.need_restart = True self.conn = pgdb.connect(host=DB_SERVER, user=DB_USER, password=DB_PASSWORD, database=DB_DBNAME) config["nuauth_user_logs_module"] = '"pgsql"' config["nuauth_user_session_logs_module"] = '"pgsql"' else: self.conn = MySQLdb.Connect(host=DB_SERVER, user=DB_USER, passwd=DB_PASSWORD, db=DB_DBNAME) config["nuauth_user_logs_module"] = '"mysql"' config["nuauth_user_session_logs_module"] = '"mysql"' self.users = USERDB self.user = self.users[0] self.acls = PlaintextAcl() self.acls.addAcl("web", VALID_PORT, self.user.gid, log_prefix=LOG_PREFIX) self.users.install(config) self.acls.install(config) self.nuauth = Nuauth(config) self.start_time = int(time() - 1.1) def query(self, sql): if POSTGRESQL: prefix = "PostgreSQL" else: prefix = "MySQL" info("%s query: %s" % (prefix, sql)) cursor = self.conn.cursor() cursor.execute(sql) info("%s result: %s rows" % (prefix, cursor.rowcount)) return cursor def fetchone(self, cursor): row = cursor.fetchone() if POSTGRESQL: info("PostgreSQL fetchone(): %s" % repr(row)) else: info("MySQL fetchone(): %s" % repr(row)) return row def tearDown(self): # Stop nuauth self.nuauth.stop() self.conn.close() self.users.desinstall() self.acls.desinstall() def _login(self, sql): # Client login client = self.user.createClientWithCerts() self.assert_(connectClient(client)) # Check number of rows for when in retry(timeout=QUERY_TIMEOUT): cursor = self.query(sql) for line in self.nuauth.readlines(): pass if cursor.rowcount: break self.assertEqual(cursor.rowcount, 1) # Read row columns (ip_saddr, user_id, username, os_sysname, os_release, os_version, end_time) = self.fetchone(cursor) if not POSTGRESQL: ip_saddr = ntohl(ip_saddr) & 0xFFFFFFFF # Check values self.assertEqual(IP(ip_saddr), client.ip) self.assertEqual(user_id, self.user.uid) self.assertEqual(username, client.username) self.assertEqual(os_sysname, OS_SYSNAME) self.assertEqual(os_release, OS_RELEASE) self.assertEqual(os_version, OS_VERSION) return client def _logout(self, sql, client): # Client logout # Use datetime.fromtimestamp() with int(time()) to have microsecond=0 logout_before = datetime_before() client.stop() for when in retry(timeout=QUERY_TIMEOUT): # Get last MySQL row cursor = self.query(sql) # Check number of rows if not cursor.rowcount: continue self.assertEqual(cursor.rowcount, 1) # Read row columns (ip_saddr, user_id, username, os_sysname, os_release, os_version, end_time) = self.fetchone(cursor) if not end_time: continue break # Check values if not POSTGRESQL: # FIXME: Convert string to datetime for PostgreSQL logout_after = datetime_after() self.assert_(logout_before <= end_time <= logout_after)
class MysqlLog(TestCase): def setUp(self): startNufw(["-s"]) config = NuauthConf() config["nuauth_log_users"] = '9' config["mysql_prefix_version"] = '1' if POSTGRESQL: config.need_restart = True self.conn = pgdb.connect( host=DB_SERVER, user=DB_USER, password=DB_PASSWORD, database=DB_DBNAME) config["nuauth_user_logs_module"] = '"pgsql"' config["nuauth_user_session_logs_module"] = '"pgsql"' else: self.conn = MySQLdb.Connect( host=DB_SERVER, user=DB_USER, passwd=DB_PASSWORD, db=DB_DBNAME) config["nuauth_user_logs_module"] = '"mysql"' config["nuauth_user_session_logs_module"] = '"mysql"' self.users = USERDB self.user = self.users[0] self.acls = PlaintextAcl() self.acls.addAcl("web", VALID_PORT, self.user.gid, log_prefix=LOG_PREFIX) self.users.install(config) self.acls.install(config) self.nuauth = Nuauth(config) self.start_time = int(time()-1.1) def query(self, sql): if POSTGRESQL: prefix = "PostgreSQL" else: prefix = "MySQL" info("%s query: %s" % (prefix, sql)) cursor = self.conn.cursor() cursor.execute(sql) info("%s result: %s rows" % (prefix, cursor.rowcount)) return cursor def fetchone(self, cursor): row = cursor.fetchone() if POSTGRESQL: info("PostgreSQL fetchone(): %s" % repr(row)) else: info("MySQL fetchone(): %s" % repr(row)) return row def tearDown(self): # Stop nuauth self.nuauth.stop() self.conn.close() self.users.desinstall() self.acls.desinstall() def _login(self, sql): # Client login client = self.user.createClientWithCerts() self.assert_(connectClient(client)) # Check number of rows for when in retry(timeout=QUERY_TIMEOUT): cursor = self.query(sql) for line in self.nuauth.readlines(): pass if cursor.rowcount: break self.assertEqual(cursor.rowcount, 1) # Read row columns (ip_saddr, user_id, username, os_sysname, os_release, os_version, end_time) = self.fetchone(cursor) if not POSTGRESQL: ip_saddr = ntohl(ip_saddr) & 0xFFFFFFFF # Check values self.assertEqual(IP(ip_saddr), client.ip) self.assertEqual(user_id, self.user.uid) self.assertEqual(username, client.username) self.assertEqual(os_sysname, OS_SYSNAME) self.assertEqual(os_release, OS_RELEASE) self.assertEqual(os_version, OS_VERSION) return client def _logout(self, sql, client): # Client logout # Use datetime.fromtimestamp() with int(time()) to have microsecond=0 logout_before = datetime_before() client.stop() for when in retry(timeout=QUERY_TIMEOUT): # Get last MySQL row cursor = self.query(sql) # Check number of rows if not cursor.rowcount: continue self.assertEqual(cursor.rowcount, 1) # Read row columns (ip_saddr, user_id, username, os_sysname, os_release, os_version, end_time) = self.fetchone(cursor) if not end_time: continue break # Check values if not POSTGRESQL: # FIXME: Convert string to datetime for PostgreSQL logout_after = datetime_after() self.assert_(logout_before <= end_time <= logout_after)
class TestPlaintextAcl(TestCase): def setUp(self): self.iptables = Iptables() self.users = USERDB self.config = NuauthConf() self.config["xml_defs_periodfile"] = '"%s"' % os.path.abspath( "../conf/periods.xml") self.acls = PlaintextAcl() # Start nuauth with new config self.users.install(self.config) self.nufw = startNufw(["-s"]) def tearDown(self): # Restore user DB and nuauth config self.users.desinstall() self.acls.desinstall() self.nuauth.stop() self.iptables.flush() def testPeriodDrop(self): self.acls.desinstall() self.acls = PlaintextAcl() if time.localtime().tm_hour >= 12: period = "0-12" else: period = "12-24" self.acls.addAcl("web", VALID_PORT, self.users[0].gid, 1, period=period) self.acls.install(self.config) self.nuauth = Nuauth(self.config) user = self.users[0] client = user.createClientWithCerts() testPort(self, self.iptables, client, VALID_PORT, False) self.acls.desinstall() def testPeriodAccept(self): self.acls.desinstall() self.acls = PlaintextAcl() if time.localtime().tm_hour < 12: period = "0-12" else: period = "12-24" self.acls.addAcl("web", VALID_PORT, self.users[0].gid, 1, period=period) self.acls.install(self.config) self.nuauth = Nuauth(self.config) user = self.users[0] client = user.createClientWithCerts() testAllowPort(self, self.iptables, client) self.acls.desinstall()