Pull to refresh

Аппаратный информатор о поступлении новой электронной почты с использованием защищенного соединения TLS на ESP8266

Reading time6 min
Views14K
При появлении Arduino IDE для Wi-Fi модуля на основе ESP8266 для меня стало возможным более удобное его программирование. А отсутствие внешнего контроллера для управления вносит еще одно огромное преимущество. В голову сразу полезли идеи разных электронных штучек с применением данного модуля. И вот пришла мысль сделать аппаратный автономный информатор о приходе новых писем на мою электронную почту. В итоге родилось устройство «E-Mail Notifier».
image

Подробности ниже.

Устройство периодически устанавливает TLS соединение с почтовым сервером и запрашивает количество писем. При первом обращении количество писем запоминается в памяти. Далее при увеличении количества писем в ящике принимается решение о приходе нового письма, включается световая и звуковая сигнализация. Квитирование события происходит по нажатию кнопки или при удалении письма из почтового ящика. Звуковая сигнализация длится около 15 секунд, а световая до квитирования события пользователем. Устройство выполнено в виде светильника и работает, в том числе, как обычный светильник. При нажатии на кнопку происходит плавное включение света. При нажатии и удержании кнопки происходит плавная смена спектра свечения. Кратковременное нажатие на кнопку при включенном освещении приводит к плавному затуханию свечения. Установить цвет свечения можно также посредством UDP соединения со смартфона или компьютера с соответствующим программным обеспечением.
Настройка параметров Wi-Fi соединения, логина и пароля к почтовому ящику и прочее производится через web-страничку устройства. Поддерживается несколько почтовых серверов.
В настоящее время известные почтовые серверы работают через защищенные соединения. Прежде чем работать с сервером командами протокола POP3 необходимо пройти авторизацию. Тут нам и нужен TLS протокол. Самое сложное для меня было установить TLS соединение с почтовым сервером. Вместе с Arduino IDE был пример обращения к web-страничке посредством SSL-соединения. Проверил – работает! Теперь мне только осталось понять что такое «отпечаток» (fingerprint), который присутствует в коде примера SSL. Для web-страниц все понятно, т.к. в свойствах соединения в браузере этот отпечаток присутствует. Но мне надо создать соединение с потовым сервером. Начал исследовать вопрос. Нашел классный инструмент OpenSSL. Комплект программ позволяет делать много интересного. Это по сути Telnet с установлением SSL соединения. Попробовал зайти на почтовый сервер и, о чудо, установилось TLS-соединение с почтовым сервером! Дальше я уже мог работать обычными командами протоколов POP3 и IMAP. Осталось извлечь из сертификата нужный мне отпечаток. Это делается посредством команды:
openssl s_client -connect pop3.mail.ru:995

После этого устанавливается защищенное соединение и внизу видно приглашение почтового сервера. Дальше работаем также как в Telnet. USER, PASS, STAT. Также можно использовать протокол IMAP. Кому что больше нравится. Необходимо лишь изменить адрес и порт почтового сервера.
Теперь надо получить сертификат и извлечь из него отпечаток, который нам необходим для библиотеки SSL.
Может быть есть способ проще, я подробно не разбирался с ключами комплекта OpenSSL, поэтому расскажу как делал сам. Итак, выполняем строчку:
openssl s_client -connect pop3.mail.ru:995 >crt

После этого выходим из программы и в файле crt в текущем каталоге будет хранится нужный нам сертификат. Что-то вроде этого
Пример сертификата
-----BEGIN CERTIFICATE-----
MIIE5jCCA86gAwIBAgIQEuH8d4WVsue+Ohe/WiSqgDANBgkqhkiG9w0BAQUFADBE
MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMU
R2VvVHJ1c3QgU1NMIENBIC0gRzIwHhcNMTUwODI3MDAwMDAwWhcNMTYwODI2MjM1
OTU5WjByMQswCQYDVQQGEwJSVTEbMBkGA1UECBQSUlVTU0lBTiBGRURFUkFUSU9O
w/s63J8N2ihPDA==
-----END CERTIFICATE-----

Копируем все что между --BEGIN CERTIFICATE-- и --END CERTIFICATE--, включая сами эти надписи, в отдельный файл. Назовем его mail.key. А теперь получим долгожданный отпечаток командой:
openssl x509 -in mail.key -fingerprint -sha1 -noout -text >keyprint

Теперь в файле keyprint будет в первой строчке хранится наш отпечаток. Для сервера pop3.mail.ru это будет
SHA1 Fingerprint=E0:10:11:B5:E6:C9:1B:7B:90:88:F8:A6:AE:6E:21:97:69:30:7A:04
Собственно это и было самой сложной задачей в разработке устройства. Надо было дойти до всех этих нюансов, но когда получилось, то был очень рад!
Для других почтовых серверов все точно также. Надо указать имя сервера и порт для соответствующего протокола POP3 или IMAP. Ни разу не приходилось работать с защищенными соединениями, поэтому, повторюсь, может быть есть способ проще.

Все исходные данные получены, теперь быстренько пишем программу для ESP8266 и, удивляемся, что все работает! Программа выделяет из почтового адреса имя сервера и подставляет в функцию SSL соответствующий серверу отпечаток сертификата.
Тем самым получаем возможность работы с почтовыми ящиками на многих серверах.
Отдельно приведу процедуру обращения к почтовому серверу с установлением TLS соединения.
Процедура обращения
const char *ssid = «yourSSID»;
const char *password = «yourPassword»;
const char* host = «pop3.mail.ru»;
const char* mailuser = «mymail mail.ru»;
const char* mailpass = «mypassword»;
const int httpsPort = 995;
const char* fingerprint = «E0 10 11 B5 E6 C9 1B 7B 90 88 F8 A6 AE 6E 21 97 69 30 7A 04»; // Отпечаток SHA1 Сертификата pop3.mail.ru:995

// Процедура запроса наличия новых писем в ящике mail.ru
void CheckMail(void)
{
String line;

if (!client.connect(host, httpsPort))
{
Serial.println(«MAIL#ERR»);
client.flush();
return;
}

if (!client.verify(fingerprint, host)) // Ошибка сертификата
{
Serial.println(«MAIL#Error certificate»);
client.flush();
return;
}
line = client.readStringUntil('\n');

client.print(String(«USER „)+mailuser+String(“\r\n»));
line = client.readStringUntil('\n');

client.print(String(«PASS „)+mailpass+String(“\r\n»));
line = client.readStringUntil('\n');
if (line==String("+OK Welcome!\r"))
{
client.print(String(«STAT\r\n»));
line = client.readString();
Serial.println(line);

client.print(String(«QUIT\r\n»));
line = client.readStringUntil('\n');
}
else { Serial.println(«MAIL#ERA»); }

client.flush();
client.stop();
}
// **** Процедура запроса наличия новых писем в ящике mail.ru



Описание аппаратной части
Принципиальная схема простая. Применил модуль ESP-12, «умные» светодиоды WS2812b.
image

Устройство питается от USB, а также и от встроенного аккумулятора на 650 мА*ч, которого хватает на 2 часа работы в режиме информирования — «Вам письмо!». Зарядное устройство для аккумулятора на микросхеме TP4056.
Отдельно выведен разъем для внутрисхемного программирования ESP-12.
image

image

image

image


Описание программной части
Разработка программы велась в среде Arduino 1.6.4 с установленным SDK для ESP8266. Основные функции брались из примеров. Модуль ESP8266 сконфигурирован для смешанного режима работы: точка доступа и клиент. При первом включении надо настроить параметры Wi-Fi соединения (логин, пароль), почтовый ящик, и пароль к почтовому ящику. Для этого необходимо подключиться через Wi-Fi соединение к точке доступа «MailNotifier» пароль: qwertyqwerty. Откроется страничка, на которой необходимо ввести данные и перезапустить модуль. Данные записываются в энергонезависимую память модуля. При включении питания настройки считываются и начинается процесс установления связи нашего информатора с точкой доступа в Интернет. Процесс сопровождается миганием синего цвета светодиода. При успешном подключении светодиод загорается желтым цветом и гаснет. С этого момента информатор периодически опрашивает почтовый сервер и, в случае поступления нового письма, информировать световым и звуковым сигналом. Если попытка установить соединение с точкой доступа не удалась, то светодиод начинает моргать красным цветом.
image


Усовершенствования
В программу добавлен NTP сервер из примеров, по нему можно получать системное время. Были мысли добавить будильники, но передумал, т.к. нет надобности.
Также к устройству можно подключаться по UDP и передавать поток данных для индивидуального включения каждого светодиода. Например, через соответствующий plugin из Winamp чтобы визуализировать музыку. И многое другое.
Также задействовал фоторезистор, для контроля освещенности, чтобы, например, не включать звуковую сигнализацию ночью. Но в данной версии данная функция программно не используется.
Без проблем можно добавить индикатор для вывода на него заголовков писем или что-либо еще. Но это все на будущее.

image


Наконец видео, демонстрирующее работу информатора.


Корпус помогли разработать и напечатать друзья из команды 3D-LIFE, за что им огромное спасибо! Теперь устройство приобрело законченный вид.

Спасибо автору интеграции Arduino IDE и ESP8266 за огромную работу!

Архив проекта со схемой, печатной платой в SL4 и исходником
Tags:
Hubs:
Total votes 18: ↑18 and ↓0+18
Comments6

Articles