2012-03-22 11 views
0

mxdeepのオプションをtrueに設定して、Zend_Validate_EmailAddressを使用し始めました。 IPアドレスが予約済みのIP範囲にあるMXレコードについては、いくつかの誤った否定が出ていると思います。Zend電子メールアドレスとディープMXチェックの検証

良い例はMX records for harn.ufl.eduです。 128.0.0.0/16のIPアドレスのために失敗しているようです。ただし、予約済みの範囲にない8.6.245.30を使用するレコードが1つあります。

もう1つの例はMX record for martinhealth.orgです。これは、MXレコードドメインの198.136.38.2を使用しています。

これは技術的に間違っているものの、実際に動作するものですか?

+0

は、Windowsでそれを使用していますか? _Within Windows環境MXチェックは、PHP 5.3以上を使用している場合にのみ利用可能です。 PHP 5.3の下でオプションで有効になっていてもMXチェックは使用されません._ –

+0

'Zend_Validate_EmailAddress'にバグがあったようです。 「128.」の範囲内の唯一の予約済みIPアドレスは '128.0.0.0'〜' 128.0.255.255'です。ハーンのメールサーバーはこの範囲にはありませんが、Zend_Validate_Emailは誤ってサブネットマスクを使って何かを計算しているようです。私がもっと知ることができるかどうかがわかります。 – drew010

+0

まもなく私がこの[チャット](http://chat.stackoverflow.com/rooms/9213/zend-validate-emailaddress)を設定して問題を話し合ったところ、ZFの問題がどこにあるのか分かりました。 – drew010

答えて

0

私の投稿のコメントには、Zend_Validate_EmailAddress::_isReservedにバグがあります。バグだけでなく、ロジックの流れを理解することは難しいです。 private関数なので、protectedに変更しましたので、サブクラスでオーバーライドできます。また、$_invalidIp配列にはいくつかの不正確な範囲がありました。

私の論理チェックでは、IPアドレスを比較する最も簡単な方法は、それらを10進整数に変換することでした。

ここに私のサブクラスです:

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); 
    } 
} 
+0

私は最終的にZend Frameworkの問題追跡ツールにバグを提出しました:http://framework.zend.com/issues/browse/ZF-12160 – Sonny

関連する問題