/*
* Envio de e-mail por SMTP usando conexão criptografada
* Jefferson Ryan - automalabs.com.br - Julho de 2017
* Testado em um ESP8266 - ESP-01 - IDE Arduino 1.8.1 e ESP8266 Core v2.3.0
* Mais informações em http://www.automalabs.com.br/?p=1595
*
*/
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
//======== Você precisa preencher estes dados ===========================================
const char* SSID = "";
const char* PASS = "";
char smtp_server[] = "";
const int smtp_port = 465; //465 é a porta segura no meu servidor. A sua pode ser outra.
const String mail_username="nome_do_usuario";
const String mail_password="senha";
const String mail_from="ESP8266 <usuario@servidor_remetente>";
const String mail_to="Jefferson <usuario@servidor_destino>";
const String mail_subject="Enviado pelo ESP8266";
const String mail_line1="Esta é a linha 1\n";
const String mail_line2="Esta é a linha 2";
const String mail_line3="Esta é a linha 3";
//Obtenha com a ajuda de https://www.grc.com/fingerprints.htm
//Precisará ser atualizado manualmente quando o certificado expirar
const char* fingerprint = "";
//=========================================================================================
bool construindoLinha=false;
const char* _b64_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
// Cria uma conexao SSL/TLS
WiFiClientSecure client;
void printFreeRAM(){
Serial.print("RAM livre: ");
Serial.print(ESP.getFreeHeap());
Serial.println(" bytes.");
}
void a3_to_a4(unsigned char * a4, unsigned char * a3) {
a4[0] = (a3[0] & 0xfc) >> 2;
a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
a4[3] = (a3[2] & 0x3f);
}
int base64_encode(char *output, const char *input, int inputLen) {
int i = 0, j = 0;
int encLen = 0;
unsigned char a3[3];
unsigned char a4[4];
while(inputLen--) {
a3[i++] = *(input++);
if(i == 3) {
a3_to_a4(a4, a3);
for(i = 0; i < 4; i++) {
output[encLen++] = _b64_alphabet[a4[i]];
}
i = 0;
}
}
if(i) {
for(j = i; j < 3; j++) {
a3[j] = '\0';
}
a3_to_a4(a4, a3);
for(j = 0; j < i + 1; j++) {
output[encLen++] = _b64_alphabet[a4[j]];
}
while((i++ < 3)) {
output[encLen++] = '=';
}
}
output[encLen] = '\0';
return encLen;
}
void setup()
{
Serial.begin(115200);
// Serial.setDebugOutput(true);
delay(10);
Serial.println("");
Serial.println("");
Serial.print("Conectando a: ");
Serial.println(SSID);
Serial.print("Com a senha: ");
Serial.println(PASS);
WiFi.begin(SSID, PASS);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi Conectado.");
Serial.print("Endereco IP local: ");
Serial.println(WiFi.localIP());
printFreeRAM();
byte ret = sendEmail();
printFreeRAM();
}
void loop()
{
}
void SEND(String message)
{
if (!construindoLinha){Serial.print("EU: ");}; //Imprimo apenas no início de cada linha
Serial.print (message);
client.print (message);
construindoLinha=true;
}
void SENDln(String message)
{
if (!construindoLinha){Serial.print("EU: ");}; //Imprimo apenas no início de cada linha
Serial.println (message);
client.println (message);
construindoLinha=false;
}
byte sendEmail()
{
byte thisByte = 0;
byte respCode;
Serial.print("Conectando a: ");
Serial.println(smtp_server);
if (!client.connect(smtp_server, smtp_port)) {
Serial.println("Falha na conexao.");
return 0;
}else
{
Serial.println("Conectado.");
}
if (client.verify(fingerprint,smtp_server)) {
Serial.println("O certificado confere.");
} else {
Serial.println("O certificado nao confere.");
//return 0; //Descomente esta linha para impedir o envio se o certificado estiver errado
}
if (!eRcv()) return 0;
char* buf = (char*)malloc(100);
SEND("EHLO ");
SENDln(smtp_server);
if (!eRcv()) return 0;
SENDln("auth login");
if (!eRcv()) return 0;
base64_encode(buf, mail_username.c_str(), mail_username.length());
client.println(buf);
Serial.println(buf);
if (!eRcv()) return 0;
base64_encode(buf, mail_password.c_str(), mail_password.length());
client.println(buf);
Serial.println(buf);
if (!eRcv()) return 0;
SEND("MAIL From: ");
SENDln(mail_from);
if (!eRcv()) return 0;
SEND("RCPT To: ");
SENDln(mail_to);
if (!eRcv()) return 0;
SENDln("DATA");
if (!eRcv()) return 0;
SEND("To: ");
SENDln(mail_to);
SEND("From: ");
SENDln(mail_from); //Este é o "nome para exibição"
SEND("Subject: ");
SENDln(mail_subject);
SENDln(mail_line1);
SENDln(mail_line2);
SENDln(mail_line3);
SENDln("."); //O email tem que terminar assim
if (!eRcv()) return 0;
SENDln("QUIT");
if (!eRcv()) return 0;
client.stop();
Serial.println("Desconectado.");
return 1;
}
byte eRcv()
{
byte respCode;
byte thisByte;
int loopCount = 0;
while (!client.available()) {
delay(1);
loopCount++;
// Se nada for recebido em 10s, desiste.
if (loopCount > 10000) {
client.stop();
Serial.println("\r\nTimeout");
return 0;
}
}
respCode = client.peek();
while (client.available())
{
thisByte = client.read();
Serial.write(thisByte);
}
if (respCode >= '4')
{
// efail();
return 0;
}
return 1;
}
Comentários