Supply pinned offline GeoIP data and distinguish VMess JSON variants
This commit is contained in:
parent
7962ada5ae
commit
dce1309842
@ -106,6 +106,9 @@ def validate(kind, data):
|
|||||||
if not sep or scheme not in ['vmess','vless','ss','ssr','trojan','hysteria','hysteria2','hy2','tuic','anytls','socks','socks5','http','https']:issue('unsupported_or_missing_scheme',line=i);continue
|
if not sep or scheme not in ['vmess','vless','ss','ssr','trojan','hysteria','hysteria2','hy2','tuic','anytls','socks','socks5','http','https']:issue('unsupported_or_missing_scheme',line=i);continue
|
||||||
if not payload:issue('empty_payload',line=i);continue
|
if not payload:issue('empty_payload',line=i);continue
|
||||||
if scheme=='vmess':
|
if scheme=='vmess':
|
||||||
|
if unquote(payload).lstrip().startswith('{'):
|
||||||
|
issue('nonstandard_vmess_json_payload_requires_client_check',line=i)
|
||||||
|
continue
|
||||||
payload=payload.split('#',1)[0].split('?',1)[0]
|
payload=payload.split('#',1)[0].split('?',1)[0]
|
||||||
try:
|
try:
|
||||||
n=json.loads(b64(payload).decode());remember(n)
|
n=json.loads(b64(payload).decode());remember(n)
|
||||||
@ -136,6 +139,9 @@ def core_check(kind, path, root, binaries, private):
|
|||||||
core=binaries/('mihomo' if kind=='clash' else 'sing-box')
|
core=binaries/('mihomo' if kind=='clash' else 'sing-box')
|
||||||
if not core.exists():return {'status':'not_tested','reason':'core_missing'}
|
if not core.exists():return {'status':'not_tested','reason':'core_missing'}
|
||||||
home=root/('core-'+kind);home.mkdir(mode=0o700,exist_ok=True)
|
home=root/('core-'+kind);home.mkdir(mode=0o700,exist_ok=True)
|
||||||
|
if kind=='clash':
|
||||||
|
for name in ['Country.mmdb','geoip.metadb']:
|
||||||
|
if (binaries/name).exists():shutil.copyfile(binaries/name,home/name)
|
||||||
args=[str(core),'-t','-d',str(home),'-f',str(path)] if kind=='clash' else [str(core),'check','-D',str(home),'-c',str(path)]
|
args=[str(core),'-t','-d',str(home),'-f',str(path)] if kind=='clash' else [str(core),'check','-D',str(home),'-c',str(path)]
|
||||||
# A private network blocks rule/provider downloads and all node traffic. No proxy is started.
|
# A private network blocks rule/provider downloads and all node traffic. No proxy is started.
|
||||||
wrapper=['systemd-run','--quiet','--wait','--pipe','--collect','--service-type=exec','-p','MemoryMax=256M','-p','MemorySwapMax=0','-p','CPUQuota=50%','-p','RuntimeMaxSec=45','-p','PrivateNetwork=yes','-p','NoNewPrivileges=yes','-p','ProtectSystem=strict','-p','ReadWritePaths='+str(home),'-p','TasksMax=64','/usr/bin/time','-f','CHECKER_MAX_RSS_KB=%M']
|
wrapper=['systemd-run','--quiet','--wait','--pipe','--collect','--service-type=exec','-p','MemoryMax=256M','-p','MemorySwapMax=0','-p','CPUQuota=50%','-p','RuntimeMaxSec=45','-p','PrivateNetwork=yes','-p','NoNewPrivileges=yes','-p','ProtectSystem=strict','-p','ReadWritePaths='+str(home),'-p','TasksMax=64','/usr/bin/time','-f','CHECKER_MAX_RSS_KB=%M']
|
||||||
|
|||||||
@ -1,4 +1,22 @@
|
|||||||
{
|
{
|
||||||
"mihomo": {"version":"v1.19.32","url":"https://github.com/MetaCubeX/mihomo/releases/download/v1.19.32/mihomo-linux-amd64-compatible-v1.19.32.gz","sha256":"ba3ce607747a07f948fc35780e108a4a7c7f552a38b9bd4d115f313ebcb89c20"},
|
"mihomo": {
|
||||||
"sing-box": {"version":"v1.14.3","url":"https://github.com/SagerNet/sing-box/releases/download/v1.14.3/sing-box-1.14.3-linux-amd64.tar.gz","sha256":"e2bdf179c15a3652955dc44867e33ca0965c9c9b91b34267dcc5a5d639a5feee"}
|
"version": "v1.19.32",
|
||||||
|
"url": "https://github.com/MetaCubeX/mihomo/releases/download/v1.19.32/mihomo-linux-amd64-compatible-v1.19.32.gz",
|
||||||
|
"sha256": "ba3ce607747a07f948fc35780e108a4a7c7f552a38b9bd4d115f313ebcb89c20"
|
||||||
|
},
|
||||||
|
"sing-box": {
|
||||||
|
"version": "v1.14.3",
|
||||||
|
"url": "https://github.com/SagerNet/sing-box/releases/download/v1.14.3/sing-box-1.14.3-linux-amd64.tar.gz",
|
||||||
|
"sha256": "e2bdf179c15a3652955dc44867e33ca0965c9c9b91b34267dcc5a5d639a5feee"
|
||||||
|
},
|
||||||
|
"Country.mmdb": {
|
||||||
|
"version": "snapshot-20261018",
|
||||||
|
"url": "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/country.mmdb",
|
||||||
|
"sha256": "64809d264be87ecfb7ac3ad19b7678893b6275038a7d4bf9eec72464a6c4f9fe"
|
||||||
|
},
|
||||||
|
"geoip.metadb": {
|
||||||
|
"version": "snapshot-20261018",
|
||||||
|
"url": "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.metadb",
|
||||||
|
"sha256": "ec6701e428b7efe610fe40b187a69fb03324892a56792b033adc080d2b6c273e"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,8 @@ for name,info in manifest.items():
|
|||||||
req=urllib.request.Request(info['url'],headers={'User-Agent':'cfn-subscription-checker'})
|
req=urllib.request.Request(info['url'],headers={'User-Agent':'cfn-subscription-checker'})
|
||||||
with urllib.request.urlopen(req,timeout=90) as r: data=r.read(100*1024*1024)
|
with urllib.request.urlopen(req,timeout=90) as r: data=r.read(100*1024*1024)
|
||||||
if hashlib.sha256(data).hexdigest()!=info['sha256']:raise RuntimeError('checksum mismatch: '+name)
|
if hashlib.sha256(data).hexdigest()!=info['sha256']:raise RuntimeError('checksum mismatch: '+name)
|
||||||
if name=='mihomo':binary=gzip.decompress(data)
|
if name in ['Country.mmdb','geoip.metadb']:binary=data
|
||||||
|
elif name=='mihomo':binary=gzip.decompress(data)
|
||||||
else:
|
else:
|
||||||
with tarfile.open(fileobj=io.BytesIO(data),mode='r:gz') as t:
|
with tarfile.open(fileobj=io.BytesIO(data),mode='r:gz') as t:
|
||||||
members=[m for m in t.getmembers() if m.isfile() and Path(m.name).name=='sing-box']
|
members=[m for m in t.getmembers() if m.isfile() and Path(m.name).name=='sing-box']
|
||||||
|
|||||||
@ -8,6 +8,9 @@ class ValidationTests(unittest.TestCase):
|
|||||||
def test_vmess_fragment_is_not_part_of_base64(self):
|
def test_vmess_fragment_is_not_part_of_base64(self):
|
||||||
s='vmess://'+base64.b64encode(json.dumps({'add':'example.com','port':443,'id':'test-id'}).encode()).decode()+'#node'
|
s='vmess://'+base64.b64encode(json.dumps({'add':'example.com','port':443,'id':'test-id'}).encode()).decode()+'#node'
|
||||||
self.assertEqual(self.codes('v2ray',s),set())
|
self.assertEqual(self.codes('v2ray',s),set())
|
||||||
|
def test_plain_json_vmess_is_reported_as_client_compatibility(self):
|
||||||
|
s='vmess://'+json.dumps({'add':'example.com','port':443,'id':'test-id'})
|
||||||
|
self.assertEqual(self.codes('v2ray',s),{'nonstandard_vmess_json_payload_requires_client_check'})
|
||||||
def test_empty_server_and_port_zero_in_valid_json(self):
|
def test_empty_server_and_port_zero_in_valid_json(self):
|
||||||
codes=self.codes('singbox',json.dumps({'outbounds':[{'type':'vmess','tag':'bad','server':'','server_port':0,'uuid':'test'}]}))
|
codes=self.codes('singbox',json.dumps({'outbounds':[{'type':'vmess','tag':'bad','server':'','server_port':0,'uuid':'test'}]}))
|
||||||
self.assertEqual(codes,{'missing_or_empty_field','invalid_port'})
|
self.assertEqual(codes,{'missing_or_empty_field','invalid_port'})
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user