import os import sys import unittest sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'payload', 'user', 'remote_access', 'pager-webui')) import server def setUpModule(): __import__('importlib').reload(server) def ctx(body=None, args=()): return type('C', (), {'body': body, 'args': args, 'query': {}})() class PineapProxyTest(unittest.TestCase): def test_proxy_get_passthrough(self): server.daemon_sock_call = lambda method, path, body=None, timeout=10: (200, {'loghandshake': False}) status, payload = server.h_pineap_get_config(ctx()) self.assertEqual(status, 200) self.assertEqual(payload['loghandshake'], False) def test_proxy_post_passthrough(self): calls = [] def fake(method, path, body=None, timeout=10): calls.append((method, path, body)) return (200, {'success': True}) server.daemon_sock_call = fake server.h_pineap_enable(ctx({'enable': True})) self.assertEqual(calls[0], ('PUT', '/api/pineap/hostapd/enable_pineap', {'enable': True})) def test_proxy_502_on_socket_failure(self): server.daemon_sock_call = lambda method, path, body=None, timeout=10: (0, None) status, payload = server.h_pineap_get_config(ctx()) self.assertEqual(status, 502) def test_mimic_routes_enable_and_disable(self): calls = [] def fake(method, path, body=None, timeout=10): calls.append(path) return (200, {'success': True}) server.daemon_sock_call = fake server.h_pineap_mimic(ctx({'enable': True})) server.h_pineap_mimic(ctx({'enable': False})) self.assertEqual(calls, ['/api/pineap/mimic/enable', '/api/pineap/mimic/disable']) def test_examine_reset(self): calls = [] def fake(method, path, body=None, timeout=10): calls.append((path, body)) return (200, {'success': True}) server.daemon_sock_call = fake server.h_pineap_examine(ctx({'reset': True})) self.assertEqual(calls[0], ('/api/pineap/examine/reset', {'reset': True})) def test_set_config_forwards_body(self): calls = [] sock_calls = [] def fake_get(method, path, body=None, timeout=10): if path == '/api/pineap/get_config': return 200, {'reconpath': '/root/recon/', 'reconname': 'pager', 'autossidpool': False} sock_calls.append((method, path)) return (200, {'success': True}) def fake(method, path, body=None, timeout=10): calls.append((method, path, body)) return (200, {'success': True}) server.daemon_sock_call = lambda m, p, body=None, timeout=10: fake_get(m, p, body, timeout) if m == 'GET' else fake(m, p, body, timeout) server.h_pineap_set_config(ctx({'loghandshake': True})) self.assertEqual(calls[0][0], 'PUT') self.assertEqual(calls[0][1], '/api/pineap/set_config') self.assertEqual(calls[0][2]['reconpath'], '/root/recon/') self.assertEqual(calls[0][2]['reconname'], 'pager') self.assertEqual(calls[0][2]['loghandshake'], True) self.assertEqual(calls[0][2]['autossidpool'], False) def test_hostapd_set_merges_interfaces(self): calls = [] def fake(method, path, body=None, timeout=10): if method == 'GET': return 200, {'mgmt_ifaces': ['wlan0mgmt'], 'wpa_ifaces': ['wlan0wpa'], 'pineap_disabled': False, 'pineape_disabled': False, 'pineape_auth_pass': True} calls.append((method, path, body)) return (200, {'success': True}) server.daemon_sock_call = fake server.h_pineap_hostapd_set(ctx({'pineape_disabled': True})) method, path, body = calls[0] self.assertEqual(method, 'PUT') self.assertEqual(path, '/api/pineap/hostapd/set_config') self.assertEqual(body['pineape_disabled'], True) self.assertEqual(body['mgmt_ifaces'], ['wlan0mgmt']) self.assertEqual(body['wpa_ifaces'], ['wlan0wpa']) def test_wifi_get_ap_reads_uci_wireless(self): def fake_run(args): cmd = args[0] if cmd == 'uci' and len(args) == 3: sec = args[2] if sec == 'wireless.wlan0wpa': return 0, "wireless.wlan0wpa.ifname='wlan0wpa'\nwireless.wlan0wpa.ssid='Evil1'\nwireless.wlan0wpa.encryption='psk2'\nwireless.wlan0wpa.key='sekret'\nwireless.wlan0wpa.disabled='0'\nwireless.wlan0wpa.hidden='0'\n", '' if sec == 'wireless.wlan0open': return 0, "wireless.wlan0open.disabled='1'\nwireless.wlan0open.ssid='pager-open'\nwireless.wlan0open.macaddr='DE:AD:BE:EF:00:01'\nwireless.wlan0open.hidden='1'\n", '' if sec == 'wireless.radio0': return 0, "wireless.radio0.channel='6'\nwireless.radio0.country='US'\n", '' if sec.startswith('pineapd.@ssidpool'): return 0, "pineapd.@ssidpool[0].bssid='auto'\npineapd.@ssidpool[0].target='broadcast'\n", '' return 0, '', '' def fake_sock(method, path, body=None, timeout=10): if path == '/api/pineap/hostapd/get_config': return 200, {'pineape_disabled': False} if path == '/api/pineap/get_config': return 200, {'autossidpool': True} return 200, {} server.device_run = fake_run server.daemon_sock_call = fake_sock status, payload = server.h_pineap_wifi_get_ap(ctx()) self.assertEqual(status, 200) self.assertEqual(payload['wpa'], {'ssid': 'Evil1', 'passphrase': 'sekret', 'enctype': 'psk2', 'hidden': False, 'enabled': True}) self.assertEqual(payload['open']['enabled'], False) self.assertEqual(payload['open']['ssid'], 'pager-open') self.assertEqual(payload['open']['bssid'], 'DE:AD:BE:EF:00:01') self.assertEqual(payload['open']['hidden'], True) self.assertEqual(payload['open']['channel'], 6) self.assertEqual(payload['open']['country'], 'US') self.assertEqual(payload['open']['target'], 'broadcast') self.assertEqual(payload['enterprise']['enabled'], True) self.assertEqual(payload['pool']['collecting'], True) def test_wifi_set_ap_open_bssid_channel_and_country(self): sock_calls = [] run_calls = [] def fake_sock(method, path, body=None, timeout=10): sock_calls.append((method, path, body)) return (200, {'success': True}) def fake_run(args): run_calls.append(args) if args[0] == 'uci' and args[1] == 'show': return 0, "wireless.radio0.channel='1'\n", '' return 0, '', '' server.daemon_sock_call = fake_sock server.device_run = fake_run status, _ = server.h_pineap_wifi_set_ap(ctx({'open': { 'ssid': 'Open', 'bssid': 'DE:AD:BE:EF:00:02', 'hidden': True, 'channel': 6, 'country': 'US', 'enabled': True}})) self.assertEqual(status, 200) method, path, body = sock_calls[0] self.assertEqual(method, 'PUT') self.assertEqual(path, '/api/settings/wifi/set_ap') conf = body['configs'][0] self.assertEqual(conf['interface'], 'wlan0open') self.assertEqual(conf['ssid'], 'Open') self.assertEqual(conf['bssid'], 'DE:AD:BE:EF:00:02') self.assertEqual(conf['hidden'], True) self.assertEqual(conf['channel'], 6) self.assertEqual(conf['enabled'], True) sets = [a for a in run_calls if a[:2] == ['uci', 'set']] self.assertEqual(sets, [['uci', 'set', 'wireless.radio0.channel=6'], ['uci', 'set', 'wireless.radio0.country=US']]) self.assertIn(['uci', 'commit', 'wireless'], run_calls) self.assertIn(['wifi', 'reload'], run_calls) def test_wifi_set_ap_builds_configs(self): calls = [] def fake_sock(method, path, body=None, timeout=10): calls.append((method, path, body)) return (200, {'success': True}) server.daemon_sock_call = fake_sock status, _ = server.h_pineap_wifi_set_ap(ctx({'wpa': { 'ssid': 'Evil2', 'passphrase': 'pass123', 'enctype': 'sae', 'hidden': True, 'enabled': True}})) self.assertEqual(status, 200) method, path, body = calls[0] self.assertEqual(method, 'PUT') self.assertEqual(path, '/api/settings/wifi/set_ap') self.assertEqual(body['configs'][0]['interface'], 'wlan0wpa') self.assertEqual(body['configs'][0]['ssid'], 'Evil2') self.assertEqual(body['configs'][0]['enctype'], 'sae') self.assertEqual(body['configs'][0]['key'], 'pass123') self.assertEqual(body['configs'][0]['enabled'], True) self.assertEqual(body['configs'][0]['channel'], 1) class PineapFilterTest(unittest.TestCase): def test_filter_get_reads_daemon_mode_and_active_list(self): server.daemon_sock_call = lambda method, path, body=None, timeout=10: ( 200, {'mode': 'deny', 'allowed_macs': ['00:11:22:33:44:55'], 'denied_macs': ['AA:BB:CC:DD:EE:FF']}) status, payload = server.h_filter_get(ctx(), 'client') self.assertEqual(status, 200) self.assertEqual(payload['mode'], 'deny') self.assertEqual(payload['entries'], ['AA:BB:CC:DD:EE:FF']) def test_ssid_filter_get_decodes_daemon_base64_values(self): server.daemon_sock_call = lambda method, path, body=None, timeout=10: ( 200, {'mode': 'allow', 'allowed_ssids': ['Q29kZXhGaWx0ZXJQcm9iZQ==', 'test'], 'denied_ssids': []}) status, payload = server.h_filter_get(ctx(), 'ssid') self.assertEqual(status, 200) self.assertEqual(payload['entries'], ['CodexFilterProbe', 'test']) def test_filter_set_mode_uses_hak5_mode_command(self): calls = [] server.daemon_sock_call = lambda method, path, body=None, timeout=10: ( 200, {'mode': 'deny', 'allowed_macs': [], 'denied_macs': []}) server.device_run = lambda args, timeout=20: (calls.append(args) or (0, '', '')) server.h_filter_post(ctx({'action': 'set_mode', 'mode': 'allow'}), 'client') self.assertEqual(calls[0], [server.HAK5CMD, 'PINEAPPLE_DEVICE_FILTER_MODE', 'allow']) def test_filter_add_includes_active_mode(self): calls = [] server.daemon_sock_call = lambda method, path, body=None, timeout=10: ( 200, {'mode': 'allow', 'allowed_macs': [], 'denied_macs': []}) server.device_run = lambda args, timeout=20: (calls.append(args) or (0, '', '')) server.h_filter_post(ctx({'action': 'add', 'value': '00:11:22:33:44:55'}), 'client') self.assertEqual(calls[0], [server.HAK5CMD, 'PINEAPPLE_DEVICE_FILTER_ADD', 'allow', '00:11:22:33:44:55']) def test_filter_delete_and_clear_include_active_mode(self): calls = [] server.daemon_sock_call = lambda method, path, body=None, timeout=10: ( 200, {'mode': 'deny', 'allowed_ssids': [], 'denied_ssids': ['Guest']}) server.device_run = lambda args, timeout=20: (calls.append(args) or (0, '', '')) server.h_filter_post(ctx({'action': 'delete', 'value': 'Guest'}), 'ssid') server.h_filter_post(ctx({'action': 'clear'}), 'ssid') self.assertEqual(calls[0], [server.HAK5CMD, 'PINEAPPLE_NETWORK_FILTER_DELETE', 'deny', 'Guest']) self.assertEqual(calls[1], [server.HAK5CMD, 'PINEAPPLE_NETWORK_FILTER_CLEAR', 'deny']) def test_filter_allow_all_clears_deny_list_and_sets_deny_mode(self): calls = [] server.daemon_sock_call = lambda method, path, body=None, timeout=10: ( 200, {'mode': 'allow', 'allowed_ssids': ['Guest'], 'denied_ssids': []}) server.device_run = lambda args, timeout=20: (calls.append(args) or (0, '', '')) server.h_filter_post(ctx({'action': 'allow_all'}), 'ssid') self.assertEqual(calls[:2], [ [server.HAK5CMD, 'PINEAPPLE_NETWORK_FILTER_CLEAR', 'deny'], [server.HAK5CMD, 'PINEAPPLE_NETWORK_FILTER_MODE', 'deny']]) if __name__ == '__main__': unittest.main()