|
|
@ -1,8 +1,8 @@ |
|
|
|
#!/usr/bin/python |
|
|
|
# -*- coding:utf-8 -*- |
|
|
|
|
|
|
|
from ProxyFilter import Plugin |
|
|
|
from ProxyFilter import baseFunc |
|
|
|
from ProxyFilter import Plugin as sip003 |
|
|
|
|
|
|
|
ssMethodList = [ # Shadowsocks加密方式 |
|
|
|
'aes-128-gcm', |
|
|
@ -56,94 +56,60 @@ ssMethodList = [ # Shadowsocks加密方式 |
|
|
|
'xchacha20-ietf-poly1305' |
|
|
|
] |
|
|
|
|
|
|
|
pluginList = [ # SIP003插件列表 |
|
|
|
'obfs-local', |
|
|
|
'simple-tls', |
|
|
|
'v2ray-plugin', |
|
|
|
'xray-plugin', |
|
|
|
'kcptun-client', |
|
|
|
'gost-plugin', |
|
|
|
'ck-client', |
|
|
|
'gq-client', |
|
|
|
'mtt-client', |
|
|
|
'rabbit-plugin', |
|
|
|
'qtun-client', |
|
|
|
'gun-plugin' |
|
|
|
] |
|
|
|
|
|
|
|
def __ssFill(raw: dict) -> dict: # 补全可选值 |
|
|
|
try: |
|
|
|
if 'plugin' not in raw: |
|
|
|
raw['plugin'] = None |
|
|
|
if raw['plugin'] is not None: |
|
|
|
if 'param' not in raw['plugin']: |
|
|
|
raw['plugin']['param'] = '' |
|
|
|
except: |
|
|
|
pass |
|
|
|
return raw |
|
|
|
|
|
|
|
def __ssFormat(raw: dict) -> dict: # 容错性格式化 |
|
|
|
try: |
|
|
|
raw['server'] = raw['server'].strip() |
|
|
|
raw['port'] = int(raw['port']) |
|
|
|
raw['method'] = raw['method'].replace('_', '-').lower().strip() |
|
|
|
if isinstance(raw['plugin'], str): |
|
|
|
raw['plugin'] = raw['plugin'].strip() |
|
|
|
if raw['plugin'] == '': |
|
|
|
raw['plugin'] = None |
|
|
|
else: |
|
|
|
raw['plugin'] = { |
|
|
|
'type': raw['plugin'], |
|
|
|
'param': '' |
|
|
|
ssFilterRules = { |
|
|
|
'rootObject': { |
|
|
|
'remark': { |
|
|
|
'optional': False, |
|
|
|
'default': '', |
|
|
|
'type': str |
|
|
|
}, |
|
|
|
'server': { |
|
|
|
'optional': True, |
|
|
|
'type': str, |
|
|
|
'format': lambda s: s.lower().strip(), |
|
|
|
'filter': baseFunc.isHost, |
|
|
|
'errMsg': 'Illegal server address' |
|
|
|
}, |
|
|
|
'port': { |
|
|
|
'optional': True, |
|
|
|
'type': int, |
|
|
|
'format': lambda i: int(i), |
|
|
|
'filter': baseFunc.isPort, |
|
|
|
'errMsg': 'Illegal port number' |
|
|
|
}, |
|
|
|
'method': { |
|
|
|
'optional': True, |
|
|
|
'type': str, |
|
|
|
'format': lambda s: s.replace('_', '-').lower().strip(), |
|
|
|
'filter': lambda method: method in ssMethodList, |
|
|
|
'errMsg': 'Unknown Shadowsocks method' |
|
|
|
}, |
|
|
|
'passwd': { |
|
|
|
'optional': True, |
|
|
|
'type': str |
|
|
|
}, |
|
|
|
'plugin': { |
|
|
|
'optional': False, |
|
|
|
'default': None, |
|
|
|
'allowNone': True, |
|
|
|
'type': 'pluginObject' |
|
|
|
} |
|
|
|
if raw['plugin'] is not None: |
|
|
|
if isinstance(raw['plugin']['type'], str): |
|
|
|
raw['plugin']['type'] = raw['plugin']['type'].strip() |
|
|
|
if raw['plugin']['type'] in [None, '']: |
|
|
|
raw['plugin'] = None |
|
|
|
else: |
|
|
|
raw['plugin']['type'] = sip003.pluginFormat(raw['plugin']['type']) |
|
|
|
except: |
|
|
|
pass |
|
|
|
return raw |
|
|
|
|
|
|
|
def __ssParamCheck(raw: dict) -> tuple[bool, str or None]: # 参数检查 |
|
|
|
try: |
|
|
|
if 'server' not in raw: |
|
|
|
return False, 'Missing `server` option' |
|
|
|
if 'port' not in raw: |
|
|
|
return False, 'Missing `port` option' |
|
|
|
if 'method' not in raw: |
|
|
|
return False, 'Missing `method` option' |
|
|
|
if 'passwd' not in raw: |
|
|
|
return False, 'Missing `passwd` option' |
|
|
|
if 'plugin' not in raw: |
|
|
|
return False, 'Missing `plugin` option' |
|
|
|
if raw['plugin'] is not None: |
|
|
|
if 'type' not in raw['plugin']: |
|
|
|
return False, 'Missing `plugin.type` option' |
|
|
|
if 'param' not in raw['plugin']: |
|
|
|
return False, 'Missing `plugin.param` option' |
|
|
|
|
|
|
|
if not isinstance(raw['server'], str): |
|
|
|
return False, 'Illegal `server` option' |
|
|
|
if not isinstance(raw['port'], int): |
|
|
|
return False, 'Illegal `int` option' |
|
|
|
if not isinstance(raw['method'], str): |
|
|
|
return False, 'Illegal `method` option' |
|
|
|
if not isinstance(raw['passwd'], str): |
|
|
|
return False, 'Illegal `passwd` option' |
|
|
|
if (raw['plugin'] is not None) and (not isinstance(raw['plugin'], dict)): |
|
|
|
return False, 'Illegal `plugin` option' |
|
|
|
|
|
|
|
if raw['plugin'] is not None: |
|
|
|
if not isinstance(raw['plugin']['type'], str): |
|
|
|
return False, 'Illegal `plugin.type` option' |
|
|
|
if not isinstance(raw['plugin']['param'], str): |
|
|
|
return False, 'Illegal `plugin.param` option' |
|
|
|
except: |
|
|
|
return False, 'Unknown error' |
|
|
|
return True, None |
|
|
|
}, |
|
|
|
'pluginObject': { |
|
|
|
'type': { |
|
|
|
'optional': True, |
|
|
|
'type': str, |
|
|
|
'format': Plugin.pluginFormat, |
|
|
|
'filter': Plugin.isPlugin, |
|
|
|
'errMsg': 'Unknown SIP003 plugin' |
|
|
|
}, |
|
|
|
'param': { |
|
|
|
'optional': False, |
|
|
|
'default': '', |
|
|
|
'type': str |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
def ssFilter(rawInfo: dict, isExtra: bool) -> tuple[bool, str or dict]: |
|
|
|
""" |
|
|
@ -159,47 +125,8 @@ def ssFilter(rawInfo: dict, isExtra: bool) -> tuple[bool, str or dict]: |
|
|
|
} |
|
|
|
""" |
|
|
|
try: |
|
|
|
raw = rawInfo |
|
|
|
raw = __ssFormat(__ssFill(raw)) # 预处理 |
|
|
|
status, reason = __ssParamCheck(raw) # 参数检查 |
|
|
|
if not status: # 参数有误 |
|
|
|
return False, reason |
|
|
|
|
|
|
|
result = {'type': 'ss'} |
|
|
|
if isExtra: # 携带额外参数 |
|
|
|
if 'remark' not in raw: # 补全默认值 |
|
|
|
raw['remark'] = '' |
|
|
|
if raw['remark'] is None: # 容错格式化 |
|
|
|
raw['remark'] = '' |
|
|
|
if not isinstance(raw['remark'], str): # 参数检查 |
|
|
|
return False, 'Illegal `remark` option' |
|
|
|
result['remark'] = raw['remark'] |
|
|
|
|
|
|
|
if baseFunc.isHost(raw['server']): |
|
|
|
result['server'] = raw['server'] # server |
|
|
|
else: |
|
|
|
return False, 'Illegal `server` option' |
|
|
|
if baseFunc.isPort(raw['port']): |
|
|
|
result['port'] = raw['port'] # port |
|
|
|
else: |
|
|
|
return False, 'Illegal `port` option' |
|
|
|
if raw['method'] in ssMethodList: |
|
|
|
result['method'] = raw['method'] # method |
|
|
|
else: |
|
|
|
return False, 'Unknown Shadowsocks method' |
|
|
|
result['passwd'] = raw['passwd'] # passwd |
|
|
|
|
|
|
|
if raw['plugin'] is None: |
|
|
|
plugin = None |
|
|
|
else: |
|
|
|
if raw['plugin']['type'] in pluginList: |
|
|
|
plugin = { |
|
|
|
'type': raw['plugin']['type'], |
|
|
|
'param': raw['plugin']['param'] |
|
|
|
} |
|
|
|
else: |
|
|
|
return False, 'Unknown sip003 plugin' |
|
|
|
result['plugin'] = plugin |
|
|
|
if not isExtra: |
|
|
|
ssFilterRules['rootObject'].pop('remark') |
|
|
|
return baseFunc.rulesFilter(rawInfo, ssFilterRules) |
|
|
|
except: |
|
|
|
return False, 'Unknown error' |
|
|
|
return True, result |
|
|
|