Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(influxdb tls + mqtt tls): Use built-in certification bundle for server verification #180

Merged
merged 4 commits into from
Oct 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 34 additions & 30 deletions code/components/influxdb_ctrl/interface_influxdbv1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <time.h>

#include <esp_http_client.h>
#include <esp_crt_bundle.h>
#include <esp_log.h>

#include "ClassLogFile.h"
Expand Down Expand Up @@ -107,42 +108,42 @@ bool influxDBv1Init(const CfgData::SectionInfluxDBv1 *_cfgDataPtr)

esp_err_t influxDBv1Publish(const std::string &_measurement, const std::string &_fieldkey1, const std::string &_fieldvalue1, const std::string &_timestamp)
{
char* response_buffer = (char*) calloc_psram_heap(std::string(TAG) + "->response_buffer", 1,
sizeof(char) * MAX_HTTP_OUTPUT_BUFFER, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);

esp_http_client_config_t http_config = {
.user_agent = "ESP32 Meter reader",
esp_http_client_config_t httpConfig = {
.user_agent = "AI-on-the-Edge Device",
.method = HTTP_METHOD_POST,
.event_handler = http_event_handler,
.buffer_size = MAX_HTTP_OUTPUT_BUFFER,
.user_data = response_buffer
.buffer_size = MAX_HTTP_OUTPUT_BUFFER
};

if (cfgDataPtr->authMode == AUTH_BASIC) {
http_config.auth_type = HTTP_AUTH_TYPE_BASIC;
http_config.username = cfgDataPtr->username.c_str();
http_config.password = cfgDataPtr->password.c_str();
httpConfig.auth_type = HTTP_AUTH_TYPE_BASIC;
httpConfig.username = cfgDataPtr->username.c_str();
httpConfig.password = cfgDataPtr->password.c_str();
}
else if (cfgDataPtr->authMode == AUTH_TLS) {
http_config.auth_type = HTTP_AUTH_TYPE_BASIC;
http_config.username = cfgDataPtr->username.c_str();
http_config.password = cfgDataPtr->password.c_str();
http_config.transport_type = HTTP_TRANSPORT_OVER_SSL;
httpConfig.auth_type = HTTP_AUTH_TYPE_BASIC;
httpConfig.username = cfgDataPtr->username.c_str();
httpConfig.password = cfgDataPtr->password.c_str();
httpConfig.transport_type = HTTP_TRANSPORT_OVER_SSL;

if (!TLSCACert.empty()) {
http_config.cert_pem = TLSCACert.c_str();
http_config.cert_len = TLSCACert.length() + 1;
http_config.skip_cert_common_name_check = true; // Skip any validation of server certificate CN field
httpConfig.cert_pem = TLSCACert.c_str();
httpConfig.cert_len = TLSCACert.length() + 1;
httpConfig.skip_cert_common_name_check = true; // Skip any validation of server certificate CN field
}
else {
LogFile.writeToFile(ESP_LOG_DEBUG, TAG, "CA Certificate empty, use certification bundle for server verification");
httpConfig.crt_bundle_attach = esp_crt_bundle_attach;
}

if (!TLSClientCert.empty()) {
http_config.client_cert_pem = TLSClientCert.c_str();
http_config.client_cert_len = TLSClientCert.length() + 1;
httpConfig.client_cert_pem = TLSClientCert.c_str();
httpConfig.client_cert_len = TLSClientCert.length() + 1;
}

if (!TLSClientKey.empty()) {
http_config.client_key_pem = TLSClientKey.c_str();
http_config.client_key_len = TLSClientKey.length() + 1;
httpConfig.client_key_pem = TLSClientKey.c_str();
httpConfig.client_key_len = TLSClientKey.length() + 1;
}
}

Expand Down Expand Up @@ -177,22 +178,27 @@ esp_err_t influxDBv1Publish(const std::string &_measurement, const std::string &
// use the default retention policy of the database
std::string apiURI = cfgDataPtr->uri + "/write?db=" + cfgDataPtr->database;
apiURI.shrink_to_fit();
http_config.url = apiURI.c_str();
httpConfig.url = apiURI.c_str();
LogFile.writeToFile(ESP_LOG_DEBUG, TAG, "URI: " + apiURI);

esp_http_client_handle_t http_client = esp_http_client_init(&http_config);
esp_http_client_handle_t httpClient = esp_http_client_init(&httpConfig);
if (httpClient == NULL) {
LogFile.writeToFile(ESP_LOG_ERROR, TAG, "HTTP client: Initialization failed");
return ESP_FAIL;
}

LogFile.writeToFile(ESP_LOG_DEBUG, TAG, "HTTP client: Initialized");

esp_http_client_set_header(http_client, "Content-Type", "text/plain");
esp_http_client_set_header(httpClient, "Content-Type", "text/plain");
//LogFile.writeToFile(ESP_LOG_DEBUG, TAG, "Header setting done");

ESP_ERROR_CHECK(esp_http_client_set_post_field(http_client, payload.c_str(), payload.length()));
ESP_ERROR_CHECK(esp_http_client_set_post_field(httpClient, payload.c_str(), payload.length()));
//LogFile.writeToFile(ESP_LOG_DEBUG, TAG, "Payload post completed");

retVal = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_http_client_perform(http_client));
retVal = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_http_client_perform(httpClient));

if (retVal == ESP_OK) {
int status_code = esp_http_client_get_status_code(http_client);
int status_code = esp_http_client_get_status_code(httpClient);
if (status_code < 300) {
LogFile.writeToFile(ESP_LOG_DEBUG, TAG, "Writing data successful. HTTP response status: " + std::to_string(status_code));
}
Expand All @@ -204,9 +210,7 @@ esp_err_t influxDBv1Publish(const std::string &_measurement, const std::string &
else {
LogFile.writeToFile(ESP_LOG_ERROR, TAG, "HTTP client: Request failed. Error: " + intToHexString(retVal));
}
esp_http_client_cleanup(http_client);
free_psram_heap(std::string(TAG) + "->response_buffer", response_buffer);

esp_http_client_cleanup(httpClient);
return retVal;
}

Expand Down
52 changes: 28 additions & 24 deletions code/components/influxdb_ctrl/interface_influxdbv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <time.h>

#include <esp_http_client.h>
#include <esp_crt_bundle.h>
#include <esp_log.h>

#include "ClassLogFile.h"
Expand Down Expand Up @@ -107,32 +108,32 @@ bool influxDBv2Init(const CfgData::SectionInfluxDBv2 *_cfgDataPtr)

esp_err_t influxDBv2Publish(const std::string &_measurement, const std::string &_fieldkey1, const std::string &_fieldvalue1, const std::string &_timestamp)
{
char* response_buffer = (char*) calloc_psram_heap(std::string(TAG) + "->response_buffer", 1,
sizeof(char) * MAX_HTTP_OUTPUT_BUFFER, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);

esp_http_client_config_t http_config = {
.user_agent = "ESP32 Meter reader",
esp_http_client_config_t httpConfig = {
.user_agent = "AI-on-the-Edge Device",
.method = HTTP_METHOD_POST,
.event_handler = http_event_handler,
.buffer_size = MAX_HTTP_OUTPUT_BUFFER,
.user_data = response_buffer
.buffer_size = MAX_HTTP_OUTPUT_BUFFER
};

if (cfgDataPtr->authMode == AUTH_TLS) {
if (!TLSCACert.empty()) {
http_config.cert_pem = TLSCACert.c_str();
http_config.cert_len = TLSCACert.length() + 1;
http_config.skip_cert_common_name_check = true; // Skip any validation of server certificate CN field
httpConfig.cert_pem = TLSCACert.c_str();
httpConfig.cert_len = TLSCACert.length() + 1;
httpConfig.skip_cert_common_name_check = true; // Skip any validation of server certificate CN field
}
else {
LogFile.writeToFile(ESP_LOG_DEBUG, TAG, "CA Certificate empty, use certification bundle for server verification");
httpConfig.crt_bundle_attach = esp_crt_bundle_attach;
}

if (!TLSClientCert.empty()) {
http_config.client_cert_pem = TLSClientCert.c_str();
http_config.client_cert_len = TLSClientCert.length() + 1;
httpConfig.client_cert_pem = TLSClientCert.c_str();
httpConfig.client_cert_len = TLSClientCert.length() + 1;
}

if (!TLSClientKey.empty()) {
http_config.client_key_pem = TLSClientKey.c_str();
http_config.client_key_len = TLSClientKey.length() + 1;
httpConfig.client_key_pem = TLSClientKey.c_str();
httpConfig.client_key_len = TLSClientKey.length() + 1;
}
}

Expand Down Expand Up @@ -166,25 +167,30 @@ esp_err_t influxDBv2Publish(const std::string &_measurement, const std::string &

std::string apiURI = cfgDataPtr->uri + "/api/v2/write?org=" + cfgDataPtr->organization + "&bucket=" + cfgDataPtr->bucket;
apiURI.shrink_to_fit();
http_config.url = apiURI.c_str();
httpConfig.url = apiURI.c_str();
LogFile.writeToFile(ESP_LOG_DEBUG, TAG, "URI: " + apiURI);

esp_http_client_handle_t http_client = esp_http_client_init(&http_config);
esp_http_client_handle_t httpClient = esp_http_client_init(&httpConfig);
if (httpClient == NULL) {
LogFile.writeToFile(ESP_LOG_ERROR, TAG, "HTTP client: Initialization failed");
return ESP_FAIL;
}

LogFile.writeToFile(ESP_LOG_DEBUG, TAG, "HTTP client: Initialized");

esp_http_client_set_header(http_client, "Content-Type", "text/plain");
esp_http_client_set_header(httpClient, "Content-Type", "text/plain");
std::string authString = "Token " + cfgDataPtr->token;
//LogFile.writeToFile(ESP_LOG_DEBUG, TAG, "Tokenheader: %s\n", _zw.c_str());
esp_http_client_set_header(http_client, "Authorization", authString.c_str());
esp_http_client_set_header(httpClient, "Authorization", authString.c_str());
//LogFile.writeToFile(ESP_LOG_DEBUG, TAG, "Header setting done");

ESP_ERROR_CHECK(esp_http_client_set_post_field(http_client, payload.c_str(), payload.length()));
ESP_ERROR_CHECK(esp_http_client_set_post_field(httpClient, payload.c_str(), payload.length()));
//LogFile.writeToFile(ESP_LOG_DEBUG, TAG, "Payload post completed");

retVal = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_http_client_perform(http_client));
retVal = ESP_ERROR_CHECK_WITHOUT_ABORT(esp_http_client_perform(httpClient));

if (retVal == ESP_OK) {
int status_code = esp_http_client_get_status_code(http_client);
int status_code = esp_http_client_get_status_code(httpClient);
if (status_code < 300) {
LogFile.writeToFile(ESP_LOG_DEBUG, TAG, "Writing data successful. HTTP response status: " + std::to_string(status_code));
}
Expand All @@ -196,9 +202,7 @@ esp_err_t influxDBv2Publish(const std::string &_measurement, const std::string &
else {
LogFile.writeToFile(ESP_LOG_ERROR, TAG, "HTTP client: Request failed. Error: " + intToHexString(retVal));
}
esp_http_client_cleanup(http_client);
free_psram_heap(std::string(TAG) + "->response_buffer", response_buffer);

esp_http_client_cleanup(httpClient);
return retVal;
}

Expand Down
7 changes: 0 additions & 7 deletions code/components/mainprocess_ctrl/ClassFlowInfluxDBv1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ static const char* TAG = "INFLUXDBV1";
ClassFlowInfluxDBv1::ClassFlowInfluxDBv1()
{
presetFlowStateHandler(true);
flowpostprocessing = NULL;
InfluxDBenable = false;
}

Expand Down Expand Up @@ -107,12 +106,6 @@ void ClassFlowInfluxDBv1::doPostProcessEventHandling()
}


bool ClassFlowInfluxDBv1::isInfluxDBEnabled(void)
{
return InfluxDBenable;
}


ClassFlowInfluxDBv1::~ClassFlowInfluxDBv1()
{
// nothing to do
Expand Down
8 changes: 3 additions & 5 deletions code/components/mainprocess_ctrl/ClassFlowInfluxDBv1.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "../../include/defines.h"
#ifdef ENABLE_INFLUXDB

#ifndef CLASSFINFLUXDBV1_H
#define CLASSFINFLUXDBV1_H
#ifndef CLASSFLOWINFLUXDBV1_H
#define CLASSFLOWINFLUXDBV1_H

#include <string>

Expand All @@ -16,7 +16,6 @@ class ClassFlowInfluxDBv1 : public ClassFlow
protected:
const CfgData::SectionInfluxDBv1 *cfgDataPtr = NULL;
bool InfluxDBenable;
ClassFlowPostProcessing *flowpostprocessing;

public:
ClassFlowInfluxDBv1();
Expand All @@ -25,10 +24,9 @@ class ClassFlowInfluxDBv1 : public ClassFlow
bool loadParameter();
bool doFlow(std::string time);
void doPostProcessEventHandling();
bool isInfluxDBEnabled();

std::string name() { return "ClassFlowInfluxDBv1"; };
};

#endif // CLASSFINFLUXDBV1_H
#endif // CLASSFLOWINFLUXDBV1_H
#endif // ENABLE_INFLUXDB
7 changes: 0 additions & 7 deletions code/components/mainprocess_ctrl/ClassFlowInfluxDBv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ static const char* TAG = "INFLUXDBV2";
ClassFlowInfluxDBv2::ClassFlowInfluxDBv2()
{
presetFlowStateHandler(true);
flowpostprocessing = NULL;
InfluxDBenable = false;
}

Expand Down Expand Up @@ -107,12 +106,6 @@ void ClassFlowInfluxDBv2::doPostProcessEventHandling()
}


bool ClassFlowInfluxDBv2::isInfluxDBEnabled(void)
{
return InfluxDBenable;
}


ClassFlowInfluxDBv2::~ClassFlowInfluxDBv2()
{
// nothing to do
Expand Down
8 changes: 3 additions & 5 deletions code/components/mainprocess_ctrl/ClassFlowInfluxDBv2.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "../../include/defines.h"
#ifdef ENABLE_INFLUXDB

#ifndef CLASSFINFLUXDBv2_H
#define CLASSFINFLUXDBv2_H
#ifndef CLASSFLOWINFLUXDBv2_H
#define CLASSFLOWINFLUXDBv2_H

#include <string>

Expand All @@ -16,7 +16,6 @@ class ClassFlowInfluxDBv2 : public ClassFlow
protected:
const CfgData::SectionInfluxDBv2 *cfgDataPtr = NULL;
bool InfluxDBenable;
ClassFlowPostProcessing *flowpostprocessing;

public:
ClassFlowInfluxDBv2();
Expand All @@ -25,10 +24,9 @@ class ClassFlowInfluxDBv2 : public ClassFlow
bool loadParameter();
bool doFlow(std::string time);
void doPostProcessEventHandling();
bool isInfluxDBEnabled();

std::string name() { return "ClassFlowInfluxDBv2"; };
};

#endif // CLASSFINFLUXDBv2_H
#endif // CLASSFLOWINFLUXDBv2_H
#endif // ENABLE_INFLUXDB
12 changes: 9 additions & 3 deletions code/components/mqtt_ctrl/interface_mqtt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <cJSON.h>

#include <mqtt_client.h>
#include <esp_crt_bundle.h>

#ifdef DEBUG_DETAIL_ON
#include <esp_timer.h>
Expand Down Expand Up @@ -309,21 +310,26 @@ int MQTT_Init()
mqtt_cfg.session.last_will.topic = LWTTopic.c_str();
mqtt_cfg.session.last_will.retain = 1;
mqtt_cfg.session.last_will.msg = std::string(MQTT_STATUS_OFFLINE).c_str();
//mqtt_cfg.session.last_will.msg_len = (int)(std::string(MQTT_STATUS_OFFLINE).length());
mqtt_cfg.session.keepalive = keepAlive;
mqtt_cfg.buffer.size = 1024; // size of MQTT send/receive buffer (Default: 1024)

if (cfgDataPtr->authMode > AUTH_NONE) {
if (cfgDataPtr->authMode == AUTH_BASIC) {
mqtt_cfg.credentials.username = cfgDataPtr->username.c_str();
mqtt_cfg.credentials.authentication.password = cfgDataPtr->password.c_str();
}
else if (cfgDataPtr->authMode == AUTH_TLS) {
mqtt_cfg.credentials.username = cfgDataPtr->username.c_str();
mqtt_cfg.credentials.authentication.password = cfgDataPtr->password.c_str();

if (cfgDataPtr->authMode == AUTH_TLS) {
if (!TLSCACert.empty()) {
mqtt_cfg.broker.verification.certificate = TLSCACert.c_str();
mqtt_cfg.broker.verification.certificate_len = TLSCACert.length() + 1;
mqtt_cfg.broker.verification.skip_cert_common_name_check = true; // Skip any validation of server certificate CN field
}
else {
LogFile.writeToFile(ESP_LOG_DEBUG, TAG, "CA Certificate empty, use certification bundle for server verfication");
mqtt_cfg.broker.verification.crt_bundle_attach = esp_crt_bundle_attach;
}

if (!TLSClientCert.empty()) {
mqtt_cfg.credentials.authentication.certificate = TLSClientCert.c_str();
Expand Down
4 changes: 2 additions & 2 deletions docs/Configuration/Parameter/InfluxDBv1/AuthMode.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@

## Description

Select authentication mode for InfluxDB authentication.
Select authentication mode for InfluxDB authentication / security.


| Input Option | Description
|:--- |:---
| `None` | No authentication, anonymous
| `Basic` | Authenticate with username and password
| `TLS` | Authenticate with username, password and TLS certificates
| `TLS` | Authenticate with username, password and/or secure with TLS certificates


!!! Note
Expand Down
Loading