From 25bd19be294cc846c3f6e9f2b75ffb35b2f85783 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Thu, 21 Oct 2021 17:53:12 +0200 Subject: [PATCH 2/3] utils/evaluate: add a dnsbl() dict like (#58055) To check an IPv4 address is inside a DNSxL, use the following expression in your condition: remote_addr in dnsbl('dnsbl.example.com') --- src/authentic2/utils/evaluate.py | 62 +++++++++++++++++++++++++++++++- tests/test_utils_evaluate.py | 27 ++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/src/authentic2/utils/evaluate.py b/src/authentic2/utils/evaluate.py index 065667aa..3f448da0 100644 --- a/src/authentic2/utils/evaluate.py +++ b/src/authentic2/utils/evaluate.py @@ -15,18 +15,24 @@ # along with this program. If not, see . import ast +import logging +import re import sys +import dns.exception +import dns.resolver from django.core.exceptions import ValidationError +from django.core.validators import validate_ipv4_address try: from functools import lru_cache except ImportError: from django.utils.lru_cache import lru_cache - from django.utils.translation import ugettext as _ +logger = logging.getLogger(__name__) + class HTTPHeaders: def __init__(self, request): @@ -67,6 +73,60 @@ class ExpressionError(ValidationError): self.text = Unparse().visit(node) +def is_valid_hostname(hostname): + if hostname[-1] == ".": + # strip exactly one dot from the right, if present + hostname = hostname[:-1] + if len(hostname) > 253: + return False + + labels = hostname.split(".") + + # the TLD must be not all-numeric + if re.match(r"[0-9]+$", labels[-1]): + return False + + allowed = re.compile(r"(?!-)[a-z0-9-]{1,63}(?