""" Security utilities for Funguy Bot plugins. """ import ipaddress import socket import logging logger = logging.getLogger("security_utils") # Networks considered unsafe for outbound connections PRIVATE_RANGES = [ ipaddress.ip_network('10.0.0.0/8'), ipaddress.ip_network('172.16.0.0/12'), ipaddress.ip_network('192.168.0.0/16'), ipaddress.ip_network('127.0.0.0/8'), ipaddress.ip_network('169.254.0.0/16'), # link‑local ipaddress.ip_network('0.0.0.0/8'), # "this" network ipaddress.ip_network('::1/128'), # IPv6 loopback ipaddress.ip_network('fc00::/7'), # unique local ipaddress.ip_network('fe80::/10'), # link‑local ipaddress.ip_network('::/128'), # unspecified ] def is_public_destination(target: str) -> bool: """ Returns True if `target` (hostname or IP) does NOT resolve to any private, loopback, or link‑local address. """ try: # Try parsing as an IP address first addr = ipaddress.ip_address(target) if any(addr in net for net in PRIVATE_RANGES): return False return True except ValueError: pass # Resolve hostname to IPs try: addrinfo = socket.getaddrinfo(target, None) for _, _, _, _, sockaddr in addrinfo: ip = sockaddr[0] addr = ipaddress.ip_address(ip) if any(addr in net for net in PRIVATE_RANGES): return False return True except Exception as e: logger.warning(f"Cannot resolve {target}: {e}") return False # --------------------------------------------------------------------------- # No‑op command handler – prevents bot crash because funguy.py calls # handle_command() on every module in the plugins directory. # --------------------------------------------------------------------------- async def handle_command(room, message, bot, prefix, config): """This module is not a command plugin; ignore all messages.""" pass