Ejemplo n.º 1
0
def main():

    # If we don't append the trailing dot, the query would try the DNS search
    # path.
    fqdn = getfqdn() + '.'

    try:
        result = dns_query(fqdn, SSHFP)
    except DNSException:
        print('WARNING got no host key fingerprint')
        exit(1)

    # Map the host keys in a dictionary using the algorithm and the fingerprint
    # type as the identifier for fast lookup while comparing them with the keys
    # from the DNS.
    output = check_output(['ssh-keygen', '-r', fqdn], universal_newlines=True)
    host_keys = {(r.algorithm, r.fp_type): r for r in (
        dns_from_text(IN, SSHFP, l.split(None, 3)[3])
        for l in output.splitlines()
    )}

    for record in result.rrset:
        record_id = (record.algorithm, record.fp_type)
        if record_id not in host_keys:
            print('WARNING host key for fingerprint does not exist')
            exit(1)
        if record.fingerprint != host_keys[record_id].fingerprint:
            print('WARNING host key fingerprint is inconsistent')
            exit(1)

    print('OK')
    exit(0)
Ejemplo n.º 2
0
def lookup_receiver_policy(host):
    '''Lookup the reciever policy for a host. Returns a ReceiverPolicy.

:param str host: The host to query. The *actual* host that is queried has
                 ``_dmarc.`` prepended to it.
:returns: The DMARC receiver policy for the host. If there is no published
          policy then :attr:`gs.dmarc.ReceiverPolicy.noDmarc` is returned.
:rtype: A member of the :class:`gs.dmarc.ReceiverPolicy` enumeration.
'''
    dmarcHost = '_dmarc.{0}'.format(host)
    retval = ReceiverPolicy.noDmarc
    try:
        dnsAnswer = dns_query(dmarcHost, 'TXT')
    except (NXDOMAIN, NoAnswer):
        pass  # retval = ReceiverPolicy.noDmarc
    else:
        answer = str(dnsAnswer[0])
        # Check that v= field is the first one in the answer (which is in
        # double quotes) as per Section 7.1 (5):
        #     In particular, the "v=DMARC1" tag is mandatory and MUST appear
        #     first in the list. Discard any that do not pass this test.
        # http://tools.ietf.org/html/draft-kucherawy-dmarc-base-04#section-7.1
        if answer[:9] == '"v=DMARC1':
            tags = answer_to_dict(answer)
            # TODO: check that 'none' is the right assumption?
            p = tags.get('p', 'none')
            policy = p if hasattr(ReceiverPolicy, p) else 'noDmarc'
            retval = ReceiverPolicy[policy]
        # else: retval = ReceiverPolicy.noDmarc
    assert isinstance(retval, ReceiverPolicy)
    return retval
Ejemplo n.º 3
0
def main():

    # If we don't append the trailing dot, the query would try the DNS search
    # path.
    fqdn = getfqdn() + '.'

    try:
        result = dns_query(fqdn, SSHFP)
    except DNSException:
        print('WARNING got no host key fingerprint')
        exit(1)

    # Map the host keys in a dictionary using the algorithm and the fingerprint
    # type as the identifier for fast lookup while comparing them with the keys
    # from the DNS.
    output = check_output(['ssh-keygen', '-r', fqdn], universal_newlines=True)
    host_keys = {(r.algorithm, r.fp_type): r
                 for r in (dns_from_text(IN, SSHFP,
                                         l.split(None, 3)[3])
                           for l in output.splitlines())}

    for record in result.rrset:
        record_id = (record.algorithm, record.fp_type)
        if record_id not in host_keys:
            print('WARNING host key for fingerprint does not exist')
            exit(1)
        if record.fingerprint != host_keys[record_id].fingerprint:
            print('WARNING host key fingerprint is inconsistent')
            exit(1)

    print('OK')
    exit(0)
Ejemplo n.º 4
0
 def connect_start( self ):
     global dns_query
     self._signal.acquire()
     try:
         if self._host == '__DUMMY__':
             self._fatal_error = socket.error( errno.EPIPE, "I need to pretend to fail here" )
             return
         if self._sock is None:
             if not self._addrinfo:
                 #print "No addresses left to try"
                 self._retry -= 1
                 if self._retry < 0:
                     #print "Out of retries"
                     self._connecting = None
                     if not self._fatal_error:
                         self._fatal_error = socket.error( errno.EPIPE, "Unknown connection failure." )
                     self._signal.notify()
                     return
                 try:
                     for p in self._port:
                         if isinstance( p, int ):
                             self._addrinfo += socket.getaddrinfo( self._host, p, socket.AF_UNSPEC, socket.SOCK_STREAM )
                         elif dns_query is not None:
                             try:
                                 answers = dns_query( ('_%s._%s.' % p) + self._host, 'SRV' )
                                 for rdata in answers:
                                     self._addrinfo += socket.getaddrinfo( rdata.target, rdata.port, socket.AF_UNSPEC, socket.SOCK_STREAM )
                             except:
                                 pass
                 except socket.gaierror, e:
                     raise socket.error( errno.EPIPE, str(e) )
                 self._addrinfo.reverse()
             self._fatal_error = None
             af, st, pr, cname, sa = self._addrinfo.pop()
             try:
                 self._sock = socket.socket( af, st, pr )
             except socket.error, e:
                 self._fatal_error = self.transform_exception( e, 'socket create' )
                 if self._fatal_error.args[0] != errno.EAGAIN:
                     return self.connect_start()
             except:
                 return self.connect_start()
             if sys.platform != 'symbian_s60':
                 self._sock.setblocking( 0 )
             try:
                 #print "Connecting to",`sa`
                 self._connecting = time.time()
                 self._sock.connect( sa )
             except socket.error, e:
                 self._fatal_error = self.transform_exception( e, 'connect' )
                 if self._fatal_error.args[0] != errno.EAGAIN:
                     return self.connect_start()
Ejemplo n.º 5
0
def validate_email(address_text):

    is_valid = True

    if not EMAIL_REGEX.match(address_text):
        is_valid = False
    else:
        # Must have Gmail or Google Apps MX records
        domain = address_text.split('@')[1]
        try:
            answers = dns_query(domain, 'MX')
            gmail_mx_servers = [
                        # Google apps for your domain
                        'aspmx.l.google.com.',
                        'aspmx2.googlemail.com.',
                        'aspmx3.googlemail.com.',
                        'aspmx4.googlemail.com.',
                        'aspmx5.googlemail.com.',
                        'alt1.aspmx.l.google.com.',
                        'alt2.aspmx.l.google.com.',
                        'alt3.aspmx.l.google.com.',
                        'alt4.aspmx.l.google.com.',

                        # Gmail
                        'gmail-smtp-in.l.google.com.',
                        'alt1.gmail-smtp-in.l.google.com.',
                        'alt2.gmail-smtp-in.l.google.com.',
                        'alt3.gmail-smtp-in.l.google.com.',
                        'alt4.gmail-smtp-in.l.google.com.'
                         ]
            # All relay servers must be gmail
            for rdata in answers:
                if not str(rdata.exchange).lower() in gmail_mx_servers:
                    is_valid = False
                    log.error("Non-Google MX record: %s" % str(rdata.exchange))

        except NoNameservers:
            is_valid = False


        return dict(
            valid_for_inbox = is_valid,
            valid_address = address_text
        )
Ejemplo n.º 6
0
def lookup_receiver_policy(host, policyTag='p'):
    # type: (str, str) -> ReceiverPolicy
    '''Lookup the reciever policy for a host. Returns a ReceiverPolicy.

:param str host: The host to query. The *actual* host that is queried has
                 ``_dmarc.`` prepended to it.
:param str policyTag: The *tag* that holds the receiver policy. Must be
                      ``p`` (the default) or ``sp`` (for the subdomain
                      policy). See :rfc:`7489#section-6.3`.
:returns: The DMARC receiver policy for the host. If there is no published
          policy then :attr:`gs.dmarc.ReceiverPolicy.noDmarc` is returned.
:rtype: A member of the :class:`gs.dmarc.ReceiverPolicy` enumeration.'''
    if policyTag not in ('p', 'sp'):
        raise ValueError('policyTag must be "p" or "sp".')
    dmarcHost = '_dmarc.{0}'.format(host)
    retval = ReceiverPolicy.noDmarc
    try:
        dnsAnswer = dns_query(dmarcHost, 'TXT')
    except (NXDOMAIN, NoAnswer, NoNameservers):
        pass  # retval = ReceiverPolicy.noDmarc
    else:
        answer = str(dnsAnswer[0])
        # Check that v= field is the first one in the answer (which is in
        # double quotes) as per Section 7.1 (5):
        #     In particular, the "v=DMARC1" tag is mandatory and MUST appear
        #     first in the list. Discard any that do not pass this test.
        # http://tools.ietf.org/html/draft-kucherawy-dmarc-base-04#section-7.1
        if answer[:9] == '"v=DMARC1':
            tags = answer_to_dict(answer)
            # TODO: check that 'none' is the right assumption?
            if policyTag == 'p':
                p = tags.get('p', 'none')
            else:
                # Look up the subdomain policy, falling back to the main policy
                # <https://tools.ietf.org/html/rfc7489#section-6.3>
                p = tags.get('sp', tags.get('p', 'none'))
            policy = p if hasattr(ReceiverPolicy, p) else 'noDmarc'
            # https://github.com/python/mypy/issues/1381
            retval = ReceiverPolicy[policy]  # type: ignore
    return retval
Ejemplo n.º 7
0
    def resolve(self):
        """
        Attempt to resolve this name once, following CNAME chains if necessary.
        """
        ttl = self.min_resolution_delay

        try:
            log.debug("Query: %s", self.target)
            answer = dns_query(self.target, rdtype=A, tcp=True)
            log.debug("Answer: %s", answer)
            for item in answer.rrset.items:
                self.values.add(item.address)
                log.debug("Resolved %s (%s): %s", self.name, self.target,
                          item.address)
            ttl = max(ttl, answer.ttl)
            if self.ttl is None:
                self.ttl = answer.ttl
        except NXDOMAIN as e:
            log.warning("Failed to resolve %s (%s): %s", self.name,
                        self.target, e)

        self.pending_resolve_count -= 1
        self.next_resolution_time = time() + ttl
        return
Ejemplo n.º 8
0
    def resolve(self):
        """
        Attempt to resolve this name once, following CNAME chains if necessary.
        """
        ttl = self.min_resolution_delay

        try:
            log.debug("Query: %s", self.target)
            answer = dns_query(self.target, rdtype=A, tcp=True)
            log.debug("Answer: %s", answer)
            for item in answer.rrset.items:
                self.values.add(item.address)
                log.debug("Resolved %s (%s): %s", self.name, self.target,
                          item.address)
            ttl = max(ttl, answer.ttl)
            if self.ttl is None:
                self.ttl = answer.ttl
        except NXDOMAIN as e:
            log.warning("Failed to resolve %s (%s): %s", self.name,
                        self.target, e)

        self.pending_resolve_count -= 1
        self.next_resolution_time = time() + ttl
        return