arduino-esp32/libraries/NetworkClientSecure/examples/WiFiClientSecureProtocolUpgrade/WiFiClientSecureProtocolUpgrade.ino
Lucas Saavedra Vaz 6bfcd6d9a9
refactor(style): Change some style options (#9526)
* refactor(style): Change some style options

* refactor(style): Apply style changes
2024-04-19 18:16:55 +03:00

190 lines
4.8 KiB
C++

/* STARTSSL example
Inline upgrading from a clear-text connection to an SSL/TLS connection.
Some protocols such as SMTP, XMPP, Mysql, Postgresql and others allow, or require,
that you start the connection without encryption; and then send a command to switch
over to encryption.
E.g. a typical SMTP submission would entail a dialog such as this:
1. client connects to server in the clear
2. server says hello
3. client sents a EHLO
4. server tells the client that it supports SSL/TLS
5. client sends a 'STARTTLS' to make use of this faciltiy
6. client/server negiotiate a SSL or TLS connection.
7. client sends another EHLO
8. server now tells the client what (else) is supported; such as additional authentication options.
... conversation continues encrypted.
This can be enabled in NetworkClientSecure by telling it to start in plaintext:
client.setPlainStart();
and client is than a plain, TCP, connection (just as NetworkClient would be); until the client calls
the method:
client.startTLS(); // returns zero on error; non zero on success.
After which things switch to TLS/SSL.
*/
#include <WiFi.h>
#include <NetworkClientSecure.h>
#ifndef WIFI_NETWORK
#define WIFI_NETWORK "YOUR Wifi SSID"
#endif
#ifndef WIFI_PASSWD
#define WIFI_PASSWD "your-secret-password"
#endif
#ifndef SMTP_HOST
#define SMTP_HOST "smtp.gmail.com"
#endif
#ifndef SMTP_PORT
#define SMTP_PORT (587) // Standard (plaintext) submission port
#endif
const char *ssid = WIFI_NETWORK; // your network SSID (name of wifi network)
const char *password = WIFI_PASSWD; // your network password
const char *server = SMTP_HOST; // Server URL
const int submission_port = SMTP_PORT; // submission port.
NetworkClientSecure client;
static bool readAllSMTPLines();
void setup() {
int ret;
//Initialize serial and wait for port to open:
Serial.begin(115200);
delay(100);
Serial.print("Attempting to connect to SSID: ");
Serial.print(ssid);
WiFi.begin(ssid, password);
// attempt to connect to Wifi network:
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
// wait 1 second for re-trying
delay(1000);
}
Serial.print("Connected to ");
Serial.println(ssid);
Serial.printf("\nStarting connection to server: %s:%d\n", server, submission_port);
// skip verification for this demo. In production one should at the very least
// enable TOFU; or ideally hardcode a (CA) certificate that is trusted.
client.setInsecure();
// Enable a plain-test start.
client.setPlainStart();
if (!client.connect(server, SMTP_PORT)) {
Serial.println("Connection failed!");
return;
};
Serial.println("Connected to server (in the clear, in plaintest)");
if (!readAllSMTPLines()) {
goto err;
}
Serial.println("Sending : EHLO\t\tin the clear");
client.print("EHLO there\r\n");
if (!readAllSMTPLines()) {
goto err;
}
Serial.println("Sending : STARTTLS\t\tin the clear");
client.print("STARTTLS\r\n");
if (!readAllSMTPLines()) {
goto err;
}
Serial.println("Upgrading connection to TLS");
if ((ret = client.startTLS()) <= 0) {
Serial.printf("Upgrade connection failed: err %d\n", ret);
goto err;
}
Serial.println("Sending : EHLO again\t\tover the now encrypted connection");
client.print("EHLO again\r\n");
if (!readAllSMTPLines()) {
goto err;
}
// normally, as this point - we'd be authenticating and then be submitting
// an email. This has been left out of this example.
Serial.println("Sending : QUIT\t\t\tover the now encrypted connection");
client.print("QUIT\r\n");
if (!readAllSMTPLines()) {
goto err;
}
Serial.println("Completed OK\n");
err:
Serial.println("Closing connection");
client.stop();
}
// SMTP command repsponse start with three digits and a space;
// or, for continuation, with three digits and a '-'.
static bool readAllSMTPLines() {
String s = "";
int i;
// blocking read; we cannot rely on a timeout
// of a NetworkClientSecure read; as it is non
// blocking.
const unsigned long timeout = 15 * 1000;
unsigned long start = millis(); // the timeout is for the entire CMD block response; not per character/line.
while (1) {
while ((i = client.available()) == 0 && millis() - start < timeout) {
/* .. wait */
};
if (i == 0) {
Serial.println("Timeout reading SMTP response");
return false;
};
if (i < 0) {
break;
}
i = client.read();
if (i < 0) {
break;
}
if (i > 31 && i < 128) {
s += (char)i;
}
if (i == 0x0A) {
Serial.print("Receiving: ");
Serial.println(s);
if (s.charAt(3) == ' ') {
return true;
}
s = "";
}
}
Serial.printf("Error reading SMTP command response line: %d\n", i);
return false;
}
void loop() {
// do nothing
}