Replace WireGuard prototype with native host service and scoped access
This commit is contained in:
1 parent
37b5394df1
commit
11f16ef4a3
16 files changed
+667
-136
No files matched your search
@@ -0,0 +1,59 @@
|
||||
import json
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
from network.config import parse_config,ConfigError
|
||||
from network.native import Manager
|
||||
|
||||
CONF='''[Interface]
|
||||
PrivateKey = AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE=
|
||||
Address = 192.0.2.10/24, fd00::10/64
|
||||
DNS = 192.0.2.1
|
||||
DNS = example.test
|
||||
[Peer]
|
||||
PublicKey = AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgI=
|
||||
AllowedIPs = 0.0.0.0/0, ::/0
|
||||
Endpoint = vpn.example.test:51820
|
||||
PersistentKeepalive = 25
|
||||
'''
|
||||
class NativeTests(unittest.TestCase):
|
||||
def manager(self,root):
|
||||
with patch.object(Manager,'reconcile'):return Manager(root,dict(lan_address='192.0.2.11',gui_port=8108,ports=[8108,8120]))
|
||||
def test_dual_stack_repeated_dns(self):
|
||||
c=parse_config(CONF,native=True);self.assertEqual(len(c['addresses']),2);self.assertEqual(c['allowed_ips'],['0.0.0.0/0','::/0']);self.assertTrue(c['warnings'])
|
||||
def test_hooks_rejected(self):
|
||||
with self.assertRaises(ConfigError):parse_config(CONF.replace('DNS = example.test','PostUp = echo unsafe'),native=True)
|
||||
def test_no_key_in_status_and_backup_complete(self):
|
||||
with tempfile.TemporaryDirectory() as t:
|
||||
m=self.manager(t);m.dispatch(dict(action='import',config=CONF));s=m.status()
|
||||
self.assertNotIn('PrivateKey',json.dumps(s));self.assertNotIn('AQEBAQ',json.dumps(s));self.assertEqual(m.dispatch(dict(action='backup-export'))['config'],CONF)
|
||||
self.assertEqual((Path(t)/'config.json').stat().st_mode&0o777,0o600)
|
||||
def test_confirm_requires_native_ingress_token(self):
|
||||
with tempfile.TemporaryDirectory() as t:
|
||||
m=self.manager(t)
|
||||
with patch.object(m,'connected',return_value=(True,1)):
|
||||
s=m.dispatch(dict(action='mode',mode='both'));trial=s['pending']['id']
|
||||
with self.assertRaises(ValueError):m.dispatch(dict(action='confirm',trial_id=trial,ingress='tunnel',proxy_token='fake'))
|
||||
m.dispatch(dict(action='confirm',trial_id=trial,ingress='tunnel',proxy_token=m.token));self.assertEqual(m.policy.mode,'both')
|
||||
def test_duplicate_host_ip_aborts_without_mutation(self):
|
||||
with tempfile.TemporaryDirectory() as t:
|
||||
m=self.manager(t);m.dispatch(dict(action='import',config=CONF))
|
||||
with patch('network.native.run',return_value=json.dumps([{'addr_info':[{'local':'192.0.2.10'}]}])) as command:
|
||||
with self.assertRaises(ValueError):m.connect()
|
||||
self.assertEqual(command.call_count,1);self.assertFalse(m.enabled)
|
||||
def test_source_routes_only_and_owned_cleanup(self):
|
||||
with tempfile.TemporaryDirectory() as t:
|
||||
m=self.manager(t);m.dispatch(dict(action='import',config=CONF));calls=[]
|
||||
def command(args,check=True):calls.append(args);return '[]' if '-j' in args else ''
|
||||
with patch('network.native.run',side_effect=command),patch.object(m,'reconcile'):
|
||||
m.connect();self.assertTrue(m.enabled)
|
||||
self.assertFalse(any('main' in a or 'default' in a for a in calls))
|
||||
up=next(i for i,a in enumerate(calls) if a[:3]==['ip','link','set'])
|
||||
route=next(i for i,a in enumerate(calls) if a[:4]==['ip','-4','route','add'])
|
||||
self.assertLess(up,route)
|
||||
self.assertTrue(any(a[:4]==['ip','-4','rule','add'] and 'from' in a for a in calls))
|
||||
self.assertTrue(any(a[:4]==['ip','-6','rule','add'] for a in calls))
|
||||
m.disconnect();self.assertFalse(m.enabled)
|
||||
self.assertFalse(any('iptables' in a or 'nft' in a for a in calls))
|
||||
if __name__=='__main__':unittest.main()
|
||||
Reference in new issue
Block a user