Zend验证电子邮件地址和深度MX检查 [英] Zend Validate Email Address and Deep MX Checking

查看:263
本文介绍了Zend验证电子邮件地址和深度MX检查的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经开始使用 Zend_Validate_EmailAddress mx 选项设置为true。我想我有一些假阴性,当涉及IP地址在保留的IP范围的MX记录。

I have started using Zend_Validate_EmailAddress with the mx and deep options set to true. I think I am getting some false negatives when it comes to MX records that have IP addresses in the reserved IP ranges.

一个很好的例子是 harn.ufl.edu的MX记录。看来,由于128.0.0.0/16范围内的IP地址,它是失败的。然而,它有一个记录使用8.6.245.30,这不在保留的范围内。

A good example is the MX records for harn.ufl.edu. It appear that it's failing because of IP addresses in the 128.0.0.0/16 range. It does however have one record that uses 8.6.245.30, which is not in the reserved range.

另一个例子是 martinhealth.org的MX记录。这是MX记录域使用198.136.38.2。

Another example is the MX record for martinhealth.org. It's MX record domain uses 198.136.38.2.

这是一个技术上不正确但实际工作的情况吗?

Is this a case of something that's technically incorrect but actually works?

推荐答案

正如对我的帖子的评论所暗示的,在 Zend_Validate_EmailAddress :: _ isReserved 中有一个错误。不仅仅是bug,而且很难理解逻辑流程。这是一个 private 函数,所以我把它改成了 protected ,所以我可以在我的子类中覆盖它。在 $ _ invalidIp 数组中也有一些不正确的范围。

As the comments on my post allude, there is a bug in Zend_Validate_EmailAddress::_isReserved. Not only is it buggy, but it's difficult to understand the logic flow. It was a private function, so I changed it to protected so I could override it in my sub-class. There were also some incorrect ranges in the $_invalidIp array.

对于我的逻辑检查,我决定最简单(最清晰的)比较IP地址的方法是将它们转换为十进制整数等价物。

For my logic check, I decided that the simplest (clearest?) way to compare IP addresses was to convert them to their decimal integer equivalents.

这是我的子类:

class My_Validate_EmailAddressDeep extends Zend_Validate_EmailAddress
{
    /**
     * @var array
     */
    protected $_messageTemplates = array(
        self::INVALID            => "Invalid type given. String expected",
        self::INVALID_FORMAT     => "'%value%' is not a valid email address in the basic [user]@[hostname] format",
        self::INVALID_HOSTNAME   => "The '%hostname%' part of '%value%' is not a valid hostname",
        self::INVALID_MX_RECORD  => "'%hostname%' does not appear to be configured to accept email",
        self::INVALID_SEGMENT    => "'%hostname%' does not appear to be configured to accept external email",
        self::DOT_ATOM           => null,
        self::QUOTED_STRING      => null,
        self::INVALID_LOCAL_PART => "The '%localPart%' part of '%value%' is not valid",
        self::LENGTH_EXCEEDED    => "'%value%' is longer than the allowed length for an email address",
    );

    /**
     * Internal options array
     * @var array
     */
    protected $_options = array(
        'allow' => Zend_Validate_Hostname::ALLOW_DNS,
        'deep' => true,
        'domain' => true,
        'hostname' => null,
        'mx' => true,
    );

    /**
     * @see http://en.wikipedia.org/wiki/Reserved_IP_addresses#Reserved_IPv4_addresses
     * @var array [first octet] => [[CIDR] => [[range start], [range end]]]
     */
    protected $_reservedIps = array(
        '0' => array('0.0.0.0/8' => array('0.0.0.0', '0.255.255.255',),),
        '10' => array('10.0.0.0/8' => array('10.0.0.0', '10.255.255.255',),),
        '127' => array('127.0.0.0/8' => array('127.0.0.0', '127.255.255.255',),),
        '169' => array('169.254.0.0/16' => array('169.254.0.0', '169.254.255.255',),),
        '172' => array('172.16.0.0/12' => array('172.16.0.0', '172.31.255.255',),),
        '192' => array(
            '192.0.2.0/24' => array('192.0.2.0', '192.0.2.255',),
            '192.88.99.0/24' => array('192.88.99.0', '192.88.99.255',),
            '192.168.0.0/16' => array('192.168.0.0', '192.168.255.255',),
        ),
        '198' => array(
            '198.18.0.0/15' => array('198.18.0.0', '198.19.255.255',),
            '198.51.100.0/24' => array('198.51.100.0', '198.51.100.255',),
        ),
        '203' => array('203.0.113.0/24' => array('203.0.113.0', '203.0.113.255',),),
        '224' => array('224.0.0.0/4' => array('224.0.0.0', '239.255.255.255',),),
        '240' => array('240.0.0.0/4' => array('240.0.0.0', '255.255.255.255',),),
    );

    /**
     * Returns if the given host is reserved
     *
     * @param string $host
     * @return boolean
     */
    protected function _isReserved($host)
    {
        if (!preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $host)) {
            $host = gethostbyname($host);
        }

        $octets = explode('.', $host);
        if (224 <= (int) $octets[0]) {
            // IP Addresses beginning with 224 or greater are all reserved, short-circuit range checks
            return true;
        } elseif (array_key_exists($octets[0], $this->_reservedIps)) {
            // for integer comparisons
            $intIp = $this->_ipToInt($host);

            // loop over reserved IP addresses
            foreach ($this->_reservedIps as $ranges) {
                foreach ($ranges as $range) {
                    if (($this->_ipToInt($range[0]) <= $intIp)
                            && ($this->_ipToInt($range[1]) >= $intIp)) {
                        // the IP address falls in a reserved range
                        return true;
                    }
                }
            }

            // the IP address did not fall in a reserved range
            return false;
        } else {
            return false;
        }
    }

    /**
     * Convert a dot-decimal IP address to it's decimal integer equivalent
     *
     * @param string $ip
     * @return integer
     */
    protected function _ipToInt($ip)
    {
        $octets = explode('.', $ip);
        foreach ($octets as $key => $octet) {
            $octets[$key] = str_pad(decbin($octet), 8, '0', STR_PAD_LEFT);
        }
        $bin = implode('', $octets);
        return bindec($bin);
    }
}

这篇关于Zend验证电子邮件地址和深度MX检查的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆