【问题标题】:Codeigniter 2x Email Class SMTP SSL verification bug on PHP 5.6PHP 5.6 上的 Codeigniter 2x 电子邮件类 SMTP SSL 验证错误
【发布时间】:2015-02-21 17:13:06
【问题描述】:

我不知道你们中有多少人在 PHP 5.6 上使用 Codeigniter 2x,但这个最新的 PHP 版本带来了 Codeigniter 尚未适应的变化。其中一项更改与 OpenSSL 有关:

所有加密的客户端流现在默认启用对等验证。默认情况下,这将使用 OpenSSL 的默认 CA 包来验证对等证书。在大多数情况下,无需进行任何更改即可与具有有效 SSL 证书的服务器进行通信,因为分销商通常将 OpenSSL 配置为使用已知良好的 CA 捆绑包。 - OpenSSL changes in PHP 5.6.x (PHP Manual)


似乎在 PHP 5.6.0(至少是 Debian jessie 中的版本,带有 openssl 1.0.1h-3)中,这个函数现在验证 SSL 证书(以多种方式) .首先,对于不受信任的证书(即本地没有信任的匹配 CA),它似乎失败,其次,对于请求和证书中不匹配的主机名,它似乎失败。


“PHP 5.6 现在验证 SSL 证书,由于证书 CN 不匹配,“fsockopen”函数在“ConnectToHost”方法中失败(需要主机名,但给出了 IP)。 - Klemen (PHP 5.6 compatibility)

问题在于,此更改导致电子邮件类 SMTP 协议出现错误:

fsockopen():SSL 操作失败,代码为 1。OpenSSL 错误消息:错误:14090086:SSL 例程:SSL3_GET_SERVER_CERTIFICATE:证书验证失败

我使用的是 Windows 的 IIS 7 本地服务器,当我将 PHP 的版本切换到 5.3 时,电子邮件已成功发送。现在,当我将其切换回 5.6 时,会发生 SSL 验证。话虽如此,这确实是PHP最新的5.6版本的问题。

这是我用来通过 SMTP 发送电子邮件的代码:

    $config = array(
      'protocol' => 'smtp',
      'smtp_host' => 'ssl://smtp.googlemail.com',
      'smtp_port' => 465,
      'smtp_user' => 'xxxx@gmail.com', // change it to yours
      'smtp_pass' => 'xxxx', // change it to yours
      'mailtype' => 'html',
      'charset' => 'iso-8859-1',
      'wordwrap' => TRUE,
    );
    $message = 'When they give you the eys!!!!';
    $this->load->library('email', $config);
    $this->email->set_newline("\r\n");
    $this->email->from('xxxx@xxxx.com','Insert Name'); // change it to yours
    $this->email->to('xxxxx@xxxxxx.com');// change it to yours
    $this->email->subject('Bye, bye, pretty baby!');
    $this->email->message($message);
    if($this->email->send())
    {
     echo 'Email sent.';
    }
    else
    {
     show_error($this->email->print_debugger());
    }

这是一个电子邮件库使用 SMTP 发送电子邮件的方法:

    protected function _smtp_connect()
{
    $ssl = NULL;
    if ($this->smtp_crypto == 'ssl')
        $ssl = 'ssl://';
    $this->_smtp_connect = fsockopen($ssl.$this->smtp_host,
                                    $this->smtp_port,
                                    $errno,
                                    $errstr,
                                    $this->smtp_timeout);
    if ( ! is_resource($this->_smtp_connect))
    {
        $this->_set_error_message('lang:email_smtp_error', $errno." ".$errstr);
        return FALSE;
    }
    $this->_set_error_message($this->_get_smtp_data());
    if ($this->smtp_crypto == 'tls')
    {
        $this->_send_command('hello');
        $this->_send_command('starttls');
        stream_socket_enable_crypto($this->_smtp_connect, TRUE, STREAM_CRYPTO_METHOD_TLS_CLIENT);
    }
    return $this->_send_command('hello');
}

你知道我怎样才能让它在 5.6 上运行吗?谢谢!

【问题讨论】:

    标签: php codeigniter email ssl


    【解决方案1】:

    首先,您的电子邮件配置没问题!不用担心这个...
    当您更新到 PHP 5.6+ 时,必须设置“CA Root”,否则 OpenSSL 证书验证无法正常工作。

    第一步: 安装 CA_Root(在我的情况下,在 FreeBSD 10 上,通过 Ports
    /usr/ports/security/ca_root_nss

    安装后,Pem Cert 将位于:
    /usr/local/etc/ssl/cert.pem


    第二步: 添加到 php.ini openssl.cafile

    openssl.cafile = /usr/local/etc/ssl/cert.pem

    重新启动您的 HTTP 服务器,并使用 phpinfo() 进行验证

    More details about this, my Blog on PT-BR language

    PS:有时...不要忘记授权您的设备访问 Gmail:设置/其他配置帐户.../设备

    【讨论】:

    • 他在 Windows 上。
    猜你喜欢
    • 2014-06-07
    • 2014-02-15
    • 2014-10-26
    • 1970-01-01
    • 1970-01-01
    • 2017-11-28
    • 1970-01-01
    • 2012-10-27
    • 2013-11-24
    相关资源
    最近更新 更多