2021-11-26 20:09:16 +00:00
|
|
|
#include "main.h"
|
2021-01-15 05:21:33 +00:00
|
|
|
#include "mesh/http/WebServer.h"
|
2020-09-19 01:29:16 +00:00
|
|
|
#include "NodeDB.h"
|
2021-01-15 05:21:33 +00:00
|
|
|
#include "mesh/http/WiFiAPClient.h"
|
2020-10-22 03:57:44 +00:00
|
|
|
#include <HTTPBodyParser.hpp>
|
|
|
|
#include <HTTPMultipartBodyParser.hpp>
|
|
|
|
#include <HTTPURLEncodedBodyParser.hpp>
|
2021-12-15 04:50:49 +00:00
|
|
|
#include "sleep.h"
|
2021-01-20 05:26:23 +00:00
|
|
|
|
2020-09-19 01:29:16 +00:00
|
|
|
#include <WebServer.h>
|
|
|
|
#include <WiFi.h>
|
2020-09-13 23:58:36 +00:00
|
|
|
|
2021-01-09 21:47:10 +00:00
|
|
|
#ifndef NO_ESP32
|
|
|
|
#include "esp_task_wdt.h"
|
|
|
|
#endif
|
2021-01-09 06:25:44 +00:00
|
|
|
|
2020-10-08 05:02:53 +00:00
|
|
|
// Persistant Data Storage
|
|
|
|
#include <Preferences.h>
|
|
|
|
Preferences prefs;
|
2020-09-13 23:58:36 +00:00
|
|
|
|
2020-10-08 05:02:53 +00:00
|
|
|
/*
|
|
|
|
Including the esp32_https_server library will trigger a compile time error. I've
|
|
|
|
tracked it down to a reoccurrance of this bug:
|
|
|
|
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57824
|
|
|
|
The work around is described here:
|
|
|
|
https://forums.xilinx.com/t5/Embedded-Development-Tools/Error-with-Standard-Libaries-in-Zynq/td-p/450032
|
|
|
|
|
|
|
|
Long story short is we need "#undef str" before including the esp32_https_server.
|
|
|
|
- Jm Casler (jm@casler.org) Oct 2020
|
|
|
|
*/
|
|
|
|
#undef str
|
|
|
|
|
|
|
|
// Includes for the https server
|
|
|
|
// https://github.com/fhessel/esp32_https_server
|
|
|
|
#include <HTTPRequest.hpp>
|
|
|
|
#include <HTTPResponse.hpp>
|
|
|
|
#include <HTTPSServer.hpp>
|
|
|
|
#include <HTTPServer.hpp>
|
|
|
|
#include <SSLCert.hpp>
|
2020-09-19 23:38:59 +00:00
|
|
|
|
2020-10-08 05:02:53 +00:00
|
|
|
// The HTTPS Server comes in a separate namespace. For easier use, include it here.
|
|
|
|
using namespace httpsserver;
|
2021-01-20 05:26:23 +00:00
|
|
|
#include "mesh/http/ContentHandler.h"
|
2020-09-19 19:50:43 +00:00
|
|
|
|
2021-08-18 03:40:46 +00:00
|
|
|
static SSLCert *cert;
|
|
|
|
static HTTPSServer *secureServer;
|
|
|
|
static HTTPServer *insecureServer;
|
2021-01-17 18:30:34 +00:00
|
|
|
|
2021-08-18 03:40:46 +00:00
|
|
|
volatile bool isWebServerReady;
|
|
|
|
volatile bool isCertReady;
|
2020-10-22 03:57:44 +00:00
|
|
|
|
2021-08-18 03:40:46 +00:00
|
|
|
static void handleWebResponse()
|
2020-09-19 01:29:16 +00:00
|
|
|
{
|
2021-08-18 03:40:46 +00:00
|
|
|
if (isWifiAvailable()) {
|
2020-09-17 03:15:00 +00:00
|
|
|
|
2021-08-18 03:40:46 +00:00
|
|
|
if (isWebServerReady) {
|
|
|
|
// We're going to handle the DNS responder here so it
|
|
|
|
// will be ignored by the NRF boards.
|
|
|
|
handleDNSResponse();
|
2020-09-19 01:29:16 +00:00
|
|
|
|
2021-08-18 03:40:46 +00:00
|
|
|
if(secureServer)
|
|
|
|
secureServer->loop();
|
|
|
|
insecureServer->loop();
|
|
|
|
}
|
2020-10-12 03:38:09 +00:00
|
|
|
|
2021-08-18 03:40:46 +00:00
|
|
|
/*
|
|
|
|
Slow down the CPU if we have not received a request within the last few
|
|
|
|
seconds.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (millis() - getTimeSpeedUp() >= (25 * 1000)) {
|
|
|
|
setCpuFrequencyMhz(80);
|
|
|
|
setTimeSpeedUp();
|
|
|
|
}
|
2020-10-12 03:38:09 +00:00
|
|
|
}
|
2020-09-13 23:58:36 +00:00
|
|
|
}
|
|
|
|
|
2021-08-18 03:40:46 +00:00
|
|
|
static void taskCreateCert(void *parameter)
|
2020-09-19 01:29:16 +00:00
|
|
|
{
|
2020-10-08 05:02:53 +00:00
|
|
|
prefs.begin("MeshtasticHTTPS", false);
|
|
|
|
|
2021-12-15 04:50:49 +00:00
|
|
|
|
|
|
|
#if 0
|
2021-12-17 19:02:29 +00:00
|
|
|
// Delete the saved certs (used in debugging)
|
|
|
|
DEBUG_MSG("Deleting any saved SSL keys ...\n");
|
|
|
|
// prefs.clear();
|
|
|
|
prefs.remove("PK");
|
|
|
|
prefs.remove("cert");
|
2021-12-15 04:50:49 +00:00
|
|
|
#endif
|
|
|
|
|
2020-10-08 05:02:53 +00:00
|
|
|
|
2021-08-18 03:40:46 +00:00
|
|
|
DEBUG_MSG("Checking if we have a previously saved SSL Certificate.\n");
|
|
|
|
|
2020-10-08 05:02:53 +00:00
|
|
|
size_t pkLen = prefs.getBytesLength("PK");
|
|
|
|
size_t certLen = prefs.getBytesLength("cert");
|
|
|
|
|
|
|
|
if (pkLen && certLen) {
|
|
|
|
DEBUG_MSG("Existing SSL Certificate found!\n");
|
2021-08-18 03:40:46 +00:00
|
|
|
|
|
|
|
uint8_t *pkBuffer = new uint8_t[pkLen];
|
|
|
|
prefs.getBytes("PK", pkBuffer, pkLen);
|
|
|
|
|
|
|
|
uint8_t *certBuffer = new uint8_t[certLen];
|
|
|
|
prefs.getBytes("cert", certBuffer, certLen);
|
|
|
|
|
|
|
|
cert = new SSLCert(certBuffer, certLen, pkBuffer, pkLen);
|
|
|
|
|
|
|
|
DEBUG_MSG("Retrieved Private Key: %d Bytes\n", cert->getPKLength());
|
|
|
|
DEBUG_MSG("Retrieved Certificate: %d Bytes\n", cert->getCertLength());
|
2021-12-15 04:50:49 +00:00
|
|
|
|
2020-10-08 05:02:53 +00:00
|
|
|
} else {
|
2021-12-15 04:50:49 +00:00
|
|
|
|
|
|
|
setCPUFast(true);
|
|
|
|
|
2020-10-08 05:02:53 +00:00
|
|
|
DEBUG_MSG("Creating the certificate. This may take a while. Please wait...\n");
|
2020-12-19 20:09:48 +00:00
|
|
|
yield();
|
2020-10-08 05:02:53 +00:00
|
|
|
cert = new SSLCert();
|
2020-12-19 20:09:48 +00:00
|
|
|
yield();
|
2020-10-08 05:02:53 +00:00
|
|
|
int createCertResult = createSelfSignedCert(*cert, KEYSIZE_2048, "CN=meshtastic.local,O=Meshtastic,C=US",
|
|
|
|
"20190101000000", "20300101000000");
|
2020-12-19 20:09:48 +00:00
|
|
|
yield();
|
2020-10-08 05:02:53 +00:00
|
|
|
|
|
|
|
if (createCertResult != 0) {
|
|
|
|
DEBUG_MSG("Creating the certificate failed\n");
|
|
|
|
|
|
|
|
// Serial.printf("Creating the certificate failed. Error Code = 0x%02X, check SSLCert.hpp for details",
|
|
|
|
// createCertResult);
|
|
|
|
// while (true)
|
|
|
|
// delay(500);
|
|
|
|
} else {
|
|
|
|
DEBUG_MSG("Creating the certificate was successful\n");
|
|
|
|
|
|
|
|
DEBUG_MSG("Created Private Key: %d Bytes\n", cert->getPKLength());
|
|
|
|
// for (int i = 0; i < cert->getPKLength(); i++)
|
|
|
|
// Serial.print(cert->getPKData()[i], HEX);
|
|
|
|
// Serial.println();
|
|
|
|
|
|
|
|
DEBUG_MSG("Created Certificate: %d Bytes\n", cert->getCertLength());
|
|
|
|
// for (int i = 0; i < cert->getCertLength(); i++)
|
|
|
|
// Serial.print(cert->getCertData()[i], HEX);
|
|
|
|
// Serial.println();
|
|
|
|
|
|
|
|
prefs.putBytes("PK", (uint8_t *)cert->getPKData(), cert->getPKLength());
|
|
|
|
prefs.putBytes("cert", (uint8_t *)cert->getCertData(), cert->getCertLength());
|
|
|
|
}
|
2021-12-15 04:50:49 +00:00
|
|
|
|
|
|
|
setCPUFast(false);
|
|
|
|
|
2020-10-08 05:02:53 +00:00
|
|
|
}
|
|
|
|
|
2021-08-18 03:40:46 +00:00
|
|
|
isCertReady = true;
|
|
|
|
|
|
|
|
// Must delete self, can't just fall out
|
2020-10-08 05:02:53 +00:00
|
|
|
vTaskDelete(NULL);
|
2020-09-13 23:58:36 +00:00
|
|
|
}
|
|
|
|
|
2020-10-08 05:02:53 +00:00
|
|
|
void createSSLCert()
|
2020-09-19 01:29:16 +00:00
|
|
|
{
|
2021-12-17 19:02:29 +00:00
|
|
|
bool runLoop = false;
|
2021-08-18 03:40:46 +00:00
|
|
|
if (isWifiAvailable() && !isCertReady) {
|
|
|
|
|
|
|
|
// Create a new process just to handle creating the cert.
|
|
|
|
// This is a workaround for Bug: https://github.com/fhessel/esp32_https_server/issues/48
|
|
|
|
// jm@casler.org (Oct 2020)
|
|
|
|
xTaskCreate(taskCreateCert, /* Task function. */
|
|
|
|
"createCert", /* String with name of task. */
|
2021-12-17 19:02:29 +00:00
|
|
|
//16384, /* Stack size in bytes. */
|
|
|
|
8192, /* Stack size in bytes. */
|
2021-08-18 03:40:46 +00:00
|
|
|
NULL, /* Parameter passed as input of the task */
|
|
|
|
16, /* Priority of the task. */
|
|
|
|
NULL); /* Task handle. */
|
|
|
|
|
|
|
|
DEBUG_MSG("Waiting for SSL Cert to be generated.\n");
|
|
|
|
while (!isCertReady) {
|
2021-12-17 19:02:29 +00:00
|
|
|
if ((millis() / 500) % 2) {
|
|
|
|
if (runLoop) {
|
|
|
|
DEBUG_MSG(".");
|
|
|
|
|
|
|
|
yield();
|
|
|
|
esp_task_wdt_reset();
|
|
|
|
|
|
|
|
if ((millis() / 1000 >= 3) && screen) {
|
|
|
|
screen->setSSLFrames();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
runLoop = false;
|
|
|
|
} else {
|
|
|
|
runLoop = true;
|
2021-11-26 20:09:16 +00:00
|
|
|
}
|
2021-08-18 03:40:46 +00:00
|
|
|
}
|
|
|
|
DEBUG_MSG("SSL Cert Ready!\n");
|
2020-10-08 05:02:53 +00:00
|
|
|
}
|
2020-09-13 23:58:36 +00:00
|
|
|
}
|
|
|
|
|
2021-01-09 06:25:44 +00:00
|
|
|
WebServerThread *webServerThread;
|
|
|
|
|
|
|
|
WebServerThread::WebServerThread() : concurrency::OSThread("WebServerThread") {}
|
|
|
|
|
|
|
|
int32_t WebServerThread::runOnce()
|
|
|
|
{
|
|
|
|
// DEBUG_MSG("WebServerThread::runOnce()\n");
|
|
|
|
handleWebResponse();
|
|
|
|
|
|
|
|
// Loop every 5ms.
|
|
|
|
return (5);
|
|
|
|
}
|
|
|
|
|
2020-10-08 05:02:53 +00:00
|
|
|
void initWebServer()
|
2020-09-19 01:29:16 +00:00
|
|
|
{
|
2020-10-08 05:02:53 +00:00
|
|
|
DEBUG_MSG("Initializing Web Server ...\n");
|
|
|
|
|
|
|
|
// We can now use the new certificate to setup our server as usual.
|
|
|
|
secureServer = new HTTPSServer(cert);
|
|
|
|
insecureServer = new HTTPServer();
|
|
|
|
|
2021-01-20 05:26:23 +00:00
|
|
|
registerHandlers(insecureServer, secureServer);
|
2020-10-15 03:24:19 +00:00
|
|
|
|
2021-08-18 03:40:46 +00:00
|
|
|
if(secureServer) {
|
|
|
|
DEBUG_MSG("Starting Secure Web Server...\n");
|
|
|
|
secureServer->start();
|
|
|
|
}
|
|
|
|
DEBUG_MSG("Starting Insecure Web Server...\n");
|
2020-10-08 05:02:53 +00:00
|
|
|
insecureServer->start();
|
2021-08-18 03:40:46 +00:00
|
|
|
if (insecureServer->isRunning()) {
|
|
|
|
DEBUG_MSG("Web Servers Ready! :-) \n");
|
|
|
|
isWebServerReady = true;
|
2020-10-19 01:44:08 +00:00
|
|
|
} else {
|
2021-08-18 03:40:46 +00:00
|
|
|
DEBUG_MSG("Web Servers Failed! ;-( \n");
|
2020-10-08 05:02:53 +00:00
|
|
|
}
|
|
|
|
}
|