Невозможно отправить электронную почту через порт 465 с помощью модуля Net :: SMTP в Perl - PullRequest
1 голос
/ 29 марта 2019

Я хочу отправить электронную почту через порт 465 моего сервера smtp с помощью модуля Net :: SMTP (без использования Net :: SMTP :: SSL) в сценарии perl от клиента. На порту 465 моего SMTP-сервера запускается служба «отправки», которая понимает SMTPS.

Я попытался найти способ сделать это в Google. Затем использовал модуль Net :: SMTP :: SSL, чтобы сделать запрос на порт 465. Он отлично работает.

Но документация для Net :: SMTP :: SSL рекомендует использовать последнюю версию Net :: SMTP вместо Net :: SMTP :: SSL. В документе четко указано, что

Начиная с Net :: SMTP v1.28 (2014-10-08), Net :: SMTP сама поддерживает SMTP через SSL, а также для STARTTLS. Используйте Net :: SMTP, а не Net :: SMTP :: SSL.

Я обновил модуль Net :: SMTP до последней версии 3.11.

Также в документе для Net :: SMTP также четко указано, что

С установленным IO :: Socket :: SSL он также обеспечивает поддержку неявного и явное шифрование TLS, т.е. SMTPS или SMTP + STARTTLS.

Часть моего кода сценария Perl на клиенте, относящаяся к упомянутой проблеме, выглядит так:

$smtp = Net::SMTP::SSL->new("$mailserver",
                        Hello => "$localhostname",
                        Timeout => 60,
                        Port => "$port",  //Port value is 465
                        Debug => 1);
 $smtp->auth($username, $password);

... Оставшийся скрипт, который устанавливает отправителя, тело получателя и т. Д.

Это отлично работает. Письмо будет отправлено. Заменив вышеуказанный код на:

$smtp = Net::SMTP->new("$mailserver",
                        Hello => "$localhostname",
                        Timeout => 60,
                        Port => "$port",  //Port value is 465
                        Debug => 1);
$smtp->auth($username, $password);

... Оставшийся скрипт, который устанавливает отправителя, тело получателя и т. Д.

Это не удалось. Журналы отладки выглядят так:

Net::SMTP>>> Net::SMTP(3.11)
Net::SMTP>>>   Net::Cmd(3.11)
Net::SMTP>>>     Exporter(5.73)
Net::SMTP>>>   IO::Socket::INET(1.39)
Net::SMTP>>>     IO::Socket(1.39)
Net::SMTP>>>       IO::Handle(1.39)
Net::SMTP: Net::Cmd::getline(): unexpected EOF on command channel:  at fescommon/mailsend-new.pl line 67.
Can't call method "auth" on an undefined value at fescommon/mailsend-new.pl line 74.

Примечание. Модули, такие как Net :: SMTP, Net :: SMTP :: SSL, IO :: Socket :: SSL и другие, обновлены до последней версии.

Ожидаемый результат заключается в том, что запрос на прослушивание службы «отправки» через порт 465 на SMTP-сервере может быть выполнен с использованием самого последнего модуля Net :: SMTP, без использования Net :: SMTP :: SSL (поскольку в документе утверждается)

1 Ответ

2 голосов
/ 29 марта 2019

Если вы хотите использовать smtps (то есть TLS с начала вместо TLS после команды STARTTLS), вы должны явно сказать об этом. Net :: SMTP волшебным образом не выводит это требование из номера порта. Из документации :

new ([HOST] [, OPTIONS])
SSL - Если соединение должно быть установлено с самого начала с использованием SSL, в отличие от более позднего обновления с помощью starttls. Вы можете использовать аргументы SSL, как описано в IO :: Socket :: SSL, но обычно они уже используют правильные аргументы.

Таким образом, правильный код должен быть:

$smtp = Net::SMTP->new($mailserver,
    SSL => 1,  # <<<<<<<<<<<<<<<<<<<<<<<< THIS IS IMPORTANT
    Hello => $localhostname,
    Timeout => 60,
    Port => $port,  # Port value is 465
    Debug => 1
);
...