refacter project
This commit is contained in:
parent
47a51c431d
commit
f7d7b68fa0
6 changed files with 665 additions and 13 deletions
537
utils/dnsstamps.py
Normal file
537
utils/dnsstamps.py
Normal file
|
|
@ -0,0 +1,537 @@
|
|||
import base64
|
||||
|
||||
|
||||
def parse(stamp: str):
|
||||
b = base64.urlsafe_b64decode(stamp.removeprefix("sdns://") + "==")
|
||||
if b[0] == 0x01:
|
||||
return DNSCrypt.parse(stamp)
|
||||
elif b[0] == 0x02:
|
||||
return DNSoverHTTPS.parse(stamp)
|
||||
elif b[0] == 0x03:
|
||||
return DNSoverTLS.parse(stamp)
|
||||
elif b[0] == 0x04:
|
||||
return DNSoverQUIC.parse(stamp)
|
||||
elif b[0] == 0x05:
|
||||
return ObliviousDoH.parse(stamp)
|
||||
elif b[0] == 0x81:
|
||||
return DNSCryptRelay.parse(stamp)
|
||||
elif b[0] == 0x85:
|
||||
return ObliviousDoHrelay.parse(stamp)
|
||||
elif b[0] == 0x00:
|
||||
return PlainDNS.parse(stamp)
|
||||
|
||||
|
||||
# Code from https://github.com/DNSCrypt/dnscrypt-resolvers/blob/21fcbaf858112c63fed2a504714cc829bd654483/utils/format.py#L101-L141
|
||||
class DNSCrypt:
|
||||
dnssec: bool = False
|
||||
nolog: bool = False
|
||||
nofilter: bool = False
|
||||
addr: str = None
|
||||
pk: str = None
|
||||
provider: str = None
|
||||
|
||||
@staticmethod
|
||||
def parse(stamp: str):
|
||||
b = base64.urlsafe_b64decode(stamp.removeprefix("sdns://") + "==")
|
||||
|
||||
# 0x01
|
||||
i = 0
|
||||
if b[i] != 0x01:
|
||||
raise ValueError()
|
||||
i = i + 1
|
||||
|
||||
parsed = DNSCrypt()
|
||||
|
||||
# props
|
||||
props = b[i]
|
||||
parsed.dnssec = not not ((props >> 0) & 1)
|
||||
parsed.nolog = not not ((props >> 1) & 1)
|
||||
parsed.nofilter = not not ((props >> 2) & 1)
|
||||
i = i + 8
|
||||
|
||||
# LP(addr [:port])
|
||||
addr_len = b[i]
|
||||
i = i + 1
|
||||
parsed.addr = b[i:i + addr_len].decode("utf-8")
|
||||
i = i + addr_len
|
||||
|
||||
# LP(pk)
|
||||
pk_len = b[i]
|
||||
i = i + 1
|
||||
if pk_len != 32:
|
||||
raise ValueError()
|
||||
hpk = b[i:i + pk_len].hex().upper()
|
||||
hpks = []
|
||||
for j in range(0, 16):
|
||||
hpks.append(hpk[j * 4: j * 4 + 4])
|
||||
parsed.pk = ":".join(hpks)
|
||||
i = i + pk_len
|
||||
|
||||
# LP(providerName)
|
||||
provider_len = b[i]
|
||||
i = i + 1
|
||||
parsed.provider = b[i:i + provider_len].decode("utf-8")
|
||||
i = i + provider_len
|
||||
|
||||
return parsed
|
||||
|
||||
|
||||
class DNSoverHTTPS:
|
||||
dnssec: bool = False
|
||||
nolog: bool = False
|
||||
nofilter: bool = False
|
||||
addr: str = None
|
||||
hashs: list[str] = []
|
||||
hostname: str = None
|
||||
path: str = None
|
||||
bootstrap_ipi: list[str] = []
|
||||
|
||||
def parse(stamp: str):
|
||||
b = base64.urlsafe_b64decode(stamp.removeprefix("sdns://") + "==")
|
||||
|
||||
# 0x02
|
||||
i = 0
|
||||
if b[i] != 0x02:
|
||||
raise ValueError()
|
||||
i = i + 1
|
||||
|
||||
parsed = DNSoverHTTPS()
|
||||
|
||||
# props
|
||||
props = b[i]
|
||||
parsed.dnssec = not not ((props >> 0) & 1)
|
||||
parsed.nolog = not not ((props >> 1) & 1)
|
||||
parsed.nofilter = not not ((props >> 2) & 1)
|
||||
i = i + 8
|
||||
|
||||
# LP(addr)
|
||||
addr_len = b[i]
|
||||
i = i + 1
|
||||
parsed.addr = b[i:i + addr_len].decode("utf-8")
|
||||
i = i + addr_len
|
||||
|
||||
# VLP(hash1, hash2, ...hashn)
|
||||
last_element = False
|
||||
while True:
|
||||
if b[i] & 0x80 == 0:
|
||||
last_element = True
|
||||
hashx_len = b[i]
|
||||
else:
|
||||
hashx_len = b[i] ^ 0x80
|
||||
if hashx_len != 0 and hashx_len != 32:
|
||||
raise ValueError()
|
||||
i = i + 1
|
||||
if hashx_len > 0:
|
||||
hashx = b[i:i + hashx_len].hex()
|
||||
parsed.hashs.append(hashx)
|
||||
i = i + hashx_len
|
||||
if last_element:
|
||||
break
|
||||
|
||||
# LP(hostname [:port])
|
||||
hostname_len = b[i]
|
||||
i = i + 1
|
||||
parsed.hostname = b[i:i + hostname_len].decode("utf-8")
|
||||
i = i + hostname_len
|
||||
|
||||
# LP(path)
|
||||
path_len = b[i]
|
||||
i = i + 1
|
||||
parsed.path = b[i:i + path_len].decode("utf-8")
|
||||
i = i + path_len
|
||||
|
||||
# VLP(bootstrap_ip1, bootstrap_ip2, ...bootstrap_ipn) (optional)
|
||||
if i < len(b):
|
||||
last_element = False
|
||||
while True:
|
||||
if b[i] & 0x80 == 0:
|
||||
last_element = True
|
||||
bootstrap_ipx_len = b[i]
|
||||
else:
|
||||
bootstrap_ipx_len = b[i] ^ 0x80
|
||||
i = i + 1
|
||||
if bootstrap_ipx_len > 0:
|
||||
bootstrap_ipx = b[i:i + bootstrap_ipx_len].decode("utf-8")
|
||||
parsed.bootstrap_ipi.append(bootstrap_ipx)
|
||||
i = i + bootstrap_ipx_len
|
||||
if last_element:
|
||||
break
|
||||
|
||||
return parsed
|
||||
|
||||
|
||||
class DNSoverTLS:
|
||||
dnssec: bool = False
|
||||
nolog: bool = False
|
||||
nofilter: bool = False
|
||||
addr: str = None
|
||||
hashs: list[str] = []
|
||||
hostname: str = None
|
||||
bootstrap_ipi: list[str] = []
|
||||
|
||||
@staticmethod
|
||||
def parse(stamp: str):
|
||||
b = base64.urlsafe_b64decode(stamp.removeprefix("sdns://") + "==")
|
||||
|
||||
# 0x03
|
||||
i = 0
|
||||
if b[i] != 0x03:
|
||||
raise ValueError()
|
||||
i = i + 1
|
||||
|
||||
parsed = DNSoverTLS()
|
||||
|
||||
# props
|
||||
props = b[i]
|
||||
parsed.dnssec = not not ((props >> 0) & 1)
|
||||
parsed.nolog = not not ((props >> 1) & 1)
|
||||
parsed.nofilter = not not ((props >> 2) & 1)
|
||||
i = i + 8
|
||||
|
||||
# LP(addr)
|
||||
addr_len = b[i]
|
||||
i = i + 1
|
||||
parsed.addr = b[i:i + addr_len].decode("utf-8")
|
||||
i = i + addr_len
|
||||
|
||||
# VLP(hash1, hash2, ...hashn)
|
||||
last_element = False
|
||||
while True:
|
||||
if b[i] & 0x80 == 0:
|
||||
last_element = True
|
||||
hashx_len = b[i]
|
||||
else:
|
||||
hashx_len = b[i] ^ 0x80
|
||||
if hashx_len != 0 and hashx_len != 32:
|
||||
raise ValueError()
|
||||
i = i + 1
|
||||
if hashx_len > 0:
|
||||
hashx = b[i:i + hashx_len].hex()
|
||||
parsed.hashs.append(hashx)
|
||||
i = i + hashx_len
|
||||
if last_element:
|
||||
break
|
||||
|
||||
# LP(hostname[:port])
|
||||
hostname_len = b[i]
|
||||
i = i + 1
|
||||
parsed.hostname = b[i:i + hostname_len].decode("utf-8")
|
||||
i = i + hostname_len
|
||||
|
||||
# VLP(bootstrap_ip1, bootstrap_ip2, ...bootstrap_ipn) (optional)
|
||||
if i < len(b):
|
||||
last_element = False
|
||||
while True:
|
||||
if b[i] & 0x80 == 0:
|
||||
last_element = True
|
||||
bootstrap_ipx_len = b[i]
|
||||
else:
|
||||
bootstrap_ipx_len = b[i] ^ 0x80
|
||||
i = i + 1
|
||||
if bootstrap_ipx_len > 0:
|
||||
bootstrap_ipx = b[i:i + bootstrap_ipx_len].decode("utf-8")
|
||||
parsed.bootstrap_ipi.append(bootstrap_ipx)
|
||||
i = i + bootstrap_ipx_len
|
||||
if last_element:
|
||||
break
|
||||
|
||||
return parsed
|
||||
|
||||
|
||||
class DNSoverQUIC:
|
||||
dnssec: bool = False
|
||||
nolog: bool = False
|
||||
nofilter: bool = False
|
||||
addr: str = None
|
||||
hashs: list[str] = []
|
||||
hostname: str = None
|
||||
bootstrap_ipi: list[str] = []
|
||||
|
||||
@staticmethod
|
||||
def parse(stamp: str):
|
||||
b = base64.urlsafe_b64decode(stamp.removeprefix("sdns://") + "==")
|
||||
|
||||
# 0x04
|
||||
i = 0
|
||||
if b[i] != 0x04:
|
||||
raise ValueError()
|
||||
i = i + 1
|
||||
|
||||
parsed = DNSoverQUIC()
|
||||
|
||||
# props
|
||||
props = b[i]
|
||||
parsed.dnssec = not not ((props >> 0) & 1)
|
||||
parsed.nolog = not not ((props >> 1) & 1)
|
||||
parsed.nofilter = not not ((props >> 2) & 1)
|
||||
i = i + 8
|
||||
|
||||
# LP(addr)
|
||||
addr_len = b[i]
|
||||
i = i + 1
|
||||
parsed.addr = b[i:i + addr_len].decode("utf-8")
|
||||
i = i + addr_len
|
||||
|
||||
# VLP(hash1, hash2, ...hashn)
|
||||
last_element = False
|
||||
while True:
|
||||
if b[i] & 0x80 == 0:
|
||||
last_element = True
|
||||
hashx_len = b[i]
|
||||
else:
|
||||
hashx_len = b[i] ^ 0x80
|
||||
if hashx_len != 0 and hashx_len != 32:
|
||||
raise ValueError()
|
||||
i = i + 1
|
||||
if hashx_len > 0:
|
||||
hashx = b[i:i + hashx_len].hex()
|
||||
parsed.hashs.append(hashx)
|
||||
i = i + hashx_len
|
||||
if last_element:
|
||||
break
|
||||
|
||||
# LP(hostname[:port])
|
||||
hostname_len = b[i]
|
||||
i = i + 1
|
||||
parsed.hostname = b[i:i + hostname_len].decode("utf-8")
|
||||
i = i + hostname_len
|
||||
|
||||
# VLP(bootstrap_ip1, bootstrap_ip2, ...bootstrap_ipn) (optional)
|
||||
if i < len(b):
|
||||
last_element = False
|
||||
while True:
|
||||
if b[i] & 0x80 == 0:
|
||||
last_element = True
|
||||
bootstrap_ipx_len = b[i]
|
||||
else:
|
||||
bootstrap_ipx_len = b[i] ^ 0x80
|
||||
i = i + 1
|
||||
if bootstrap_ipx_len > 0:
|
||||
bootstrap_ipx = b[i:i + bootstrap_ipx_len].decode("utf-8")
|
||||
parsed.bootstrap_ipi.append(bootstrap_ipx)
|
||||
i = i + bootstrap_ipx_len
|
||||
if last_element:
|
||||
break
|
||||
|
||||
return parsed
|
||||
|
||||
|
||||
class ObliviousDoH:
|
||||
dnssec: bool = False
|
||||
nolog: bool = False
|
||||
nofilter: bool = False
|
||||
hostname: str = None
|
||||
path: str = None
|
||||
|
||||
@staticmethod
|
||||
def parse(stamp: str):
|
||||
b = base64.urlsafe_b64decode(stamp.removeprefix("sdns://") + "==")
|
||||
|
||||
# 0x05
|
||||
i = 0
|
||||
if b[i] != 0x05:
|
||||
raise ValueError()
|
||||
i = i + 1
|
||||
|
||||
parsed = ObliviousDoH()
|
||||
|
||||
# props
|
||||
props = b[i]
|
||||
parsed.dnssec = not not ((props >> 0) & 1)
|
||||
parsed.nolog = not not ((props >> 1) & 1)
|
||||
parsed.nofilter = not not ((props >> 2) & 1)
|
||||
i = i + 8
|
||||
|
||||
# LP(hostname [:port])
|
||||
hostname_len = b[i]
|
||||
i = i + 1
|
||||
parsed.hostname = b[i:i + hostname_len].decode("utf-8")
|
||||
i = i + hostname_len
|
||||
|
||||
# LP(path)
|
||||
path_len = b[i]
|
||||
i = i + 1
|
||||
parsed.path = b[i:i + path_len].decode("utf-8")
|
||||
i = i + path_len
|
||||
|
||||
return parsed
|
||||
|
||||
|
||||
class DNSCryptRelay:
|
||||
addr: str = None
|
||||
|
||||
@staticmethod
|
||||
def parse(stamp):
|
||||
b = base64.urlsafe_b64decode(stamp.removeprefix("sdns://") + "==")
|
||||
|
||||
# 0x81
|
||||
i = 0
|
||||
if b[i] != 0x81:
|
||||
raise ValueError()
|
||||
i = i + 1
|
||||
|
||||
parsed = DNSCryptRelay()
|
||||
|
||||
# LP(addr)
|
||||
addr_len = b[i]
|
||||
i = i + 1
|
||||
parsed.addr = b[i:i + addr_len].decode("utf-8")
|
||||
i = i + addr_len
|
||||
|
||||
return parsed
|
||||
|
||||
|
||||
class ObliviousDoHrelay:
|
||||
dnssec: bool = False
|
||||
nolog: bool = False
|
||||
nofilter: bool = False
|
||||
addr: str = None
|
||||
hashs: list[str] = []
|
||||
hostname: str = None
|
||||
path: str = None
|
||||
bootstrap_ipi: list[str] = []
|
||||
|
||||
@staticmethod
|
||||
def parse(stamp: str):
|
||||
b = base64.urlsafe_b64decode(stamp.removeprefix("sdns://") + "==")
|
||||
|
||||
# 0x85
|
||||
i = 0
|
||||
if b[i] != 0x85:
|
||||
raise ValueError()
|
||||
i = i + 1
|
||||
|
||||
parsed = ObliviousDoHrelay()
|
||||
|
||||
# props
|
||||
props = b[i]
|
||||
parsed.dnssec = not not ((props >> 0) & 1)
|
||||
parsed.nolog = not not ((props >> 1) & 1)
|
||||
parsed.nofilter = not not ((props >> 2) & 1)
|
||||
i = i + 8
|
||||
|
||||
# LP(addr)
|
||||
addr_len = b[i]
|
||||
i = i + 1
|
||||
parsed.addr = b[i:i + addr_len].decode("utf-8")
|
||||
i = i + addr_len
|
||||
|
||||
# VLP(hash1, hash2, ...hashn)
|
||||
last_element = False
|
||||
while True:
|
||||
if b[i] & 0x80 == 0:
|
||||
last_element = True
|
||||
hashx_len = b[i]
|
||||
else:
|
||||
hashx_len = b[i] ^ 0x80
|
||||
if hashx_len != 0 and hashx_len != 32:
|
||||
raise ValueError()
|
||||
i = i + 1
|
||||
if hashx_len > 0:
|
||||
hashx = b[i:i + hashx_len].hex()
|
||||
parsed.hashs.append(hashx)
|
||||
i = i + hashx_len
|
||||
if last_element:
|
||||
break
|
||||
|
||||
# LP(hostname [:port])
|
||||
hostname_len = b[i]
|
||||
i = i + 1
|
||||
parsed.hostname = b[i:i + hostname_len].decode("utf-8")
|
||||
i = i + hostname_len
|
||||
|
||||
# LP(path)
|
||||
path_len = b[i]
|
||||
i = i + 1
|
||||
parsed.path = b[i:i + path_len].decode("utf-8")
|
||||
i = i + path_len
|
||||
|
||||
# VLP(bootstrap_ip1, bootstrap_ip2, ...bootstrap_ipn) (optional)
|
||||
if i < len(b):
|
||||
last_element = False
|
||||
while True:
|
||||
if b[i] & 0x80 == 0:
|
||||
last_element = True
|
||||
bootstrap_ipx_len = b[i]
|
||||
else:
|
||||
bootstrap_ipx_len = b[i] ^ 0x80
|
||||
i = i + 1
|
||||
if bootstrap_ipx_len > 0:
|
||||
bootstrap_ipx = b[i:i + bootstrap_ipx_len].decode("utf-8")
|
||||
parsed.bootstrap_ipi.append(bootstrap_ipx)
|
||||
i = i + bootstrap_ipx_len
|
||||
if last_element:
|
||||
break
|
||||
|
||||
return parsed
|
||||
|
||||
|
||||
class PlainDNS:
|
||||
dnssec: bool = False
|
||||
nolog: bool = False
|
||||
nofilter: bool = False
|
||||
addr: str = None
|
||||
|
||||
@staticmethod
|
||||
def parse(stamp: str):
|
||||
b = base64.urlsafe_b64decode(stamp.removeprefix("sdns://") + "==")
|
||||
|
||||
# 0x00
|
||||
i = 0
|
||||
if b[i] != 0x00:
|
||||
raise ValueError()
|
||||
i = i + 1
|
||||
|
||||
parsed = PlainDNS()
|
||||
|
||||
# props
|
||||
props = b[i]
|
||||
parsed.dnssec = not not ((props >> 0) & 1)
|
||||
parsed.nolog = not not ((props >> 1) & 1)
|
||||
parsed.nofilter = not not ((props >> 2) & 1)
|
||||
i = i + 8
|
||||
|
||||
# LP(addr)
|
||||
addr_len = b[i]
|
||||
i = i + 1
|
||||
parsed.addr = b[i:i + addr_len].decode("utf-8")
|
||||
i = i + addr_len
|
||||
|
||||
return parsed
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# DNSCrypt
|
||||
t = parse(
|
||||
"sdns://AQMAAAAAAAAAETk0LjE0MC4xNC4xNTo1NDQzILgxXdexS27jIKRw3C7Wsao5jMnlhvhdRUXWuMm1AFq6ITIuZG5zY3J5cHQuZmFtaWx5Lm5zMS5hZGd1YXJkLmNvbQ")
|
||||
print(t)
|
||||
|
||||
# DoH
|
||||
t = parse("sdns://AgcAAAAAAAAADTIxNy4xNjkuMjAuMjIADWRucy5hYS5uZXQudWsKL2Rucy1xdWVyeQ")
|
||||
t = parse(
|
||||
"sdns://AgMAAAAAAAAADjE2My40Ny4xMTcuMTc2oMwQYNOcgym2K2-8fQ1t-TCYabmB5-Y5LVzY-kCPTYDmoPf1ryiAHod9ffOivij-FJ8ydKftKfE2_VA845jLqAsNoLNeBZUM-9gln5N1uhAYcLjDxMDsWlKXV-YxZ-neJqnooEROvWe7g_iAezkh6TiskXi4gr1QqtsRIx8ETPXwjffOoOZEumlj4zX-dly5l2sSsQ61QpS0JHd2TMs6OsyjrLL8ICquP7e_BeTIHEGU3KRFEdT5rzBHhuwa5yGECc9ioINVEGFkbC5hZGZpbHRlci5uZXQKL2Rucy1xdWVyeQ")
|
||||
print(t)
|
||||
|
||||
# DoT
|
||||
t = parse("sdns://AwcAAAAAAAAABzEuMS4xLjEAD29uZS5vbmUub25lLm9uZQ")
|
||||
print(t)
|
||||
|
||||
# DoQ
|
||||
t = parse("sdns://BAcAAAAAAAAABzEuMS4xLjEAD29uZS5vbmUub25lLm9uZQ")
|
||||
print(t)
|
||||
|
||||
# oDoH
|
||||
t = parse("sdns://BQcAAAAAAAAADWpwLnRpYXJhcC5vcmcFL29kb2g")
|
||||
print(t)
|
||||
|
||||
# DNSCrypt relay
|
||||
t = parse("sdns://gQ04Ni4xMDYuNzQuMjE5")
|
||||
print(t)
|
||||
|
||||
# oDoH relay
|
||||
t = parse("sdns://hQcAAAAAAAAADDg5LjM4LjEzMS4zOAAYb2RvaC1ubC5hbGVrYmVyZy5uZXQ6NDQzBi9wcm94eQ")
|
||||
print(t)
|
||||
|
||||
# Plain DNS
|
||||
t = parse("sdns://AAUAAAAAAAAABzEuMS4xLjE")
|
||||
print(t)
|
||||
Loading…
Add table
Add a link
Reference in a new issue