Манипулирование заголовками From и To

manipulirovanie zagolovkami from i to Сценарии на стороне клиента

Первым письмом здесь было то, которое мы послали с фиктивным адресом отправителя. Вторым было более легитимное сообщение. Как и в адресах отправителя, в строках заголовков SMTP также допускает некоторый произвол. Сценарий smtpmail автоматически добавляет строки заголовков «From» и «To» в текст сообщения с теми адресами, которые были переданы интерфейсу SMTP, но только в порядке жеста вежливости. Иногда, однако, нельзя узнать даже, кому было послано письмо — чтобы скрыть круг получателей или поддержать законные списки адресов, отправители могут манипулировать этими заголовками в тексте сообщения.

Например, если изменить сценарий smtpmail так, чтобы он не создавал автоматически строку заголовка «To:» с теми же адресами, которые передаются вызову интерфейса SMTP:

text = (‘From: %s\nDate: %s\nSubject: %s\n’ % (From, Date, Subj))

можно будет вручную ввести заголовок «To:», отличающийся от настоящего адреса получателя — методу отправки модуля smtplib будет передаваться действительный список адресатов, а строка заголовка «To:» в тексте сообщения — это то, что будут отображать большинство почтовых клиентов (в сценарии smtpmail-noTo.py в дереве примеров приводится реализация поддержки такого анонимного поведения, и не забудьте ввести пустую строку после ввода строки заголовка «To:»):

C:\\PP4E\Internet\Email> smtpmail-noTo.py

From? Eric.the.Half.a.Bee@aol.com

To? PP4E@learning-python.com

Subj? a b c d e f g

Type message text, end with line=(ctrl + D or Z)

To: nobody.in.particular@marketing.com

Spam; Spam and eggs; Spam, spam, and spam.

"Z

ConnectingNo errors.

Bye.

В некоторых отношениях адреса «From» и «To» в вызове метода отправки и в заголовках сообщения аналогичны адресу на конверте и письму в конверте. Первое используется для пересылки, а второе представляет то, что видит читатель. Здесь оба адреса «From» являются фиктивными. Кроме того, я указал действительный адрес «To», но в строке заголовка «To:» я вручную ввел фиктивное имя — первый адрес определяет действительное место доставки сообщения, а второй отображается клиентами электронной почты. Если ваш клиент отображает строку «To:», такое письмо при просмотре будет выглядеть немного странным.

Например, если посмотреть, как отображается письмо, которое мы только что отправили, в моем почтовом ящике на сайте learning-python.com, то будет очень сложно сказать, кем и кому было отправлено это письмо, в том веб-интерфейсе, который предоставляет мой интернет-провайдер, как показано на рис. 13.5.

Рис. 13.5 Анонимное письмо в клиенте с веб-интерфейсом (смотрите также пример PyMailGUI далее)

 

Кроме того, и необработанный текст сообщения не поможет нам в этом, разве только внимательнее посмотреть на заголовки «Received:», добавляемые серверами, через которые пересылалось письмо:

C:\\PP4E\Internet\Email> popmail.py

Password for pop.secureserver.net?

Connecting

b’+OK <4802.1273156821@p3plpop03-03.prod.phx3.secureserver.net>’

There are 5 mail messages in 6364 bytes

(b’+OK ‘, [b’1 1860′, b’2 1408′, b’3 1049′, b’4 1009′, b’5 1038′], 40)

————————————————————————

[Press Enter key]

…первые три письма опущены…

Received: (qmail 30325 invoked from network); 6 May 2010 14:33:45 -0000

Received: from unknown (HELO p3pismtp01-004.prod.phx3.secureserver.net) ([10.6.1 (envelope-sender <Eric.the.Half.a.Bee@aol.com>) by p3plsmtp06-03.prod.phx3.secureserver.net (qmail-1.03) with SMTP for <PP4E@learning-python.com>; 6 May 2010 14:33:45 -0000

…часть строк опущена…

Received: from [66.194.109.3] by smtp.mailmt.com (ArGoSoft Mail

Server .NET v.1.

for <PP4E@learning-python.com>; Thu, 06 May 2010 10:33:16 -0400

From: Eric.the.Half.a.Bee@aol.com

Date: Thu, 06 May 2010 14:32:32 -0000

Subject: a b c d e f g

To: nobody.in.particular@marketing.com

Message-ID: <66koqg66e0q1c8hl06052010103316@SMTP>

X-FromIP: 66.194.109.3

X-Nonspam: None

Spam; Spam and eggs; Spam, spam, and spam.

Bye.

Еще раз повторю — не делайте так без веских причин. Я показываю это только с целью помочь вам понять, какую роль играют заголовки письма в процессе обработки электронной почты. Чтобы написать автоматический спам-фильтр, удаляющий нежелательную входящую почту, например, вам потребуется изучить контрольные признаки и научиться отыскивать их в тексте сообщения. Приемы, применяемые при рассылке спама, становятся все более изощренными, и по сложности давно превзошли простую подделку адресов отправителя и получателя (более подробную информацию по этой теме вы найдете в Интернете в целом и в почтовом фильтре SpamBayes, написанном на языке Python), но это одна из наиболее распространенных хитростей.

Кроме того, фокусы с адресами «To» могут оказаться полезными в контексте законных списков рассылки — при просмотре сообщения в заголовке «To:» выводится название списка, а не список потенциально большого количества получателей, указанных в вызове метода отправки сообщения. Как будет показано в следующем разделе, почтовый клиент легко может отправить сообщение всем получателям в списке, но вставить общее название списка в заголовок «To:».

Но в других ситуациях отправка электронной почты с фальшивыми строками «From:» и «To:» эквивалентна анонимным телефонным звонкам. Большинство почтовых программ не позволяет изменить строку «From» и не делает отличия между адресом получателя и строкой заголовка «To», хотя SMTP широко открыт в этом отношении.

В предыдущей версии сценария smtpmail, представленной в примере 13.19, в заголовок «Date» записывалось текущее время и дата в простом формате, который не совсем соответствует стандарту форматирования даты в SMTP:

>>> import time

>>> time.asctime()

‘Wed May 05 17:52:05 2010′

Большинство серверов не обращают внимания на этот заголовок и позволяют вставлять в него любой текст с датой или даже могут сами добавлять его при необходимости. Клиенты тоже часто проявляют подобную беззаботность, но не всегда. Одна из программ с веб-интерфейсом, предоставляемая моим интернет-провайдером, корректно отображает даты в любом случае, но другая оставляет такие неправильно отформатированные значения пустыми при отображении. При желании как можно точнее соответствовать стандартам вы можете форматировать заголовок с датой с помощью следующего программного кода (результат которого может быть проанализирован любыми стандартными инструментами, такими как функция time.strptime):

import time

gmt = time.gmtime(time.time())

fmt = ‘%a, %d %b %Y %H:%M:%S GMT’

str = time.strftime(fmt, gmt) hdr = ‘Date: ‘ + str print(hdr)

После выполнения этого фрагмента значение переменной hdr будет иметь следующий вид:

Date: Wed, 05 May 2010 21:49:32 GMT

Функция time.strftime позволяет формировать строку с датой и временем в любом формате; функция time.asctime реализует единственный стандартный формат. Еще лучше использовать тот же прием, который используется в сценарии smtpmail, — в современном пакете email (описывается далее в этой главе) имеется модуль email.utils, который предоставляет функции для корректного форматирования даты и времени. Сценарий smtpmail использует первый из следующих вариантов форматирования:

>>> import email.utils

>>> email.utils.formatdate()

‘Wed, 05 May 2010 21:54:28 -0000′

>>> email.utils.formatdate(localtime=True)

‘Wed, 05 May 2010 17:54:52 -0400′

>>> email.utils.formatdate(usegmt=True)

Wed, 05 May 2010 21:55:22 GMT

Смотрите описание примеров pymail и mailtools в этой главе, где вы увидите дополнительные способы использования. Последний повторно используется в крупных почтовых клиентах PyMailGUI и PyMailCGI, представленных далее в этой книге.

Использованная литература:

Марк Лутц — Программирование на Python, 4-е издание, II том, 2011

Каталог сайтов Всего.ру
Оцените статью
Секреты программирования
Добавить комментарий