Протокол IMAP4
O В этой главе
O Достоинства протокола IMAP4
O Основные команды
O Чтение сообщений
Протокол IMAP4 (Internet Mail Access Protocol) сильно уступает в популярности POP3, но значительно превосходит его функциональности. Однако никакого противоречия здесь нет. В отличие от POP3, IMAP4 предполагает хранение и обработку сообщений на сервере, откуда вытекает необходимость наличия постоянного канала связи. Большинство пользователей не могут позволить себе подобную роскошь, и потому IMAP4 в основном используется в локальных корпоративных сетях, где постоянная связь с сервером - не проблема.
Большинство получателей, не имеющих постоянного соединения с Internet, предпочитают не хранить почту на сервере, а забирать ее на свой локальный ящик и обрабатывать сообщения собственными клиентскими средствами.
Совсем иная ситуация складываться в локальных корпоративных сетях, где постоянная и стабильная связь с сервером - не проблема. Корреспонденция, хранящаяся на сервере, доступна всем клиентам, обладающими соответственными правами доступа, и надежно защищена (равно как и сам сервер), в то время как гарантировать целостность информации на множестве локальных машин затруднительно.
С другой стороны, в POP3-ящиках почта храниться незначительные промежутки времени, и это затрудняет ее похищение злоумышленником. Напротив же, идеология IMAP4 диктует постоянное хранение всей почты на одном сервере. И если этот сервер окажется взломан, злоумышленник получит доступ сразу ко всей корреспонденции.
Под обработкой сообщений понимается возможность растасовать корреспонденцию по множеству папок и наличие развитых функций поиска необходимого письма. Все это реализовано практически в любой почтовой программе (например, Outlook Express, The Bat), однако, при использовании протокола IMAP4 эти операции выполняются сервером, а не клиентом.
Такой подход приводит к интенсивному взаимодействию с сервером и может легко вызвать его перегрузку. Поэтому, в протоколе появились новшества, заметно оптимизирующие скорость обмена. В отличие от POP3, взаимодействие клиента с IMAP4 сервером стоится не по принципу «запрос-ответ», а происходит асинхронно. То есть можно посылать следующую команду не дожидаясь ответа на предыдущую. Порядок обработки запросов определяется сервером из соображений оптимизации скорости работы, и часто случается так, что команды обрабатываются в обратном порядке.
Что бы иметь возможность определить к какому именно запросу относится ответ сервера, в протокол были введены теги. Тег предваряет каждый запрос клиента и ответ сервера.
Обмен при этом выглядит приблизительно так:
· тег1 команда 1
· тег2 команда 2
· тег2 ответ на команду 2
· тег3 команда3
· тег1 ответ на команду 1
· тег3 ответ на команду 3
Тег представляет собой короткую символьно-цифровую строку, идентифицирующую каждую команду клиента. Ответы сервера (или очередные запросы клиента, в том случае, когда они связаны друг с другом) должны ссылаются на команду по ее тегу.
Однако чаще всего взаимодействие происходит по старому - доброму принципу «запрос-ответ». В самом деле, прежде чем посылать очередную команду, недурно бы получить ответ на предыдущий запрос. Например, читать корреспонденцию не получится до тех пор, пока сервер не выдаст список всех сообщений в почтовом ящике. Поэтому, в приведенных ниже примерах будет всегда использоваться один и тот же тег, что вполне допустимо, - как только приходит ответ сервера, использованный ранее тег, вновь становиться «свободным».
Большинство поставщиков бесплатных сетевых услуг не поддерживают протокола IMAP4. Поэтому, найти такой сервер, для многих окажется не легкой задачей. Неплохой идеей будет набрать в строке запроса поисковой системы (такой, как «Апорт») нечто вроде «IMAP4+free»
Неплохо себя зарекомендовала бесплатная служба “Mailru.com”, предоставляющая быстрый и бессбойный доступ к почтовому ящику по протоколам POP3, STMP, IMAP4.
Семьдесят три страницы убористого технического текста RFC-1730 документируют более двадцати различных команд протокола. Подробное описание IMAP4 превратило бы популярную книгу во множество скучных томов справочного руководства. В беглом обзоре этой главы будут рассмотрены лишь простейшие операции с почтовым ящиком, но вполне достаточные для чтения корреспонденции.
Для начала работы необходимо установить TCP-соединение через сто сорок третий порт.
Подключение к mail.softclub.net
Через секунду после установления соединения, на экране telnet-клиента появится приглашение следующего вида:
· OK joshua.softclub.net IMAP4rev1 v12.250 server ready
Сразу же после его выдачи сервер переходит в состояние аутентификации. Передать свое имя и пароль клиент может двумя способами: либо воспользоваться командой “login” и послать их по сети в открытом виде (как чаще всего и происходит), либо выбрать защищенный режим, воспользовавшись командой “authenticate”, которая передает шифрованный пароль. Здесь не приводится анализ уязвимости тех или иных алгоритмов шифрования паролей и их реализаций. В общем случае все они достаточно надежны, а ошибки конкретных реализаций всегда можно найти на любом сайте, посвященном сетевой безопасности.
В приведенном ниже примере для входа на сервер используется команда “login”, следом за которой идут имя и пароль пользователя, разделенные пробелом:
· kpnc login kpnc MyPassword
· kpnc OK LOGIN completed
Ответ сервера состоит из трех частей: возращенного тега “kpnc” , ключевого слова “OK”, подтверждающего успешное завершение операции (в противном случае было бы “BAD”), и осмысленной текстовой строки (“LOGIN completed”).
С момента подтверждения пароля доступ к почтовому ящику открыт. Но прежде, чем приступить к чтению поступившей корреспонденции, необходимо понять, как она храниться на сервере. Конечно же, в папках, ибо в современной компьютерной терминологии папкой называется все, способное вмещать в себя что-то еще Название и содержимое папок определяется самим пользователем, но в любой системе обязательно присутствует папка “INBOX”, в которую помещается поступающая корреспонденция.
Для выбора папки предусмотрена команда “SELECT”, использование которой продемонстрировано в следующем примере:
· kpnc SELECT INBOX
· * FLAGS (\Answered \Flagged \Draft \Deleted \Seen)
· * OK [PERMANENTFLAGS(\Answered\Flagged\Draft\Deleted\Seen \*)]
· * 1 EXISTS
· * 1 RECENT
· * OK [UNSEEN 1]
· * OK [UIDVALIDITY 954332839]
· kpnc OK [READ-WRITE] Completed
Значок звездочки указывает на неразрывность информационного потока. До тех пор, пока в начале строки не встретится возращенный тег, никто не должен вклиниваться в процесс передачи.
За ключевым словом “FLAGS” (порядок которого в ответе произволен) перечисляются все доступные флаги для сообщений данной папки. Назначение их такого:
· Answered: на сообщение был отправлен ответ
· Flagged: сообщение имеет флаг (отмечено «галочкой»)
· Draft: незавершенное сообщение (черновик)
· Deleted: сообщение помечено как удаленное, но еще физически не удалено
· Seen: сообщение уже было прочитано
· Recent: только что полученное сообщение
Следующее ключевое слово “PERMANENTFLAGS” показывает, какие флаги сообщений может менять пользователь, где знак «*» (джокер) обозначает «все флаги».
Две строки, расположенные ниже, говорят о том, что в ящике содержится всего одно письмо, которое было только что получено. «Только что» следует трактовать как «в промежутке между двумя последними сессиями».
Сообщение “UNSEEN 1” входит в перечень необязательных для реализации и подсчитывает количество непрочитанных писем. В приведенном примере имеется только одно такое письмо.
Уникальный временной идентификатор папки, следующий за “UIDVALIDITY”, может использоваться взамен ее имени и варьируется от сессии к сессии.
Последняя строка сообщает права клиента на эту папку. В данном случае доступно чтение и запись сообщений.
Следующий эксперимент демонстрирует технику чтения сообщений. В отличие от POP3, такую, казалось бы, простую операцию выполнить весьма затруднительно. Тогда как POP3 допускает лишь одну возможность - получение всего сообщения целиком, протокол IMAP4 помимо номера выбранного сообщения требует указание критерия запроса!
Полное описание синтаксиса запроса содержится в RFC-1730, с котором настоятельно рекомендуется ознакомиться, но здесь привести даже в общих чертах не представляется возможным.
Сообщение может быть прочитано различными способами, один из которых продемонстрирован ниже. Он заключается в вызове команды “FETCH” с параметрами, обсуждение которых выходит за рамки данной книги, но может быть почерпнуто из RFC-1730.
В простейшем случае для получения заголовка сообщения необходимо перейти в папку, в которой хранится это сообщение (для этого используется команда “SELECT”) и отправить серверу следующий запрос “FETCH msg BODY[HEADER]”, где “msg” порядковый номер требуемого сообщения.
Например, это может выглядеть так:
· kpnc SELECT INBOX
· kpnc FETCH 1 BODY[HEADER]
· 1 FETCH (FLAGS (\Recent \Seen) BODY[HEADER] {1032}
· Return-Path: «[email protected]»
· Received: from msk2.mail.ru (mx2.mail.ru [194.67.23.33])
· by mx1.mailru.com (8.10.0/8.10.0.Beta10) with ESMTP id e2TCbfd35173
· for «[email protected]»; Wed, 29 Mar 2000 16:37:41 +0400 (MSD)
· Received: from camel.int ([10.0.0.98] helo=camel.mail.ru)
· by msk2.mail.ru with esmtp (Exim 3.02 #116)
· id 12aHjy-0000Dk-00
· for [email protected]; Wed, 29 Mar 2000 16:38:30 +0400
· Received: from ppp-02.krintel.ru ([195.161.41.226] helo=KPNC)
· by camel.mail.ru with smtp (Exim 3.02 #107)
· id 12aHje-0002OB-00
· for [email protected]; Wed, 29 Mar 2000 16:38:12 +0400
· Message-ID: «[email protected]»
· From: =?koi8-r?B?69LJ0yDrwdPQxdLTy8k=?= «[email protected]»
· To: «[email protected]»
· Subject: Test
· Date: Wed, 29 Mar 2000 16:31:32 +0400
· MIME-Version: 1.0
· Content-Type: text/plain;
· charset="koi8-r"
· Content-Transfer-Encoding: 7bit
· X-Priority: 3
· X-MSMail-Priority: Normal
· X-Mailer: Microsoft Outlook Express 5.00.2417.2000
· X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300
·)
· kpnc OK Completed
А текст письма можно получить, воспользовавшись запросом “FETCH msg BODY[TEXT]”.
Например:
· kpnc FETCH 1 BODY[TEXT]
· 1 FETCH (BODY[TEXT] {16}
· Hello, KPNC!
·
·)
· kpnc OK Completed
Остальные команды протокола IMAP4 здесь рассматриваться не будут, но могут быть найдены в технической документации RFC-1730, RFC-2060 и RFC-2062.
Дополнение. Почтовый сервер изнутри
O В этой главе:
O Краткая история возникновения почтальона SendMail
O Архитектура SendMail
O Компоненты SendMail - User Agent, Transfer Agent, Delivery Agent
O Иерархия и взаимодействие компонентов SendMail
O Устройство и назначение Агента Пользователя
O Устройство и назначение Агента Пересылки
O Устройство и назначение Агента Доставки
O Устройство почтового ящика
O Механизм отправки писем локальным получателям
O Механизм отправки писем удаленным получателям
O Прием входящих сообщений, модель Sender - Receiver
O Аутентификация отправителя
O SMTP-соединение
O SMTP-транзакции
O Использование SMTP сервера для приема входящей почты
O Очередь отправки сообщений
O Relay-серверы
O Команды терминальной посылки, организация конференции реального времени
O Форвардинг почты
O Устройство агента POP3
«…автор, которому кажется, будто он очень ясно излагает свои мысли, не всегда бывает понятен читателям… автор идет от мысли к словам, а читатель - от слов к мысли»
Н. Шамфор
При описании почтовых протоколов в трех предыдущих главах принципы функционирования почтового сервера оказались незатронутыми и будут детально рассмотрены в этой главе. Конечно, никаких универсальных механизмов доставки, хранения и обработки корреспонденции не существует - каждый разработчик в праве реализовывать их по-своему. Поэтому, здесь будет рассмотрена лишь одна, самая популярная программа SendMail, которая установлена на подавляющем большинстве почтовых серверов. Остальные почтальоны функционируют практически по той же схеме, поэтому нет нужды рассматривать каждого из них в отдельности.
Первая версия SendMail была написана в 1980 году Эриком Аллманом (Eric Allman), студентом Калифорнийского университета в Беркли, для облегчения пересылки почты из локальной сети университета Berknet, узлам, подключенным к ARPAnet.
В качестве ядра для SendMail использовалась тщательно отлаженная программа DeliverMail (написанная в 1979 году под BSD Unix 4.0), не обладающая способностью поддержки разнородных сетей. Именно этот недостаток был устранен в SendMail. Расплатой за универсальность стала значительно возросшая сложность программы, а вместе с ней и количество допущенных ошибок. В шутку утверждается - дыр в SendMail больше, чем во всех остальных вместе взятых приложениях для UNIX.
Программа SendMail распространяется свободно вместе с исходными текстами, поэтому совершенствуется и латается многочисленными разработчиками, многие из которых адаптируют ее для собственных нужд. Найти ее можно на
Рисунок SendMail.bmp Так выглядит логотип программы SendMail
Функционально SendMail состоят из трех обособленных компонентов: User Agent (Агента Пользователя), Transfer Agent (Агента Пересылки) и Delivery Agent (Агента Доставки).
· Агент пользователя позволяет формировать сообщения для отправки и декодировать полученные послания, хранящиеся в почтовом ящике (mailbox).
· Агент Пересылки занимается приемом и пересылка корреспонденции с одной машины на другую, с учетом используемого получателем протокола связи.
· Агент Доставки управляет почтовым ящиком пользователя, помещая в него входящие сообщения.
Таким образом, SendMail представляет собой законченную почтовую систему, не требующую услуг никаких других приложений.
Рисунок 028.fig Устройство и взаимодействие двух почтальонов SendMail
Устройство почтового ящика варьируется в широких пределах, но в простейшем случае - это обычный файл, в который последовательно одно за другим записываются все входящие сообщения. В других реализациях каждое сообщение помещается в отдельный файл, но, так или иначе, почтовый ящик образно можно представить в виде именованной записи, хранящейся на сервере. Протокол POP3 (IMAP4) не единственный механизм доступа к собственной корреспонденции - с тем же успехом можно воспользоваться службами telnet, FTP, WWW и т.д.
Главное достоинство POP3 (IMAP4) - предоставление удобного унифицированного интерфейса для работы с почтовыми ящиками. В пересылке корреспонденции они никак не участвуют. Их роль значительно скромнее - доставить почту с сервера на локальный компьютер пользователя. Теоретически можно обойтись и без них - Агент Пользователя, встроенный в SendMail, замечательно справляется с задачей отображения сообщений .
При отправке письма используется следующий алгоритм: сначала SendMail пытается установить местоположение получателя. Если тот расположен на локальной машине , запускается программа “/bin/mail”, помещая сообщение в почтовый ящик пользователя. Ситуация усложняется, когда получатель находится на другом узле. Тогда SendMail по форме адреса пытается распознать используемый протокол. Так, например, встретив адрес вида host1!host2!пользователь Transfer Agent использует UUCP протокол и SMTP протокол для адреса наподобие . В крайнем случае, может быть предпринята попытка доставки письма прямым соединением по модему или другим сетям.
Агент Пересылки ведает и приемом входящих сообщений. При описании SMTP протокола, затрагивалась модель “Sender-Receiver”. В один момент времени SMTP-сервер выступает передатчиком сообщения, а в другой - приемником. Обе функции реализует Агент Пересылки, - являясь ядром почтовой системы. Другими словами, Transfer Agent представляет собой одну из возможных реализаций протокола SMTP, все остальные компоненты заняты более скромной работой «по хозяйству».
В свою очередь Агент Пересылки состоит из многочисленных модулей, из которых в первую очередь необходимо выделить механизмы поддержки авторизации и транзакций.
Первые версии SendMail, равно как и других почтовых программ, не требовали аутентификации пользователя перед отправкой почты. Никто не видел в этом особо изъяна (ведь никакого несанкционированного доступа к информации при этом не происходило ) Так продолжалось до тех пор, пока не появились первые спамеры, рассылающие по сети гигабайты бесполезного хлама. Непременным условиям их существования были, есть и останутся общедоступные сервера исходящей почты. Поэтому, понадобились технические средства, способные блокировать неугодных пользователей.
На первый взгляд ничего сложного в этом нет. Достаточно, например, запрашивать пароль при входе на сервер, но… это потребовало бы переделки всего клиентского программного обеспечения. Поэтому, было решено использовать в качестве пароля IP-адрес клиента. К сожалению, в большинстве случаев провайдеры предоставляют абонентам, так называемый, динамический IP адрес, который может выдаваться множеству лиц и в качестве уникального идентификатора личности не подходит. Тогда предложили следующий механизм, - сначала пользователь должен подключится к POP3 серверу и ввести свое имя и пароль . После успешного завершения операции определяется IP адрес клиента и передается SMTP-серверу. В течение некоторого промежутка времени , SMTP-сервер открывает вход для пользователя, обладающего данным IP адресом. Недостатки такого решения - слабая защищенность и определенные неудобства при отправке почты - так, например, “Outlook Express” в первую очередь пытается выполнить отправку исходящей почты, и только потом проверяет почтовый ящик.
Процесс отправки почты с помощью Outlook, на сервер требующий авторизации отправителя, выглядит так, - при первой попытке отправки письма SMTP сервер возвращает ошибку, рекомендуя сначала «засветиться» по POP3. Щелчок мыши по кнопке «доставить почту» приводит к повторной попытке зайти на SMTP сервер, которая точно так же будет отвергнута. После этого Outlook заходит на POP3 сервер, где и оставляет требуемый IP адрес. Второй щелчок мыши «доставить почту» наконец-то приводит к желаемому результату, но, сколько же лишних операций для этого пришлось сделать!
Некоторые сервера всего лишь проверяют обратный адрес клиента, сообщаемый им командой “MAIL FROM”. Разумеется, ничего не стоит передать поддельные данные, послав письмо от имени другого человека. Для этого достаточно знать имя хотя бы одного пользователя, зарегистрированного на сервере.
Поэтому, современные почтовые серверы оснащены собственными механизмами аутентификации, требующими явной передачи имени и пароля.
К сожалению, аутентификацию отправителя поддерживают далеко не все почтовые клиенты, к числу которых относятся все версии Outlook, младше пятой.
Outlook 5.0 и выше обеспечивают проверку подлинности пользователя - для этого достаточно взвести соответствующую галочку в настойках «Серверы»
Рисунок 029 Аутентификация отправителя
Поддержка SMTP-транзакции опирается на SMTP-соединение и включает в себя три шага. Это открытие транзакции (совершаемое командой «MAIL FROM»), определение адресов доставки (задаваемое серией команд «RCPT TO») и передачи текста сообщения (инициируемое командой «DATA»). Последовательность «перенос строки», «точка», «перенос строки» завершает транзакцию. Подробно этот процесс описан в главе «Протокол SMTP», но некоторые нюансы остались «за кадром» и будут рассмотрены ниже.
«Транзакция» переводится на русский язык как «групповая операция», - и в данном случае обозначает возможность отправки одного сообщения по множеству (группе) адресов. Открытие транзакции заставляет получателя очистить все старые таблицы и буферы данных для приема нового сообщения. Затем последовательными вызовами «RCPT TO» перечисляются адреса назначения. При этом возможны следующие ситуации, - если получатель находится на узле SMTP-сервера, письмо будет просто опущено в его почтовый ящик, в противном же случае поведение Агента Пересылки будет зависеть от настроек, установленных администратором. Во многих случаях рассылка корреспонденции за пределы локальной машины запрещена, - сервер действует только на прием. Именно такая конфигурация и называется в просторечии «почтовым ящиком пользователя». Так, например, сканирование портов сервера mail.computerra.ru, указывает на открытый двадцать пятый порт (т.е. SMTP сервер установлен).
Рисунок 30.gif Сканирование портов сервера mail.computerra.ru
Но попытка использовать mail.computerra.ru в качестве сервера исходящей почты в своем почтовом клиенте ни к чему не приведет, - сервер откажется отправлять сообщения. На самом деле он может их отправлять, но только на локальные адреса - такие, которые выглядят как . То есть полноценный SMTP сервер используется исключительно для приема входящей почты. Так называемые в обиходе сервера исходящей почты отличаются от него всего лишь одной строкой конфигурационного файла, разрешающей пересылку за пределы локальной машины.
С этим связан частый вопрос пользователя «почему я не могу отправлять сообщения через mail.ru - сервер ругается и отвергает получателя». На самом деле на mail.ru установлено два SMTP сервера - один по адресу mail.ru, допускающий рассылку только в пределах mail.ru; другой же находится на smtp.mail.ru - вот он-то и нужен большинству пользователей.
При этом опять-таки возможны варианты, - если адрес получателя и протокол опознан сервером, он пытается отправить письмо по назначению, в противном случае предлагает сделать это клиенту самостоятельно . Наконец, адрес получателя может быть задан некорректно или вовсе отсутствовать, о чем SMTP сервер незамедлительно уведомит отправителя. Однако ошибка указания одного или нескольких получателей не разрывает SMTP-транзакцию и никак не влияет на остальные команды “RCPT TO”.
Если возникает необходимость разорвать текущую транзакцию и перезагрузить SMTP-соединение, используют команду «RSET», вызываемую без аргументов . Буфера отправителя и получателя данной транзакции окажутся очищенными и отправку письма придется начинать сначала.
Агент Пересылки добавит исходящее сообщение в очередь отправки, чаще всего расположенную в файле «/var/spool/mqueue», и в порядке «социалистической очереди» будет пытаться доставить письма получателям. Если по каким-то причинам, например, отсутствию связи с сервером, сообщение не удастся отправить в течение нескольких часов, отправителю будет передано уведомление, и, по прошествии определенного количества попыток, SendMail возвратит письмо отправителю и удалит его из очереди.
В некоторых случаях задача доставки корреспонденции по назначению ложится на специализированные сервера, называемые Релеями (от английского relay), затронутые в главе «Протокол SMTP». В общих чертах они идентичны обычным SMTP-серверам и часто реализуются на базе SendMail. Практически единственное существенное отличие relay-серверов заключается в пропускной способности канала, соединяющего их с Internet, - он должен быть рассчитан на интенсивную рассылку корреспонденции.
Описанными выше возможностями должен обладать любой Агент Пересылки, отвечающий стандартам RFC. Но помимо базовых функций существует набор команд необязательных для реализации, среди которых порой попадаются удивительно полезные и любопытные.
Так, например, с помощью электронной почты несложно организовать конференцию для общения в реальном времени . Для этого достаточно воспользоваться командами, пересылающими письма на удаленный терминал, а не в почтовый ящик. В первых версиях DeliverMail существовала возможность задать адрес получателя в виде “host/dev/con”, но из соображений безопасности это было исправлено, однако такая идея понравилась разработчикам и получила дальнейшее развитие.
Сегодня же эта «вкусность» почтовых серверов практически забыта и представляет лишь исторический интерес. Для демонстрационного эксперимента потребуется терминал, работающий под управлением UNIX и почтовый сервер, поддерживающий передачу писем на терминал .
Команда “SEND FROM”, использующаяся вместо “MAIL FROM”, отправляет сообщение на консоль получателя. Если же получатель окажется неактивным - письмо будет утеряно без каких-либо уведомлений, поэтому рекомендуется использовать команду “SOML FROM” (Send Or Mail), которая автоматически помещает сообщение в ящик, если терминал пользователя неактивен. Команда “SAML FROM” (Send And Mail) отправляет сообщение на терминал и, независимо от успешности операции, направляет его копию в почтовый ящик получателя.
Для ответа респонденту не требуется разрыва SMTP-соединения - достаточно отправителю и получателю поменяться местами, воспользовавшись командой “TURN”, вызываемой без аргументов.
Такой способ общения имеет свои недостатки, но все же временами бывает достаточно удобен, расширяя базовые возможности электронной почты. К сожалению, SendMail не поддерживает команд «SEND FROM», «SOML FROM», «SAML FROM» и, поэтому, придется искать другой почтовый сервер.
Довольно часто на почтовых серверах случаются перебои, и доступ к почтовому ящику на время устранения неполадок становится недоступным, а иногда даже теряется его содержимое. Вот если бы отправитель направлял почту на несколько адресов сразу! Бытует мнение якобы достичь этого штатными средствами невозможно. На самом деле приемлемое решение проблемы достигается внесением всего одной стоки в конфигурационный файл “.forward”, расположенный в домашнем каталоге пользователя.
Например:
\kpnc, ,
В этом случае, SendMail будет дублировать всю входящую корреспонденцию по двум указанным адресам и кроме этого, помещать в почтовый ящик пользователя, расположенный в каталоге “/var/mail/kpnc” . Если же подстроку “\kpnc” удалить, почта не будет сохраняться на сервере . Аналогичного результата можно добиться перечислением требуемых адресов в файле aliases.
Значительно проще устроен POP3 Agent. В большинстве случаев его реализация полностью умещается в нескольких сотнях строк языка Си или Perl . Этого оказывается вполне достаточно для поддержки десяти базовых команд протокола POP3 (USER, PASS, QUIT, STAT, LIST, RETR, DELE, NOOP, LAST, RSET - подробнее каждой из них рассказывается в главе «Протокол POP3»).
Получение почты происходит в три стадии. На первом этапе выполняется авторизация - проверка имени и пароля пользователя. В простеющем случае они передаются по сети в открытом виде, но в последнее время из соображений безопасности стали прибегать к различным алгоритмам шифрования. Если проверка пароля прошла успешно, агент открывает транзакцию и предоставляет доступ к почтовому ящику. На стадии обновления транзакции уничтожаются все сообщения, отмеченные пользователем для удаления. В большинстве случаев для манипуляций с ящиком Агент POP3 прибегает к услугам Агента Пользователя SendMail или другого почтальона, установленного в системе. Таким образом, в POP3 сервере не остается ничего таинственного.
Врезка «информация»
Агенты POP3 крайне непопулярны в среде UNIX. Так, например, в стандартной поставке SPARC под Solaris никакого агента POP3 вообще нет и желающие установить его на свою систему вынуждены делать это самостоятельно - благо исходные тексты программ, реализующих этот протокол, широко распространены в сети.
Дополнение. Анонимная рассылка корреспонденции
O В этой главе:
O Создание скрипта, отправляющего сообщения
O Обеспечение анонимности отправителя письма
O Фальсификация заголовков сообщения
Большинство SMTP-серверов определяют IP-адрес отправителя сообщения и вставляют его в заголовок. Конечно, IP-адрес это еще не сам отправитель (которого пойди найди), но иногда возникает необходимость остаться полностью анонимным.
В Сети существует множество служб, предоставляющих услуги подобного рода (например, proxy-серверы, анонимайзеры), но анонимайзеры явно указывают на желание отправителя остаться неизвестным, а по поводу анонимности некоторых proxy-серверов многих терзают смутные сомнения.
Одно из возможных решений проблемы заключается использование программы пересылкой писем, размещенной на удаленном сервере. Выбор сервера, подключенного к быстрому Internet-каналу, упросит массовую рассылку корреспонденции.
Часто начинающие вредители не могут придумать ничего оригинальнее, чем заставлять сервер с помощью скрипта получать самый свежий дистрибьютив бета-версии Windows 2000 и посылать его на ящик жертвы в немерянных количествах.
Куда привлекательнее выглядит попытка принудительного приобщения атакуемого к миру прекрасного, например, ознакомление его с космическими исследованиями NASA (для чего используются фотографии, доступные на сайте )
Ниже приведена одна из возможных реализаций такой программе, написанной на языке Perl (на диске, прилагаемом к книге, она находится в файле “/SRC/smtp.pl”). Подробное объяснение ее работы выходит за рамки данной книги, однако, структура программы достаточна проста, чтобы в ней мог разобраться даже неподготовленный читатель.
· use Socket;
· my($mailFrom) = '[email protected]';
· my($MailTo) = '[email protected]';
·
· socket(SMTP, PF_INET(), SOCK_STREAM(), 6);
· connect(SMTP,sockaddr_in(25,inet_aton("mail.aport.ru")));
·
· recv(SMTP, $buffer, 200, 0);
· print "$buffer\n";
·
· send(SMTP, "HELO kpnc\n",0);
· print "»HELO\n";
·
· my($buffer) = @_;
· recv(SMTP, $buffer, 200, 0);
· print "$buffer\n";
·
· send(SMTP, "MAIL FROM: «$mailFrom»\n",0);
· print "»MAIL FROM:«$mailFrom»\n";
· recv(SMTP, $buffer, 200, 0);
· print "$buffer\n";
·
· send(SMTP, "RCPT TO: «$MailTo»\n",0);
· print "»RCPT TO: «$MailTo»\n";
· recv(SMTP, $buffer, 200, 0);
· print "$buffer\n";
·
· send(SMTP, "DATA\n",0);
· print "»DATA\n";
· recv(SMTP, $buffer, 200, 0);
· print "$buffer\n";
·
· send(SMTP, "From: Kris Kaspersky\n", 0);
· print "»From: Kris Kaspersky";
· print "«BR»\n\n";
·
· send(SMTP, "Subject: Test\n", 0);
· print "»Subject: Test\n";
·
· send(SMTP, "Hello, KPNC!\n", 0);
· print "»Hello, KPNC!\n";
·
· send(SMTP, "\r\n.\r\n",0);
· print "\r\n.\r\n";
· recv(SMTP, $buffer, 200, 0);
· print "$buffer\n";
·
· send(SMTP, "QUIT\n",0);
· print "»QUIT\n";
· recv(SMTP, $buffer, 200, 0);
· print "$buffer\n";
·
· close(SMTP);
Приведенный пример позволяет отослать только одно письмо по указанному адресу. На самом же деле, если программа может отправить одно письмо, то сумеет и десять, стоит только дополнить ее циклом .
Автор умышленно не привел законченного примера, оставляя читателю свободное пространство для творчества. В противном случае слишком велик был бы соблазн забросить книгу на полку и использовать содержащиеся на диске программные реализации атак, совершенно не интересуясь механизмом их работы.
Скрипт необходимо разместить на сервере, который поддерживает удаленное выполнение программ, разрешает telnet-вход, имеет в наличие интерпретатор Perl и допускает установку соединений с другими узлами сети. Перечисленным требованиям удовлетворяет, например, hobbiton.org и некоторые другие бесплатные сервера.
Для размещения файла скрипта на сервере лучше всего воспользоваться ftp-протоколом, а запустить его из telnet-сессии проще всего так: “perl имяфайла.pl”. (Для запуска скрипта по протоколу HTTP его придется несколько модифицировать, о том, как это сделать рассказано в главе «Протокол HTTP»). После завершения работы скрипта экран должен выглядеть приблизительно так:
Рисунок 31 Демонстрация работы скрипта, посылающего письмо
Для облегчения понимания этот пример не имеет никаких изменяемых настоек и все данные прописаны непосредственно в теле программы. Однако это не законченная программа, а всего лишь макет, демонстрирующий принципиальную возможность анонимной отправки корреспонденции.
Заголовок письма, доставленного на “
[email protected]” (или по любому другому адресу) должен выглядеть приблизительно так:
· Received: from hobbiton.org ([216.161.239.42] helo=kpnc)
· by hearst.mail.ru with smtp (Exim 3.14 #3)
· id 12yrfs-000KGD-00
· From: Kris Kaspersky
· Subject: Test
· Date: Mon, 05 Jun 2000 11:51:53 +0400
В заголовке содержится IP-адрес сервера, выполнившего скрипт, но нет никакой информации об отправителе (за исключением данных, которые он пожелал оставить сам). Таким образом, можно построить собственный анонимайзер, позволяющий его создателю (а, возможно, и другим пользователям) рассылать анонимные сообщения.
Подобные услуги предоставляют сотни поставщиков в сети, но не все анонимайзеры действительно надежны. Лучше всего пользоваться программным обеспечением собственного написания, в котором можно гарантировать отсутствие «закладок», а поведение чужого ресурса временами бывает непредсказуемо .
Однако технически возможно фиксировать IP-адреса всех пользователей, подключившихся к hobbiton.org и запустивших скрипт рассылки на выполнение. Поэтому, отправителю, желающему остаться абсолютно неизвестным, необходимо найти такой сервер, который бы не вел никаких протоколов . Или можно задействовать несколько десятков узлов, последовательно пересылая скрипт (или команду на его выполнение) от машины к машине. Если хотя бы один из узлов этой цепочки не регистрирует всех подключений, то установить отправителя будет невозможно. Некоторые приемы позволяют подделать содержимое IP-заголовка. Но, поскольку такая операция требует весьма высокой квалификации, к ней обычно не прибегают.
Кроме сокрытия анонимности отправителя, скрипт может использоваться для фальсификации (или уничтожения) заголовков писем. Например, можно создать видимость, что сервер, отправивший письмо, всего лишь транзитный узел пересылки, а «настоящий» отправитель находится совсем - совсем в другом месте.
Для этого достаточно вставить в заголовок одно (или несколько) полей «Received», например, так “Received: from mail.pets.ja” . Модифицированный вариант smtp.pl находится на прилагаемом к книге диске под именем smtp1.pl, и от оригинального файла отличается следующими строками:
· send(SMTP, "Received: from mail.pets.ja\n", 0);
· print "»Received: from mail.pets.ja";
Заголовок письма, отправленного с его помощью, должен выглядеть приблизительно так:
· Received: from [209.143.154.93] (helo=kpnc)
· by camel.mail.ru with smtp (Exim 3.02 #107)
· id 12d6EL-000NmZ-00
· Received: from mail.pets.ja
· From: Kris Kaspersky
· Subject: Test
· Bcc:
· Date: Thu, 06 Apr 2000 10:57:30 +0400
Получатель, скорее всего, решит, что письмо пришло с сервера mail.pets.ja, и вряд ли обратит внимание на ретрансляторы. Выявление истинного получателя можно значительно затруднить, если не класть письмо непосредственно в почтовый ящик клиента, а переслать его через несколько транзитных серверов. В этом помогут возможности управления маршрутизацией доставки сообщения, поддерживаемые SMTP-протоколом. Если задействовать несколько десятков узлов и вставить в письмо несколько десятков подложных строк “Received”, то установить истинного отправителя сообщения станет практически невозможно, вернее сказать, нецелесообразно.
Однако грубая подделка заголовка облегчает выявление фальсифицированных полей. Основные ошибки, по которым легко узнается подлог, следующие: указанных адресов серверов вообще не существует в природе; стиль заполнения сервером поля “Received” отличается от используемого злоумышленником; реальное время пересылки писем сервером на порядок ниже (или выше), чем это следует из заголовка письма.
Поэтому, мало иметь образцы заполнения “Received” каждым из узлов - необходимо выяснить средние задержки в доставке сообщений. Еще более сложно разобраться с алгоритмом генерации идентификаторов, добавляемых большинством транзитных серверов к заголовку письма для избежания его зацикливания. Такой идентификатор уникален для каждого сервера и не может представлять абсолютно случайное значение, поскольку, в тогда бы существовала возможность повторной выдачи одного и того же идентификатора, что недопустимо.
Обеспечить уникальность помогает привязка ко времени пересылки письма. Некоторые алгоритмы генерации идентификатора позволяют его обратить и узнать время, когда он был выдан. Это позволяет выявить поддельные идентификаторы, а вместе с ними и поддельные поля в заголовке письма.
Причем по «внешнему виду» идентификатора трудно (невозможно) сказать каким образом он был получен. Для этого необходимо изучить исходные тексты сервера (если они доступны) или дизассемблировать машинный код (если исходные тексты вне досягаемости). В следующем заголовке приведены примеры двух идентификаторов. Разумеется, визуально ничего нельзя сказать о том, как они были получены:
· Received: from lists.securityfocus.com ([207.126.127.68])
· by hearst.mail.ru with esmtp (Exim 3.14 #4)
· id 13WRh6-000LBx-00; Wed, 06 Sep 2000 02:59:57 +0400
· Received: from lists.securityfocus.com (lists.securityfocus.com [207.126.127.68])
· by lists.securityfocus.com (Postfix) with ESMTP
· id E62DC1EF74; Tue, 5 Sep 2000 15:58:34 -0700 (PDT)
· Received: from LISTS.SECURITYFOCUS.COM by LISTS.SECURITYFOCUS.COM
· (LISTSERV-TCP/IP release 1.8d) with spool id 13121453 for
Впрочем, маловероятно, чтобы получатель обладал квалификацией, достаточной для проведения анализа подобного уровня. И большинство пользователей можно ввести в заблуждение даже грубой подделкой заголовка.
Дополнение. Анонимное получение корреспонденции
Не имейте никаких иллюзий насчет денег. Их нельзя есть. Их нельзя носить на себе. Единственное, что можно делать с деньгами - это их тратить. Именно для этого они и предназначены.
Эрл Стенли Гарднер «дело об удачливом проигравшем»
При получении почты обычным способом сервер определяет (а некоторых случаях и запоминает) IP-адрес подключившегося клиента. Но иногда получателю нежелательно раскрывать свой адрес, даже если он динамический. Провайдер, выделяя абоненту IP, запоминает (может запоминать) время, в которое он был выдан и имя пользователя, которому он был выдан. Поэтому, существует возможность установить личность получателя письма.
Для сохранения анонимности можно воспользоваться специально разработанным скриптом, который читает корреспонденцию и выкладывает ее на какой-нибудь анонимный ftp-сервер. Это позволяет убить сразу двух зайцев - скрыть собственный адрес и обойти один из недостатков POP3 протокола - отсутствие докачки.
В самом деле, если в ящике лежит сообщение огромных размеров, а связь то и дело рвется, может потребоваться немалое количество попыток, пока, наконец, письмо не попадет на локальный компьютер. Напротив, скрипт, выполняющийся на сервере с быстрым каналом, выполнит ту же операцию за значительно меньшее время, и, выложив сообщение на ftp, значительно облегчит клиенту получение письма, поскольку, теперь отпадет необходимость начинать процесс перекачки с самого начала после каждого разрыва соединения.
В приведенном ниже примере в качестве альтернативы Perl использован язык Python,основные достоинства которого - простота и огромное количество всевозможных библиотек, поставляемых вместе с языком. Ниже будет продемонстрировано использование одной из них.
Библиотека poplib скрывает от пользователя механизмы взаимодействия клиента с POP3-сервером, однако, значительно упрощает процесс программирования. Минимально функциональная программа, читающая все письма, поступившие к этому моменту в почтовый ящик, может выглядеть так (на диске, прилагаемом к книге, он находится в файле “/src/pop.py”):
· #!/usr/local/bin/python
· import poplib
· print "Python’s Mail client"
· print "Connecting…"
· M = poplib.POP3("mail.ru")
· print "Login…"
· M.user("MyLogin")
· print "Password…"
· M.pass_("MyUnpublishedPassword")
· print "Get List of message"
· numMessages = len(M.list()[1])
· print "Numers of message: ",numMessages
· for i in range(numMessages):
· for j in M.retr(i+1)[1]:
· print j
Вероятно, единственной проблемой окажется поиск сервера с установленным интерпретатором Python. Малая распространенность этого языка затрудняет его использование злоумышленниками, которым пришлось бы либо обзавестись собственным сервером, либо получить права администратора для удаленной установки Python.