Невозможно установить соединение TLS в PHP через fsockopen - PullRequest
2 голосов
/ 15 июля 2011

Я пытаюсь пару дней установить соединение TLS с SMTP-сервером в PHP через fsockopen () на моем недавно установленном сервере Ubuntu. Я пробовал почти все и гуглил в течение нескольких часов, но все равно у меня не получилось.

Код PHP выглядит следующим образом:

$fp = fsockopen("tls://smtp.xxxx.com", 25, $errno, $errstr, 30);
if (!$fp) {
    echo "$errstr ($errno)<br />\n";
} else {
 // some other stuff
}  

Выходные данные равны просто (0), то есть $ errstr = null и $ errno = 0.

OpenSSL установлен и включен:

OpenSSL support: enabled
OpenSSL Library Version: OpenSSL 0.9.8o 01 Jun 2010
OpenSSL Header Version: OpenSSL 0.9.8o 01 Jun 2010

и следующие транспорты сокета потока зарегистрированы: tcp, udp, unix, udg, ssl, sslv3, sslv2, tls.

Порт открыт как работает телнет из консоли.

Есть идеи, что не так или как я мог бы по крайней мере получить еще отладочный вывод?

Спасибо, Markus

Ответы [ 3 ]

6 голосов
/ 15 июля 2011

Ваше соединение не имеет особого смысла. Используя обработчик TLS, вы хотите, чтобы TLS устанавливался ПЕРЕД любыми данными. Но порт 25 является стандартным SMTP, который может устанавливать только TLS ПОСЛЕ , который вы изначально подключили через незашифрованное обычное соединение. Как только это начальное соединение установлено, вы можете включить TLS с помощью команды STARTTLS, чтобы сообщить SMTP-серверу о переключении.

Если вы хотите TLS с самого начала, используйте порт 465, который с самого начала является ssl / tls.

5 голосов
/ 18 декабря 2011

В gmail порт подключения ssl имел ssl с самого начала, но порт tls, который вы подключили обычным, и должен был запустить tls вручную с помощью команды STARTTLS. Я предполагаю, что это то же самое. Вот и пример для Gmail, чтобы вы могли видеть, что происходит. Команда EHLO показывает команду STARTTLS, в то время как если вы начинаете с ssl с самого начала, она переходит в список команд AUTH XOAUTH.

<code><?php
function get($socket,$length=1024){
    $send = '';
    $sr = fgets($socket,$length);
    while( $sr ){
        $send .= $sr;
        if( $sr[3] != '-' ){ break; }
        $sr = fgets($socket,$length);
    }
    return $send;
}
function put($socket,$cmd,$length=1024){
    fputs($socket,$cmd."\r\n",$length);
}
if (!($smtp = fsockopen("smtp.gmail.com", 587, $errno, $errstr, 15))) {
    die("Unable to connect");
}
echo "<pre>\n";
echo get($smtp); // should return a 220 if you want to check

$cmd = "EHLO ${_SERVER['HTTP_HOST']}";
echo $cmd."\r\n";
put($smtp,$cmd);
echo get($smtp); // 250

$cmd = "STARTTLS";
echo $cmd."\r\n";
put($smtp,$cmd);
echo get($smtp); // 220
if(false == stream_socket_enable_crypto($smtp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)){
    // fclose($smtp); // unsure if you need to close as I haven't run into a security fail at this point
    die("unable to start tls encryption");
}

$cmd = "EHLO ".$_SERVER['HTTP_HOST'];
echo $cmd;
put($smtp,$cmd);
echo get($smtp); // 250

$cmd = "QUIT";
echo $cmd."\r\n";
put($smtp,$cmd);
echo get($smtp);

echo "
"; fclose ($ SMTP);
0 голосов
/ 15 июля 2011

Если это работает из командной строки, но не из Apache, то, вероятно, есть некоторая разница между конфигурацией PHP: выполните различие между /etc/php/apache2/php.ini и /etc/php/cli/php.ini и посмотрите, что могло измениться.

...