mirror of
https://github.com/certbot/certbot.git
synced 2026-07-28 08:05:31 +02:00
Merge pull request #1814 from joohoi/domaincheck
Check domain list from plugin get_all_names() and remove wildcard, punycode etc. [needs tweak]
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
"""Let's Encrypt user-supplied configuration."""
|
||||
import os
|
||||
import urlparse
|
||||
import re
|
||||
|
||||
import zope.interface
|
||||
|
||||
from letsencrypt import constants
|
||||
from letsencrypt import errors
|
||||
from letsencrypt import interfaces
|
||||
from letsencrypt import le_util
|
||||
|
||||
|
||||
class NamespaceConfig(object):
|
||||
@@ -123,40 +123,5 @@ def check_config_sanity(config):
|
||||
|
||||
# Domain checks
|
||||
if config.namespace.domains is not None:
|
||||
_check_config_domain_sanity(config.namespace.domains)
|
||||
|
||||
|
||||
def _check_config_domain_sanity(domains):
|
||||
"""Helper method for check_config_sanity which validates
|
||||
domain flag values and errors out if the requirements are not met.
|
||||
|
||||
:param domains: List of domains
|
||||
:type domains: `list` of `string`
|
||||
:raises ConfigurationError: for invalid domains and cases where Let's
|
||||
Encrypt currently will not issue certificates
|
||||
|
||||
"""
|
||||
# Check if there's a wildcard domain
|
||||
if any(d.startswith("*.") for d in domains):
|
||||
raise errors.ConfigurationError(
|
||||
"Wildcard domains are not supported")
|
||||
# Punycode
|
||||
if any("xn--" in d for d in domains):
|
||||
raise errors.ConfigurationError(
|
||||
"Punycode domains are not supported")
|
||||
|
||||
# Unicode
|
||||
try:
|
||||
for domain in domains:
|
||||
domain.encode('ascii')
|
||||
except UnicodeDecodeError:
|
||||
raise errors.ConfigurationError(
|
||||
"Internationalized domain names are not supported")
|
||||
|
||||
# FQDN checks from
|
||||
# http://www.mkyong.com/regular-expressions/domain-name-regular-expression-example/
|
||||
# Characters used, domain parts < 63 chars, tld > 1 < 64 chars
|
||||
# first and last char is not "-"
|
||||
fqdn = re.compile("^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,63}$")
|
||||
if any(True for d in domains if not fqdn.match(d)):
|
||||
raise errors.ConfigurationError("Requested domain is not a FQDN")
|
||||
for domain in config.namespace.domains:
|
||||
le_util.check_domain_sanity(domain)
|
||||
|
||||
@@ -4,6 +4,7 @@ import os
|
||||
|
||||
import zope.component
|
||||
|
||||
from letsencrypt import errors
|
||||
from letsencrypt import interfaces
|
||||
from letsencrypt import le_util
|
||||
from letsencrypt.display import util as display_util
|
||||
@@ -186,7 +187,8 @@ def choose_names(installer):
|
||||
logger.debug("No installer, picking names manually")
|
||||
return _choose_names_manually()
|
||||
|
||||
names = list(installer.get_all_names())
|
||||
domains = list(installer.get_all_names())
|
||||
names = get_valid_domains(domains)
|
||||
|
||||
if not names:
|
||||
manual = util(interfaces.IDisplay).yesno(
|
||||
@@ -207,6 +209,22 @@ def choose_names(installer):
|
||||
else:
|
||||
return []
|
||||
|
||||
def get_valid_domains(domains):
|
||||
"""Helper method for choose_names that implements basic checks
|
||||
on domain names
|
||||
|
||||
:param list domains: Domain names to validate
|
||||
:return: List of valid domains
|
||||
:rtype: list
|
||||
"""
|
||||
valid_domains = []
|
||||
for domain in domains:
|
||||
try:
|
||||
le_util.check_domain_sanity(domain)
|
||||
valid_domains.append(domain)
|
||||
except errors.ConfigurationError:
|
||||
continue
|
||||
return valid_domains
|
||||
|
||||
def _filter_names(names):
|
||||
"""Determine which names the user would like to select from a list.
|
||||
|
||||
@@ -280,3 +280,37 @@ def add_deprecated_argument(add_argument, argument_name, nargs):
|
||||
|
||||
add_argument(argument_name, action=ShowWarning,
|
||||
help=argparse.SUPPRESS, nargs=nargs)
|
||||
|
||||
def check_domain_sanity(domain):
|
||||
"""Method which validates domain value and errors out if
|
||||
the requirements are not met.
|
||||
|
||||
:param domain: Domain to check
|
||||
:type domains: `string`
|
||||
:raises ConfigurationError: for invalid domains and cases where Let's
|
||||
Encrypt currently will not issue certificates
|
||||
|
||||
"""
|
||||
# Check if there's a wildcard domain
|
||||
if domain.startswith("*."):
|
||||
raise errors.ConfigurationError(
|
||||
"Wildcard domains are not supported")
|
||||
# Punycode
|
||||
if "xn--" in domain:
|
||||
raise errors.ConfigurationError(
|
||||
"Punycode domains are not presently supported")
|
||||
|
||||
# Unicode
|
||||
try:
|
||||
domain.encode('ascii')
|
||||
except UnicodeDecodeError:
|
||||
raise errors.ConfigurationError(
|
||||
"Internationalized domain names are not presently supported")
|
||||
|
||||
# FQDN checks from
|
||||
# http://www.mkyong.com/regular-expressions/domain-name-regular-expression-example/
|
||||
# Characters used, domain parts < 63 chars, tld > 1 < 64 chars
|
||||
# first and last char is not "-"
|
||||
fqdn = re.compile("^((?!-)[A-Za-z0-9-]{1,63}(?<!-)\\.)+[A-Za-z]{2,63}$")
|
||||
if not fqdn.match(domain):
|
||||
raise errors.ConfigurationError("Requested domain is not a FQDN")
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# coding=utf-8
|
||||
"""Test letsencrypt.display.ops."""
|
||||
import os
|
||||
import sys
|
||||
@@ -385,6 +386,17 @@ class ChooseNamesTest(unittest.TestCase):
|
||||
|
||||
self.assertEqual(self._call(self.mock_install), [])
|
||||
|
||||
def test_get_valid_domains(self):
|
||||
from letsencrypt.display.ops import get_valid_domains
|
||||
all_valid = ["example.com", "second.example.com",
|
||||
"also.example.com"]
|
||||
all_invalid = ["xn--ls8h.tld", "*.wildcard.com", "notFQDN",
|
||||
"uniçodé.com"]
|
||||
two_valid = ["example.com", "xn--ls8h.tld", "also.example.com"]
|
||||
self.assertEqual(get_valid_domains(all_valid), all_valid)
|
||||
self.assertEqual(get_valid_domains(all_invalid), [])
|
||||
self.assertEqual(len(get_valid_domains(two_valid)), 2)
|
||||
|
||||
|
||||
class SuccessInstallationTest(unittest.TestCase):
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
||||
Reference in New Issue
Block a user