mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-17 05:41:25 +02:00
@@ -59,6 +59,14 @@ class AdminParametersForm(param_forms.AdminParametersForm):
|
||||
)
|
||||
)
|
||||
|
||||
custom_dns_server = GenericIPAddressField(
|
||||
label=ugettext_lazy("Custom DNS server"),
|
||||
required=False,
|
||||
help_text=ugettext_lazy(
|
||||
"Use a custom DNS server instead of local server configuration"
|
||||
)
|
||||
)
|
||||
|
||||
dkim_keys_storage_dir = forms.CharField(
|
||||
label=ugettext_lazy("DKIM keys storage directory"),
|
||||
initial="",
|
||||
@@ -79,14 +87,6 @@ class AdminParametersForm(param_forms.AdminParametersForm):
|
||||
)
|
||||
)
|
||||
|
||||
use_specific_dns_server = GenericIPAddressField(
|
||||
label=ugettext_lazy("Use specific DNS server"),
|
||||
required=False,
|
||||
help_text=ugettext_lazy(
|
||||
"Use a specific DNS server instead of local server configuration"
|
||||
)
|
||||
)
|
||||
|
||||
mbsep = SeparatorField(label=ugettext_lazy("Mailboxes"))
|
||||
|
||||
handle_mailboxes = YesNoField(
|
||||
|
||||
+29
-27
@@ -7,7 +7,6 @@ from __future__ import unicode_literals
|
||||
import ipaddress
|
||||
import logging
|
||||
import random
|
||||
import socket
|
||||
import string
|
||||
from functools import wraps
|
||||
from itertools import chain
|
||||
@@ -175,12 +174,15 @@ def get_domain_mx_list(domain):
|
||||
"""Return a list of MX IP address for domain."""
|
||||
result = []
|
||||
logger = logging.getLogger("modoboa.admin")
|
||||
dns_server = param_tools.get_global_parameter("use_specific_dns_server")
|
||||
dns_server = param_tools.get_global_parameter("custom_dns_server")
|
||||
if dns_server:
|
||||
dns.resolver.default_resolver.nameservers = [dns_server]
|
||||
resolver = dns.resolver.Resolver()
|
||||
resolver.nameservers = [dns_server]
|
||||
else:
|
||||
resolver = dns.resolver
|
||||
|
||||
try:
|
||||
dns_answers = dns.resolver.query(domain, "MX")
|
||||
dns_answers = resolver.query(domain, "MX")
|
||||
except dns.resolver.NXDOMAIN as e:
|
||||
logger.error(_("No DNS records found for %s") % domain, exc_info=e)
|
||||
except dns.resolver.NoAnswer as e:
|
||||
@@ -193,29 +195,29 @@ def get_domain_mx_list(domain):
|
||||
domain, exc_info=e)
|
||||
else:
|
||||
for dns_answer in dns_answers:
|
||||
try:
|
||||
mx_domain = dns_answer.exchange.to_unicode(
|
||||
omit_final_dot=True, idna_codec=IDNA_2008_UTS_46)
|
||||
ip_answers = dns.resolver.query(mx_domain)
|
||||
except dns.resolver.NXDOMAIN as e:
|
||||
logger.error(_("No DNS records found without MX for %s")
|
||||
% domain, exc_info=e)
|
||||
else:
|
||||
for ip_answer in ip_answers:
|
||||
for answer_set in ip_answer.response.answer:
|
||||
for address in answer_set:
|
||||
try:
|
||||
address_smart = smart_text(address)
|
||||
mx_ip = ipaddress.ip_address(address_smart)
|
||||
except ValueError as e:
|
||||
logger.warning(
|
||||
_("Invalid IP address format for "
|
||||
"%(domain)s; %(addr)s")
|
||||
% {"domain": mx_domain,
|
||||
"addr": smart_text(address)},
|
||||
exc_info=e)
|
||||
else:
|
||||
result.append((mx_domain, mx_ip))
|
||||
for rtype in ["A", "AAAA"]:
|
||||
try:
|
||||
mx_domain = dns_answer.exchange.to_unicode(
|
||||
omit_final_dot=True, idna_codec=IDNA_2008_UTS_46)
|
||||
ip_answers = resolver.query(mx_domain, rtype)
|
||||
except dns.resolver.NXDOMAIN as e:
|
||||
logger.error(
|
||||
_("No {type} record found for MX {mx}").format(
|
||||
type=rtype, mx=domain), exc_info=e)
|
||||
else:
|
||||
for ip_answer in ip_answers:
|
||||
try:
|
||||
address_smart = smart_text(ip_answer.address)
|
||||
mx_ip = ipaddress.ip_address(address_smart)
|
||||
except ValueError as e:
|
||||
logger.warning(
|
||||
_("Invalid IP address format for "
|
||||
"{domain}; {addr}").format(
|
||||
domain=mx_domain,
|
||||
addr=smart_text(ip_answer.address)
|
||||
), exc_info=e)
|
||||
else:
|
||||
result.append((mx_domain, mx_ip))
|
||||
return result
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -19,8 +19,9 @@ from django.utils.translation import ugettext as _, ugettext_lazy
|
||||
from modoboa.core.models import User
|
||||
from modoboa.lib import exceptions as lib_exceptions
|
||||
from modoboa.lib.email_utils import split_mailbox
|
||||
from modoboa.lib.sysutils import exec_cmd
|
||||
from modoboa.lib.sysutils import doveadm_cmd
|
||||
from modoboa.parameters import tools as param_tools
|
||||
|
||||
from .base import AdminObject
|
||||
from .domain import Domain
|
||||
|
||||
@@ -158,8 +159,8 @@ class Mailbox(AdminObject):
|
||||
options = {}
|
||||
if curuser != mbowner:
|
||||
options["sudo_user"] = mbowner
|
||||
code, output = exec_cmd(
|
||||
"doveadm user -f home %s" % self.full_address, **options
|
||||
code, output = doveadm_cmd(
|
||||
"user -f home %s" % self.full_address, **options
|
||||
)
|
||||
if code:
|
||||
raise lib_exceptions.InternalError(
|
||||
|
||||
@@ -114,7 +114,7 @@ class MXTestCase(ModoTestCase):
|
||||
"""Test to get mx list from specific DNS server."""
|
||||
mock_query.side_effect = utils.mock_dns_query_result
|
||||
mock_getaddrinfo.side_effect = utils.mock_ip_query_result
|
||||
self.set_global_parameter("use_specific_dns_server", "123.45.67.89")
|
||||
self.set_global_parameter("custom_dns_server", "123.45.67.89")
|
||||
get_domain_mx_list("does-not-exist.example.com")
|
||||
|
||||
@mock.patch("ipaddress.ip_address")
|
||||
@@ -139,13 +139,19 @@ class MXTestCase(ModoTestCase):
|
||||
("modoboa.admin", "ERROR", _("No working name servers found")),
|
||||
("modoboa.admin", "WARNING",
|
||||
_("DNS resolution timeout, unable to query %s at the moment")
|
||||
% "timeout.example.com"),
|
||||
% "timeout.example.com"),
|
||||
("modoboa.admin", "ERROR",
|
||||
_("No DNS records found without MX for %(domain)s")
|
||||
_("No A record found for MX %(domain)s")
|
||||
% {"domain": "no-lookup.example.com"}),
|
||||
("modoboa.admin", "ERROR",
|
||||
_("No AAAA record found for MX %(domain)s")
|
||||
% {"domain": "no-lookup.example.com"}),
|
||||
("modoboa.admin", "WARNING",
|
||||
_("Invalid IP address format for %(domain)s; %(addr)s")
|
||||
% {"domain": "bad-response.example.com", "addr": "000.0.0.0"}),
|
||||
_("Invalid IP address format for %(domain)s; %(addr)s")
|
||||
% {"domain": "bad-response.example.com", "addr": "000.0.0.0"}),
|
||||
("modoboa.admin", "WARNING",
|
||||
_("Invalid IP address format for %(domain)s; %(addr)s")
|
||||
% {"domain": "bad-response.example.com", "addr": "000.0.0.0"}),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"""Test utilities."""
|
||||
|
||||
from __future__ import unicode_literals
|
||||
from dns.rrset import RRset
|
||||
|
||||
import socket
|
||||
|
||||
@@ -12,27 +11,16 @@ from dns.rdtypes.ANY.MX import MX
|
||||
from dns.resolver import NXDOMAIN, NoAnswer, NoNameservers, Timeout
|
||||
|
||||
|
||||
|
||||
class RRsetResponse(object):
|
||||
|
||||
def __init__(self):
|
||||
self.answer = [["192.0.2.1"]]
|
||||
|
||||
class RRset(object):
|
||||
|
||||
def __init__(self):
|
||||
self.response = RRsetResponse()
|
||||
self.address = "192.0.2.1"
|
||||
|
||||
class RRsetResponseInvalid(object):
|
||||
|
||||
def __init__(self):
|
||||
self.answer = [["000.0.0.0"]]
|
||||
|
||||
class RRsetInvalid(object):
|
||||
|
||||
def __init__(self):
|
||||
self.response = RRsetResponseInvalid()
|
||||
|
||||
self.address = "000.0.0.0"
|
||||
|
||||
|
||||
_MX_RECORD_1 = MX("IN", "MX", 10, Name("mx.example.com".split(".")))
|
||||
@@ -42,7 +30,6 @@ _DNE_MX_RECORD = MX("IN", "MX", 10, Name(
|
||||
"does-not-exist.example.com".split(".")))
|
||||
_MX_RECORDS = [_MX_RECORD_1]
|
||||
_IP_SET_RECORDS = [RRset()]
|
||||
|
||||
|
||||
_IPV4_RECORD_1 = (socket.AF_INET, socket.SOCK_STREAM, 6, "", ("192.0.2.1", 25))
|
||||
_IPV4_RECORD_2 = (socket.AF_INET, socket.SOCK_STREAM, 6, "", ("192.0.2.2", 25))
|
||||
@@ -79,20 +66,20 @@ _POSSIBLE_IP_RESULTS = {
|
||||
|
||||
def mock_dns_query_result(qname, *args, **kwargs):
|
||||
if "MX" in args:
|
||||
if qname in _POSSIBLE_DNS_RESULTS:
|
||||
return get_mock_dns_query_response(_POSSIBLE_DNS_RESULTS, qname)
|
||||
return _MX_RECORDS
|
||||
if qname in _POSSIBLE_DNS_RESULTS:
|
||||
return get_mock_dns_query_response(_POSSIBLE_DNS_RESULTS, qname)
|
||||
return _MX_RECORDS
|
||||
elif qname in _POSSIBLE_DNS_RESULTS_NO_MX:
|
||||
return get_mock_dns_query_response(_POSSIBLE_DNS_RESULTS_NO_MX, qname)
|
||||
else:
|
||||
return _IP_SET_RECORDS
|
||||
|
||||
|
||||
|
||||
def get_mock_dns_query_response(responses, attributeName):
|
||||
if isinstance(responses[attributeName], Exception):
|
||||
raise responses[attributeName]
|
||||
else:
|
||||
return responses[attributeName]
|
||||
return responses[attributeName]
|
||||
|
||||
|
||||
def mock_ip_address_result(host, *args, **kwargs):
|
||||
if host in _POSSIBLE_IP_RESULTS:
|
||||
@@ -100,9 +87,8 @@ def mock_ip_address_result(host, *args, **kwargs):
|
||||
raise _POSSIBLE_IP_RESULTS[host]
|
||||
else:
|
||||
return _POSSIBLE_IP_RESULTS[host]
|
||||
|
||||
return _IP_RECORDS
|
||||
|
||||
|
||||
|
||||
def mock_ip_query_result(host, port, *args, **kwargs):
|
||||
if host in _POSSIBLE_IP_RESULTS:
|
||||
@@ -110,5 +96,4 @@ def mock_ip_query_result(host, port, *args, **kwargs):
|
||||
raise _POSSIBLE_IP_RESULTS[host]
|
||||
else:
|
||||
return _POSSIBLE_IP_RESULTS[host]
|
||||
|
||||
return _IP_RECORDS
|
||||
|
||||
@@ -69,7 +69,7 @@ SETTINGS_SAMPLE = {
|
||||
"admin-create_alias_on_mbox_rename": False,
|
||||
"admin-dkim_keys_storage_dir": "",
|
||||
"admin-dkim_default_key_length": 1024,
|
||||
"admin-use_specific_dns_server": "193.43.55.67"
|
||||
"admin-custom_dns_server": "193.43.55.67"
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user