Commits

George Notaras committed fdbbbf0

Added ``validate_hostname`` utility function.

Comments (0)

Files changed (3)

docs/configuration.rst

 ``PDNS_IS_SLAVE``
     Can be ``True`` or ``False``. Currently has not effect.
 
+``PDNS_ALLOW_WILDCARD_NAMES``
+    Can be ``True`` or ``False``. Turns wildcard support on and off respectively.
+    This setting affects input validation in the ``name`` and ``content`` fields
+    of those resource records that support wildcards.
+
 .. _supports: http://doc.powerdns.com/types.html
 
 

src/powerdns_manager/settings.py

 ]
 PDNS_ENABLED_RR_TYPES = getattr(settings, 'PDNS_ENABLED_RR_TYPES', _DEFAULT_PDNS_ENABLED_RR_TYPES)
 
+PDNS_ALLOW_WILDCARD_NAMES = getattr(settings, 'PDNS_ALLOW_WILDCARD_NAMES', True)
+

src/powerdns_manager/utils.py

 import base64
 import string
 import StringIO
+import re
 
 import dns.zone
 import dns.query
 
 from django.db.models.loading import cache
 from django.utils.crypto import get_random_string
+from django.core.exceptions import ValidationError
+from django.core.validators import validate_ipv46_address
+
+from powerdns_manager import settings
+
+
+
+def validate_hostname(hostname,
+        reject_ip=True, supports_cidr_notation=False, supports_wildcard=False):
+    """Validates that ``hostname`` does not contain illegal characters.
+    
+    In case ``hostname`` is not validated a ``ValidationError`` is raised.
+    
+    By default, the valid hostname characters are:
+    
+        A-Za-z0-9._-
+    
+    The pattern above allows the hostname to be an IP address (IPv4). By default,
+    if hostname validates as an IP address, it is rejected. To allow IP addresses
+    as hostnames, set ``reject_ip`` to False when calling this validator.
+    
+    If ``supports_cidr_notation`` is True, then ``/`` is allowed too.
+    
+    If ``supports_wildcard`` is True, then ``*`` is allowed too, unless
+    the ``PDNS_ALLOW_WILDCARD_NAMES`` has been set to False (default is True).
+    
+    """
+    if not hostname:
+        return
+    
+    if reject_ip:
+        # Check if hostname is an IP and reject it if it is.
+        try:
+            validate_ipv46_address(hostname)
+        except ValidationError:
+            pass
+        else:
+            raise ValidationError('IP addresses cannot be used as hostnames')
+    
+    valid_sequence = 'A-Za-z0-9._\-'    # dash needs to be escaped
+    
+    if supports_cidr_notation:
+        valid_sequence = '%s/' % valid_sequence
+        
+    if supports_wildcard:
+        if settings.PDNS_ALLOW_WILDCARD_NAMES:
+            valid_sequence = '%s*' % valid_sequence
+    
+    if not re.match('^[%s]+$' % valid_sequence, hostname):
+        raise ValidationError('The hostname contains illegal characters')
 
 
 def generate_serial(serial_old=None):
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.