|
|
|
#!/usr/bin/python
|
|
|
|
# -*- coding:utf-8 -*-
|
|
|
|
|
|
|
|
from ProxyFilter import baseFunc
|
|
|
|
|
|
|
|
ssrMethodList = [ # ShadowsocksR加密方式
|
|
|
|
'aes-128-cfb',
|
|
|
|
'aes-192-cfb',
|
|
|
|
'aes-256-cfb',
|
|
|
|
'aes-128-cfb1',
|
|
|
|
'aes-192-cfb1',
|
|
|
|
'aes-256-cfb1',
|
|
|
|
'aes-128-cfb8',
|
|
|
|
'aes-192-cfb8',
|
|
|
|
'aes-256-cfb8',
|
|
|
|
'aes-128-ctr',
|
|
|
|
'aes-192-ctr',
|
|
|
|
'aes-256-ctr',
|
|
|
|
'aes-128-gcm',
|
|
|
|
'aes-192-gcm',
|
|
|
|
'aes-256-gcm',
|
|
|
|
'aes-128-ofb',
|
|
|
|
'aes-192-ofb',
|
|
|
|
'aes-256-ofb',
|
|
|
|
'camellia-128-cfb',
|
|
|
|
'camellia-192-cfb',
|
|
|
|
'camellia-256-cfb',
|
|
|
|
'none',
|
|
|
|
'table',
|
|
|
|
'rc4',
|
|
|
|
'rc4-md5',
|
|
|
|
'rc4-md5-6',
|
|
|
|
'bf-cfb',
|
|
|
|
'cast5-cfb',
|
|
|
|
'des-cfb',
|
|
|
|
'idea-cfb',
|
|
|
|
'seed-cfb',
|
|
|
|
'rc2-cfb',
|
|
|
|
'salsa20',
|
|
|
|
'xsalsa20',
|
|
|
|
'chacha20',
|
|
|
|
'xchacha20',
|
|
|
|
'chacha20-ietf',
|
|
|
|
]
|
|
|
|
|
|
|
|
ssrProtocolList = [ # ShadowsocksR协议
|
|
|
|
'origin',
|
|
|
|
'verify_sha1',
|
|
|
|
'verify_simple',
|
|
|
|
'verify_deflate',
|
|
|
|
'auth_simple',
|
|
|
|
'auth_sha1',
|
|
|
|
'auth_sha1_v2',
|
|
|
|
'auth_sha1_v4',
|
|
|
|
'auth_aes128',
|
|
|
|
'auth_aes128_md5',
|
|
|
|
'auth_aes128_sha1',
|
|
|
|
'auth_chain_a',
|
|
|
|
'auth_chain_b',
|
|
|
|
'auth_chain_c',
|
|
|
|
'auth_chain_d',
|
|
|
|
'auth_chain_e',
|
|
|
|
'auth_chain_f',
|
|
|
|
]
|
|
|
|
|
|
|
|
ssrObfsList = [ # ShadowsocksR混淆方式
|
|
|
|
'plain',
|
|
|
|
'http_post',
|
|
|
|
'http_simple',
|
|
|
|
'tls_simple',
|
|
|
|
'tls1.2_ticket_auth',
|
|
|
|
'tls1.2_ticket_fastauth',
|
|
|
|
'random_head',
|
|
|
|
]
|
|
|
|
|
|
|
|
def __ssrProtocol(protocol) -> str:
|
|
|
|
protocol = baseFunc.toStrTidy(protocol).replace('-', '_')
|
|
|
|
if protocol == '':
|
|
|
|
return 'origin'
|
|
|
|
return protocol
|
|
|
|
|
|
|
|
def __ssrObfs(obfs) -> str:
|
|
|
|
obfs = baseFunc.toStrTidy(obfs).replace('-', '_')
|
|
|
|
if obfs == '':
|
|
|
|
return 'plain'
|
|
|
|
return obfs
|
|
|
|
|
|
|
|
ssrFilterRules = {
|
|
|
|
'rootObject': {
|
|
|
|
'remark': {
|
|
|
|
'optional': False,
|
|
|
|
'default': '',
|
|
|
|
'type': str,
|
|
|
|
'format': baseFunc.toStr
|
|
|
|
},
|
|
|
|
'group': {
|
|
|
|
'optional': False,
|
|
|
|
'default': '',
|
|
|
|
'type': str,
|
|
|
|
'format': baseFunc.toStr
|
|
|
|
},
|
|
|
|
'server': {
|
|
|
|
'optional': True,
|
|
|
|
'type': str,
|
|
|
|
'format': baseFunc.toStrTidy,
|
|
|
|
'filter': baseFunc.isHost,
|
|
|
|
'errMsg': 'Illegal server address'
|
|
|
|
},
|
|
|
|
'port': {
|
|
|
|
'optional': True,
|
|
|
|
'type': int,
|
|
|
|
'format': baseFunc.toInt,
|
|
|
|
'filter': baseFunc.isPort,
|
|
|
|
'errMsg': 'Illegal port number'
|
|
|
|
},
|
|
|
|
'method': {
|
|
|
|
'optional': True,
|
|
|
|
'type': str,
|
|
|
|
'format': lambda s: baseFunc.toStrTidy(s).replace('_', '-'),
|
|
|
|
'filter': lambda method: method in ssrMethodList,
|
|
|
|
'errMsg': 'Unknown ShadowsocksR method'
|
|
|
|
},
|
|
|
|
'passwd': {
|
|
|
|
'optional': True,
|
|
|
|
'type': str,
|
|
|
|
'format': baseFunc.toStr
|
|
|
|
},
|
|
|
|
'protocol': {
|
|
|
|
'optional': False,
|
|
|
|
'default': 'origin',
|
|
|
|
'type': str,
|
|
|
|
'format': __ssrProtocol,
|
|
|
|
'filter': lambda protocol: protocol in ssrProtocolList,
|
|
|
|
'errMsg': 'Unknown ShadowsocksR protocol'
|
|
|
|
},
|
|
|
|
'protocolParam': {
|
|
|
|
'optional': False,
|
|
|
|
'default': '',
|
|
|
|
'type': str,
|
|
|
|
'format': baseFunc.toStr
|
|
|
|
},
|
|
|
|
'obfs': {
|
|
|
|
'optional': False,
|
|
|
|
'default': 'plain',
|
|
|
|
'type': str,
|
|
|
|
'format': __ssrObfs,
|
|
|
|
'filter': lambda obfs: obfs in ssrObfsList,
|
|
|
|
'errMsg': 'Unknown ShadowsocksR obfs'
|
|
|
|
},
|
|
|
|
'obfsParam': {
|
|
|
|
'optional': False,
|
|
|
|
'default': '',
|
|
|
|
'type': str,
|
|
|
|
'format': baseFunc.toStr
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
def ssrFilter(rawInfo: dict, isExtra: bool) -> tuple[bool, str or dict]:
|
|
|
|
"""
|
|
|
|
ShadowsocksR节点合法性检查
|
|
|
|
|
|
|
|
不合法:
|
|
|
|
return False, {reason}
|
|
|
|
|
|
|
|
合法:
|
|
|
|
return True, {
|
|
|
|
'type': 'ssr',
|
|
|
|
...
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
try:
|
|
|
|
if not isExtra: # 去除非必要参数
|
|
|
|
ssrFilterRules['rootObject'].pop('remark')
|
|
|
|
ssrFilterRules['rootObject'].pop('group')
|
|
|
|
status, result = baseFunc.ruleFilter(rawInfo, ssrFilterRules, {})
|
|
|
|
if not status: # 节点格式错误
|
|
|
|
return False, result
|
|
|
|
if result['protocol'] == 'origin': # origin无参数
|
|
|
|
result['protocolParam'] = ''
|
|
|
|
if result['obfs'] == 'plain': # plain无参数
|
|
|
|
result['obfsParam'] = ''
|
|
|
|
return True, result
|
|
|
|
except:
|
|
|
|
return False, 'Unknown error'
|