Дмитрий Сергеевич (axshavan) wrote,
Дмитрий Сергеевич
axshavan

Categories:

SMTP

Немного хочу рассказать про SMTP. Это простой протокол передачи почты. Хотя я бы сказал, что это протокол отправки почты, получать почту с помощью SMTP вряд ли возможно. И он действительно простой! Он высокоуровневый потому что. Возьмём консоль и telnet. Для удобства я выделил жирным то, что ввожу я.
axshavan@note:~$ telnet smtp.yandex.ru 25
Trying 77.88.21.38...
Connected to smtp.yandex.ru.
Escape character is '^]'.
220 smtp3.yandex.ru ESMTP Yandex
helo axshavan
250 smtp3.yandex.ru
mail from: <moyapochta@yandex.ru>
554 5.7.1 <moyapochta@yandex.ru>: Sender address rejected: Access denied
quit
221 2.0.0 Bye
А, ну правильно. Авторизоваться надо.

Итак, после соединения smtp-сервер говорит "220 это я, и ещё я поддерживаю расширенный smtp". Я здороваюсь с сервером командой HELO. Сервер отвечает кодом 250. Код 250 - это значит, что всё в порядке, сервер ждёт команду. Я пишу MAIL FROM: <адрес отправителя>, но сервер меня заворачивает с кодом 554, который означает "transaction failed". Хотя, по идее, он должен был ответить кодом 535 и подписать, что надо авторизоваться. Потом я с ним распрощался командой QUIT.
Теперь покажу как авторизовываться.
axshavan@note:~$ telnet smtp.yandex.ru 25
Trying 93.158.134.38...
Connected to smtp.yandex.ru.
Escape character is '^]'.
220 smtp7.yandex.ru ESMTP Yandex
ehlo axshavan
250-smtp7.yandex.ru
250-PIPELINING
250-SIZE 40960000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH LOGIN PLAIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
auth login
334 VXNlcm5hbWU6
bW95YXBvY2h0YUB5YW5kZXgucnU=
334 UGFzc3dvcmQ6
0YfRgtC+LCDQsdC70Y/RgtGMLCDRgdCw0LzRi9C5INGF0LjRgtGA0YvQuT8gOik=
235 2.7.0 Authentication successful
mail from: <moyapochta@yandex.ru>
250 2.1.0 Ok
rcpt to: <moyapochta@yandex.ru>
250 2.1.5 Ok
data
354 End data with <CR><LF>.<CR><LF>
Привет, Дмитрий Сергеевич :)
.
250 2.0.0 Ok: queued as ACF1E1CF8156
quit
221 2.0.0 Bye
Connection closed by foreign host.
Смотрите, что тут происходит. Я здороваюсь с сервером командой EHLO, то есть, по-русски, не "привет", а "епривт", показывая тем самым, что хочу использовать расширения протокола SMTP. И сервер мне сразу показывает, какие он поддерживает. Обратите внимание, что он везде ставит 250 и дефис, кроме как в последней строчке, перед DSN. Это важное замечание, так как вы можете ориентироваться на этот дефис при чтении, если вы используете блокирующие сокеты, чтоб не ждать несколько минут, пока сервер отвалится по таймауту. Меня интересует строка, где сервер пишет AUTH LOGIN PLAIN - это означает, что он поддерживает авторизацию двух типов: PLAIN и LOGIN. LOGIN - самый простой способ, но всё равно, для того, чтоб с его помощью авторизоваться, надо уметь читать и писать строки, закодированные в формате base64. Я таким даром не обладаю, поэтому заранее себе заготовил закодированные таким образом логин и пароль.

И вот я пишу: AUTH LOGIN, поясняя тем самым, что хочу авторизоваться методом LOGIN. Сервер говорит: "334 VXNlcm5hbWU6", значит, ждёт логин. Я логин быстренько копипастю и ввожу, и сервер говорит: "334 UGFzc3dvcmQ6" - хочет пароль. Эта белиберда после кодов ответа 334 суть слова "Username:" и "Password:", закодированные в base64, так как по правилам общение во время авторизации должно обязательно идти в закодированных в base64 строках. Кстати, года 4 назад я столкнулся с сервером, который давал всего пару секунд на ввод логина и пароля, то есть, фактически, запрещал отправку письма вручную. Яндекс же не парится по этому поводу и позволяет успеть туда-сюда альттабнуться и скопипастить всё. Логин и пароль я ввёл правильно, о чём мне сообщает сервер.

Дальше самое основное. "MAIL FROM:" - от кого письмо. Почтовый адрес в треугольных скобочках писать вроде бы принято, но сервер может проглотить и без оных. "RCPT TO:" - recipient to, кому письмо. И один адрес. Если надо отправить письмо нескольким разным адресатам, надо вводить несколько команд RCPT TO, по одному на адрес. Сервер обязан принимать до 100 адресов вроде бы. Что касается скрытой копии (BCC - blind carbon copy), то это не часть команд SMTP, а часть письма. То есть в начале письма надо написать хеадер "Bcc: <email@example.com>", как-то так. По идее, smtp-сервера вообще не должны указывать весь список адресатов в хедерах письма, но не обязаны, и поэтому даже рекомендуется для пущей секретности посылать отдельные письма адресатам, которые в BCC.

Потом пишу DATA, и сервер отвечает кодом 354, подтверждая готовность принять тело письма. Так как в теле письма могут попадаться сочетания символов, совпадающие с командами SMTP, то решили, чтоб не путаться, сделать так: считать всё вводимое телом письма до тех пор, пока не будет введена стоящая на отдельной строке точка. Эта самая стоящая на отдельной строке точка считается концом письма, о чём сервер мне напоминает.

О том, как посылать в теле письма прикреплённые файлы, я, пожалуй, рассказывать не стану, уж больно притомился, печатая.

P.S. RTFM RFC 5321
Tags: web
Subscribe

Recent Posts from This Journal

  • Размышления про материалы

    Восседая на троне в специальной комнате, я призадумался о свойствах туалетной бумаги и о том, чем можно её заменить. Очень часто бывает, знаете, что…

  • Dracula

    Вчера вечером наконец-то дочитал до конца «Дракулу» на английском. Правильнее будет сказать «продрался до конца». Чтоб я да ещё да какую-нибудь…

  • Завтрак

    С каждой годовщиной ведения своего ЖЖ я к посту со статистическими данными обычно добавляю подборку ссылок на мои посты за прошедший год, которые…

  • Post a new comment

    Error

    Comments allowed for friends only

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 2 comments