FireBot/config.py

246 lines
8 KiB
Python
Raw Normal View History

2023-11-06 00:51:42 +00:00
#!/usr/bin/python3
2023-11-07 12:51:55 +00:00
from os import environ as env
2023-11-24 19:09:46 +00:00
from dotenv import load_dotenv # type: ignore
2023-11-09 03:20:50 +00:00
import re, codecs
2024-05-19 03:23:36 +00:00
from typing import Optional, Any, Union
2024-03-06 18:33:04 +00:00
import bare, pylast
2024-05-23 18:12:46 +00:00
from pydnsbl import DNSBLIpChecker, DNSBLDomainChecker, providers as BL
2024-05-18 22:38:49 +00:00
2024-05-24 17:06:41 +00:00
class droneBL(BL.Provider):
def process_response(self, response):
reasons = set()
for result in response:
reason = result.host
2024-05-24 17:06:41 +00:00
if reason in ["127.0.0.3"]:
reasons.add("IRC Spambot")
elif reason in ["127.0.0.19"]:
reasons.add("Abused VPN")
elif reason in ["127.0.0.9", "127.0.0.8"]:
reasons.add("Open Proxy")
elif reason in ["127.0.0.13"]:
reasons.add("Automated Attacks")
else:
2024-05-24 17:06:41 +00:00
print("Unknown dnsbl reason: " + reason, flush=True)
reasons.add("unknown")
return reasons
2024-05-24 17:06:41 +00:00
providers = BL.BASE_PROVIDERS + [droneBL("dnsbl.dronebl.org")]
2024-05-23 18:12:46 +00:00
ipbl = DNSBLIpChecker(providers=providers)
hsbl = DNSBLDomainChecker(providers=providers)
2023-11-08 02:30:35 +00:00
hardbl = ["146.70.59.36"]
2023-11-07 12:51:55 +00:00
load_dotenv()
2024-09-17 17:16:25 +00:00
__version__ = "v3.0.22"
2024-04-07 05:38:49 +00:00
npbase: str = (
"\[\x0303last\.fm\x03\] [A-Za-z0-9_[\]{}\\|\-^]{1,$MAX} (is listening|last listened) to: \x02.+ - .*\x02( \([0-9]+ plays\)( \[.*\])?)?" # pyright: ignore [reportInvalidStringEscapeSequence]
)
2023-11-09 03:41:07 +00:00
su = "^(su|sudo|(su .*|sudo .*))$"
2023-11-09 03:20:50 +00:00
servers: dict[str, dict[str, Any]] = {
2023-11-06 00:51:42 +00:00
"ircnow": {
2024-04-07 04:45:38 +00:00
"address": "127.0.0.1",
2023-11-06 00:51:42 +00:00
"port": 6601,
"interval": 200,
"pass": env["ircnow_pass"],
"channels": {"#random": 0, "#dice": 0, "#offtopic": 0, "#main/replirc": 0},
"ignores": ["#main/replirc"],
2023-11-15 04:39:02 +00:00
"hosts": ["9pfs.repl.co"],
2024-05-24 17:06:41 +00:00
"dnsblMode": "kickban",
2023-11-06 00:51:42 +00:00
},
"efnet": {
"address": "irc.underworld.no",
2023-11-06 00:51:42 +00:00
"channels": {"#random": 0, "#dice": 0},
"hosts": ["154.sub-174-251-241.myvzw.com"],
"threads": ["pingMon"],
2024-05-18 22:38:49 +00:00
"dnsblMode": "kickban",
2023-11-06 00:51:42 +00:00
},
"replirc": {
2024-04-07 04:45:38 +00:00
"address": "127.0.0.1",
2023-11-06 00:51:42 +00:00
"pass": env["replirc_pass"],
2024-04-07 05:38:49 +00:00
"channels": {
"#random": 0,
"#dice": 0,
"#main": 0,
"#bots": 0,
"#firebot": 0,
"#sshchat": 0,
"#firemc": 0,
"#fp-radio": 0,
2024-05-10 01:01:05 +00:00
"#fp-radio-debug": 0,
"#hardfork": 0,
2024-05-23 18:12:46 +00:00
"#opers": 0,
2024-04-07 05:38:49 +00:00
},
2024-03-06 18:33:04 +00:00
"ignores": ["#fp-radio"],
2023-11-15 05:06:49 +00:00
"admins": ["h-tl"],
2023-11-15 04:38:41 +00:00
"hosts": ["owner.firepi"],
2024-05-01 01:52:16 +00:00
"threads": ["radio"],
2024-05-11 00:43:14 +00:00
"autoMethod": "MARKOV",
2024-05-18 22:38:49 +00:00
"dnsblMode": "akill",
2023-11-06 00:51:42 +00:00
},
2023-11-13 22:27:20 +00:00
"backupbox": {
2024-04-07 04:45:38 +00:00
"address": "127.0.0.1",
2024-03-06 18:33:04 +00:00
"port": 6607,
"channels": {"#default": 0, "#botrebellion": 0, "#main/replirc": 0},
"ignores": ["#main/replirc"],
2024-04-07 05:38:49 +00:00
"hosts": [
"172.20.171.225",
"169.254.253.107",
"2600-6c5a-637f-1a85-0000-0000-0000-6667.inf6.spectrum.com",
],
2024-04-20 07:48:43 +00:00
"onIdntCmds": ["OPER e e"],
2024-05-18 22:38:49 +00:00
"dnsbl-mode": "gline",
},
"twitch": {
"nick": "fireschatbot",
"address": "irc.chat.twitch.tv",
"serverPass": env["twitch_pass"],
"channels": {
"#firepup650": 0,
},
"admins": ["firepup650"],
2024-05-12 03:30:31 +00:00
"prefix": "!",
2023-11-15 05:26:02 +00:00
},
2023-11-06 00:51:42 +00:00
}
admin_hosts: list[str] = ["firepup.firepi", "47.221.98.52"]
2023-11-07 13:25:53 +00:00
ESCAPE_SEQUENCE_RE = re.compile(
r"""
( \\U........ # 8-digit hex escapes
| \\u.... # 4-digit hex escapes
| \\x.. # 2-digit hex escapes
| \\[0-7]{1,3} # Octal escapes
| \\N\{[^}]+\} # Unicode characters by name
| \\[\\'"abfnrtv] # Single-character escapes
)""",
re.UNICODE | re.VERBOSE,
)
2023-11-07 13:53:14 +00:00
prefix = "."
2024-03-06 18:33:04 +00:00
lastfmLink = pylast.LastFMNetwork(env["FM_KEY"], env["FM_SECRET"])
npallowed: list[str] = ["FireBitBot"]
2023-11-08 02:30:35 +00:00
2024-04-07 05:38:49 +00:00
2023-11-07 13:53:14 +00:00
def decode_escapes(s: str) -> str:
def decode_match(match):
return codecs.decode(match.group(0), "unicode-escape")
return ESCAPE_SEQUENCE_RE.sub(decode_match, s)
2023-11-09 03:20:50 +00:00
def cmdFind(message: str, find: list, usePrefix: bool = True) -> bool:
cmd = message.split(" ")
if not cmd:
return False
if usePrefix:
for match in find:
sMatch = (prefix + match).split(" ")
try:
if all(cmd[i] == sMatch[i] for i in range(len(sMatch))):
return True
except IndexError:
...
else:
for match in find:
sMatch = match.split(" ")
try:
if all(cmd[i] == sMatch[i] for i in range(len(sMatch))):
return True
except IndexError:
...
return False
2023-11-09 03:20:50 +00:00
def mfind(message: str, find: list, usePrefix: bool = True) -> bool:
if usePrefix:
return any(message[: len(match) + 1] == prefix + match for match in find)
else:
return any(message[: len(match)] == match for match in find)
2023-11-24 07:15:33 +00:00
2023-12-05 04:50:03 +00:00
def sub(
message: str, bot: bare.bot, chan: Optional[str] = "", name: Optional[str] = ""
) -> str:
2023-11-24 07:15:33 +00:00
result = message.replace("$BOTNICK", bot.nick).replace("$NICK", bot.nick)
2023-12-05 04:50:03 +00:00
result = result.replace("$NICKLEN", str(bot.nicklen)).replace(
"$MAX", str(bot.nicklen)
)
2023-11-24 07:15:33 +00:00
if chan:
result = result.replace("$CHANNEL", chan).replace("$CHAN", chan)
if name:
result = result.replace("$SENDER", name).replace("$NAME", name)
return result
2024-05-18 22:38:49 +00:00
2024-05-23 18:12:46 +00:00
def dnsbl(hostname: str) -> tuple[str, dict[str, list[str]]]:
2024-05-19 03:23:36 +00:00
hosts = []
2024-05-23 18:12:46 +00:00
hstDT = {}
2024-05-18 22:38:49 +00:00
try:
2024-05-19 03:23:36 +00:00
hstDT = ipbl.check(hostname).detected_by
2024-05-20 19:59:55 +00:00
except ValueError: # It's not an IP
try:
hstDT = hsbl.check(hostname).detected_by
except ValueError: # It's also not a hostname
hstDT = {}
if hostname in hardbl:
hstDT["hardcoded"] = ["Known bad host"]
2024-05-19 03:23:36 +00:00
for host in hstDT:
if hstDT[host] != ["unknown"]:
hosts.append(host)
2024-05-18 22:38:49 +00:00
if not hosts:
2024-05-24 17:06:41 +00:00
return "", hstDT
2024-05-18 22:38:49 +00:00
hostStr = None
if len(hosts) >= 3:
2024-05-24 17:06:41 +00:00
hostStr = ", and ".join((", ".join(hosts)).rsplit(", ", 1))
2024-05-18 22:38:49 +00:00
else:
2024-05-24 17:06:41 +00:00
hostStr = " and ".join(hosts)
2024-05-23 18:12:46 +00:00
return hostStr, hstDT
2024-05-24 17:06:41 +00:00
def dnsblHandler(
bot: bare.bot, nick: str, hostname: str, chan: str
) -> tuple[str, dict[str, list[str]]]:
dnsblStatus = "Not enabled"
2024-05-23 18:12:46 +00:00
dnsblResps = {}
if bot.dnsblMode != "none":
2024-06-10 09:20:54 +00:00
dnsblStatus, dnsblResps = (
dnsbl(hostname)
if not hostname in bot.dns
else (bot.dns[hostname]["status"], bot.dns[hostname]["resps"])
)
2024-06-10 09:20:45 +00:00
bot.dns[hostname] = {"status": dnsblStatus, "resps": dnsblResps}
if dnsblStatus:
match bot.dnsblMode:
case "kickban":
2024-05-24 17:06:41 +00:00
bot.sendraw(
f"KICK {chan} {nick} :Sorry, but you're on the {dnsblStatus} blacklist(s)."
2024-05-24 17:06:41 +00:00
)
bot.sendraw(f"MODE {chan} +b *!*@{hostname}")
case "akill":
2024-05-24 17:06:41 +00:00
bot.sendraw(
f"OS AKILL ADD *@{hostname} !P Sorry, but you're on the {dnsblStatus} blacklist(s)."
)
case "kline":
2024-05-24 17:06:41 +00:00
bot.sendraw(
f"KILL {nick} :Sorry, but you're on the {dnsblStatus} blacklist(s)."
)
bot.sendraw(
f"KLINE 524160 *@{hostname} :Sorry, but you're on the {dnsblStatus} blacklist(s)."
)
bot.sendraw(
f"KLINE *@{hostname} :Sorry, but you're on the {dnsblStatus} blacklist(s)."
)
case "gline":
2024-05-24 17:06:41 +00:00
bot.sendraw(
f"KILL {nick} :Sorry, but you're on the {dnsblStatus} blacklist(s)."
)
bot.sendraw(
f"GLINE *@{hostname} 524160 :Sorry, but you're on the {dnsblStatus} blacklist(s)."
)
bot.sendraw(
f"GLINE *@{hostname} :Sorry, but you're on the {dnsblStatus} blacklist(s)."
)
case _:
bot.log(f'Unknown dnsbl Mode "{bot.dnsblMode}"!', "WARN")
2024-05-23 18:12:46 +00:00
return dnsblStatus, dnsblResps