函数stream_socket_enable_crypto返回SSL23_GET_SERVER_HELLO:未知协议

时间:2018-12-22 21:03:35

标签: php smtp starttls

我正在尝试验证SMTP服务器的连接数据是否有效(服务器,端口,STARTTLS(如果已选择),用户和密码)。我已经使用Thunderbird尝试了相同的连接数据,所以它们是有效的,因为我可以发送电子邮件。

但是我的PHP代码不起作用,所以我想它不是服务器。调用stream_socket_enable_crypto()

时发生错误

我尝试在crypto_type参数(STREAM_CRYPTO_METHOD_SSLv23_CLIENTSTREAM_CRYPTO_METHOD_TLS_CLIENT)的不同值之间切换,但没有成功。

function smtpconnect($server, $port, $user, $password, $tls = false)
{
    $errno = ''; // error number and messages
    $errstr = '';
    $response = [ 'connected' => false, 'message' => '' ];

    // connect to the host on the specified port
    $socket = fsockopen($server, $port, $errno, $errstr, 30);
    if (is_resource($socket)) {
        $hello = smtpcommand($socket, 'EHLO ' . $_SERVER['SERVER_ADDR']);

        if (substr($hello, 0, 3) != '220') {
            $response['message'] = "This does not look like a SMTP server";
            return $response;
        }

        if ($tls) {
            $tls = smtpcommand($socket, 'STARTTLS');

            if (substr($tls, 0, 3) != '250') {
                $response['message'] = 'TLS connection could not be established';
                return $response;
            }

            $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;

            if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
                $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
                $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
            }

            stream_set_blocking($socket, true);
            $crypto = stream_socket_enable_crypto($socket, true, $crypto_method);
            stream_set_blocking($socket, false);

            if (!$crypto) {
                $response['message'] = 'Encrypted connection could not be started';
                return $response;
            }

            $hello = smtpcommand($socket, 'EHLO ' . $_SERVER['SERVER_ADDR']);
        }

        smtpcommand($socket, 'AUTH LOGIN');
        smtpcommand($socket, base64_encode($user));
        $pass = smtpcommand($socket, base64_encode($password));
        if (substr($pass, 0, 3) != '235') {
            $response['message'] = 'Invalid SMTP user or password';
            return $response;
        }
        $response['connected'] = true;
        return $response;
    }
}

function smtpcommand($socket, $command)
{
    try {
        fwrite($socket, $command . "\r\n");
    } catch (Exception $e) {
        return $e->getMessage();
    }
    return smtpresponse($socket, 30);
}

function smtpresponse($socket, $timeout)
{
    stream_set_timeout($socket, $timeout);
    $response = '';
    while (($line = fgets($socket, 515)) != false) {
        $response .= trim($line) . "\n";
        if (substr($line, 3, 1) == ' ') {
            break;
        }
    }
    return trim($response);
}

尽管STARTTLS返回220,但stream_socket_enable_crypto()函数失败,返回'无法建立TLS连接'消息并将错误发送到日志文件。我希望此函数返回TRUE

0 个答案:

没有答案