diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2020-06-19 17:19:59 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2020-06-19 17:19:59 +0100 |
commit | f99d7e2a44e0ebe6372a7322329c2813119d8215 (patch) | |
tree | 91a3af521514811badb0b557bf1285f0c79efcc3 /rules | |
parent | a245f4f38ac1000ee070cc7bc611e862c46df4d2 (diff) | |
download | rspamd-f99d7e2a44e0ebe6372a7322329c2813119d8215.tar.gz rspamd-f99d7e2a44e0ebe6372a7322329c2813119d8215.zip |
[Rules] Refactor bleach32 addresses handling
Diffstat (limited to 'rules')
-rw-r--r-- | rules/bitcoin.lua | 63 |
1 files changed, 32 insertions, 31 deletions
diff --git a/rules/bitcoin.lua b/rules/bitcoin.lua index 86380badf..d9c94fdf1 100644 --- a/rules/bitcoin.lua +++ b/rules/bitcoin.lua @@ -96,44 +96,45 @@ local function verify_beach32_cksum(hrp, elts) return polymod(hrpExpand(hrp), elts) == 1 end -local function is_segwit_bech32_address(word) - local has_upper, has_lower, has_invalid - - if #word > 90 then return false end +local function gen_bleach32_table(input) + local d = {} + local i = 1 + local res = true + local charset = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l' - fun.each(function(ch) - if ch < 33 or ch > 126 then - has_invalid = true - elseif ch >= 97 and ch <= 122 then - has_lower = true - elseif ch >= 65 and ch <= 90 then - has_upper = true; + fun.each(function(byte) + if res then + local pos = charset:find(byte) + if not pos then + res = false + else + d[i] = pos - 1 + i = i + 1 + end end - end, fun.map(string.byte, fun.iter(word))) + end, fun.iter(input)) - if has_invalid or (has_lower and has_upper) then - return false - end + return res and d or nil +end - word = word:lower() - local last_one_pos = word:find('1[^1]*$') - if not last_one_pos or (last_one_pos < 1 or last_one_pos + 7 > #word) then - return false - end - local hrp = word:sub(1, last_one_pos - 1) - local d = {} - local charset = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l'; - for i=last_one_pos + 1,#word do - local c = word:sub(i, i) - local pos = charset:find(c) +local function is_segwit_bech32_address(word) + local prefix = word:sub(1, 3) - if not pos then + if prefix == 'bc1' or prefix.sub(1, 1) == '1' or prefix.sub(1, 1) == '3' then + -- Strip beach32 prefix in bitcoin + word = word:lower() + local last_one_pos = word:find('1[^1]*$') + if not last_one_pos or (last_one_pos < 1 or last_one_pos + 7 > #word) then return false end - d[#d + 1] = pos - 1 - end + local hrp = word:sub(1, last_one_pos - 1) + local addr = word:sub(last_one_pos + 1, -1) + local decoded = gen_bleach32_table(addr) - return verify_beach32_cksum(hrp, d) + if decoded then + return verify_beach32_cksum(hrp, decoded) + end + end end @@ -144,7 +145,7 @@ rspamd_config:register_symbol{ local rspamd_re = require "rspamd_regexp" local btc_wallet_re = rspamd_re.create_cached('^[13LM][1-9A-Za-z]{25,34}$') - local segwit_wallet_re = rspamd_re.create_cached('^[b][c]1[qpzry9x8gf2tvdw0s3jn54khce6mua7l]{14,74}$', 'i') + local segwit_wallet_re = rspamd_re.create_cached('^(?:bc1|[13])?[qpzry9x8gf2tvdw0s3jn54khce6mua7l]{14,}$', 'i') local words_matched = {} local segwit_words_matched = {} local valid_wallets = {} |