Browse Source

feat: Trojan-Go share url decode

master
Dnomd343 3 years ago
parent
commit
460852fcf8
  1. 2
      ProxyDecoder/Trojan.py
  2. 96
      ProxyDecoder/TrojanGo.py
  3. 3
      ProxyDecoder/decoder.py
  4. 52
      demo.py

2
ProxyDecoder/Trojan.py

@ -8,7 +8,7 @@ def __trojanCommonDecode(url: str) -> dict:
"""
Trojan标准分享链接解码
FORMAT: trojan://$(UUID)@server:port?{fields}#$(remark)
FORMAT: trojan://$(password)@server:port?{fields}#$(remark)
type -> tcp / kcp / ws / http / quic / grpc

96
ProxyDecoder/TrojanGo.py

@ -0,0 +1,96 @@
#!/usr/bin/python
# -*- coding:utf-8 -*-
import re
from ProxyDecoder import baseFunc
def __trojanGoCommonDecode(url: str) -> dict:
"""
Trojan-Go标准分享链接解码
FORMAT: trojan-go://$(password)@server:port/?{fields}#$(remark)
sni -> TLS SNI
type -> original / ws
host -> WebSocket Host
path -> WebSocket Path
encryption -> urlEncode(ss;aes-256-gcm;ss-password)
plugin -> urlEncode(pluginName;pluginOption) -> officially undefined (refer to SIP002 scheme)
"""
match = re.search(r'^trojan-go://([\S]+?)(#[\S]*)?$', url) # trojan-go://...#REMARK
remark = baseFunc.urlDecode(
match[2][1:] if match[2] is not None else ''
)
match = re.search(
r'^([\S]+)@([a-zA-Z0-9.:\-_\[\]]+)/?([\S]*)$', match[1] # $(password)@server[:port]/?...
)
info = {
'passwd': baseFunc.urlDecode(match[1]),
'remark': remark
}
params = baseFunc.paramSplit(match[3])
match = re.search(
r'^([a-zA-Z0-9.:\-_\[\]]+?)(:([0-9]{1,5}))?$', match[2] # server[:port]
)
info['server'] = baseFunc.formatHost(match[1])
info['port'] = int(match[3]) if match[3] is not None else 443
if 'sni' in params:
info['sni'] = params['sni']
if 'type' in params:
if params['type'] not in ['', 'original', 'ws']:
raise Exception('Unknown Trojan-Go network type')
if params['type'] == 'ws': # WebSocket mode
info['ws'] = {}
if 'host' in params:
info['ws']['host'] = params['host']
if 'path' in params:
info['ws']['path'] = params['path']
if 'encryption' in params and params['encryption'] not in ['', 'none']: # shadowsocks encrypt
match = re.search(
r'^ss;([a-zA-Z0-9\-_]+):([\S]+)$', params['encryption']
)
info['ss'] = {
'method': match[1],
'passwd': match[2]
}
if 'plugin' in params and params['plugin'] not in ['', 'none']: # SIP003 plugin
match = re.search(
r'^([\S]+?)(;([\S]+))?$', params['plugin']
)
info['plugin'] = {
'type': match[1],
'param': match[3] if match[3] is not None else ''
}
return info
def trojanGoDecode(url: str) -> dict or None:
"""
Trojan-Go分享链接解码
链接合法:
return {
'type': 'trojan-go',
...
}
链接不合法:
return None
"""
if url[0:12] != 'trojan-go://':
return None
try:
result = __trojanGoCommonDecode(url) # try Trojan-Go common decode
except:
return None
result['type'] = 'trojan-go'
return result

3
ProxyDecoder/decoder.py

@ -7,6 +7,7 @@ from ProxyDecoder import ShadowsocksR
from ProxyDecoder import VMess
from ProxyDecoder import VLESS
from ProxyDecoder import Trojan
from ProxyDecoder import TrojanGo
def decode(url: str) -> dict or None:
"""
@ -34,6 +35,8 @@ def decode(url: str) -> dict or None:
return VLESS.vlessDecode(url)
elif scheme == 'trojan':
return Trojan.trojanDecode(url)
elif scheme == 'trojan-go':
return TrojanGo.trojanGoDecode(url)
except:
pass
return None

52
demo.py

@ -5,32 +5,32 @@ import ProxyDecoder as Decoder
import ProxyFilter as Filter
import Check as Checker
info = {
'type': 'trojan-go',
'server': '127.0.0.1',
'port': 12345,
'passwd': 'dnomd343',
'sni': 'local.343.re',
'plugin': {
'type': 'simple-tls',
'param': 'n=local.343.re;no-verify'
}
}
# info = {
# 'type': 'trojan-go',
# 'server': '127.0.0.1',
# 'port': 12345,
# 'passwd': 'dnomd343',
# 'sni': 'local.343.re',
# 'plugin': {
# 'type': 'simple-tls',
# 'param': 'n=local.343.re;no-verify'
# }
# }
#
# status, ret = Filter.filte(info, isExtra = True)
# print(status)
# print(ret)
#
# data = Checker.proxyTest({
# 'check': ['http'],
# 'info': ret
# })
#
# print(data)
status, ret = Filter.filte(info, isExtra = True)
print(status)
url = 'trojan-go://password1234@google.com/?sni=microsoft.com&type=ws&host=youtube.com&path=%2Fgo&encryption=ss%3Baes-256-gcm%3Afuckgfw&plugin=obfs-local%3Bobfs%3Dhttp%3Bobfs-host%3Dwww.bing.com#server%20name'
ret = Decoder.decode(url)
print(ret)
data = Checker.proxyTest({
'check': ['http'],
'info': ret
})
print(data)
# status, client = Builder.build(ret, '/tmp/ProxyC')
# print(status)
# print(client)
#
# time.sleep(300)
# Builder.destroy(client)
ret = Filter.filte(ret)
print(ret)

Loading…
Cancel
Save