mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-11-25 11:49:34 +01:00
feat(mosq): Add support for basic MQTT authentication
This commit is contained in:
@@ -90,6 +90,10 @@ if (CONFIG_MOSQ_ENABLE_SYS)
|
|||||||
endif()
|
endif()
|
||||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
|
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
|
||||||
|
|
||||||
|
# Enable linker wrapping for mosquitto_unpwd_check to allow connection callback interception
|
||||||
|
# without modifying upstream code
|
||||||
|
target_link_options(${COMPONENT_LIB} PRIVATE "-Wl,--wrap=mosquitto_unpwd_check")
|
||||||
|
|
||||||
# Some mosquitto source unconditionally define `_GNU_SOURCE` which collides with IDF build system
|
# Some mosquitto source unconditionally define `_GNU_SOURCE` which collides with IDF build system
|
||||||
# producing warning: "_GNU_SOURCE" redefined
|
# producing warning: "_GNU_SOURCE" redefined
|
||||||
# This workarounds this issue by undefining the macro for the selected files
|
# This workarounds this issue by undefining the macro for the selected files
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
| Type | Name |
|
| Type | Name |
|
||||||
| ---: | :--- |
|
| ---: | :--- |
|
||||||
| struct | [**mosq\_broker\_config**](#struct-mosq_broker_config) <br>_Mosquitto configuration structure._ |
|
| struct | [**mosq\_broker\_config**](#struct-mosq_broker_config) <br>_Mosquitto configuration structure._ |
|
||||||
|
| typedef int(\* | [**mosq\_connect\_cb\_t**](#typedef-mosq_connect_cb_t) <br> |
|
||||||
| typedef void(\* | [**mosq\_message\_cb\_t**](#typedef-mosq_message_cb_t) <br> |
|
| typedef void(\* | [**mosq\_message\_cb\_t**](#typedef-mosq_message_cb_t) <br> |
|
||||||
|
|
||||||
## Functions
|
## Functions
|
||||||
@@ -35,6 +36,8 @@ ESP port of mosquittto supports only the options in this configuration structure
|
|||||||
|
|
||||||
Variables:
|
Variables:
|
||||||
|
|
||||||
|
- mosq\_connect\_cb\_t handle_connect_cb <br>On connect callback. If configured, user function is called whenever a client attempts to connect. The callback receives client\_id, username, password, and password length. Return 0 to accept the connection, non-zero to reject it.
|
||||||
|
|
||||||
- void(\* handle_message_cb <br>On message callback. If configured, user function is called whenever mosquitto processes a message.
|
- void(\* handle_message_cb <br>On message callback. If configured, user function is called whenever mosquitto processes a message.
|
||||||
|
|
||||||
- const char \* host <br>Address on which the broker is listening for connections
|
- const char \* host <br>Address on which the broker is listening for connections
|
||||||
@@ -43,6 +46,12 @@ Variables:
|
|||||||
|
|
||||||
- esp\_tls\_cfg\_server\_t \* tls_cfg <br>ESP-TLS configuration (if TLS transport used) Please refer to the ESP-TLS official documentation for more details on configuring the TLS options. You can open the respective docs with this idf.py command: `idf.py docs -sp api-reference/protocols/esp_tls.html`
|
- esp\_tls\_cfg\_server\_t \* tls_cfg <br>ESP-TLS configuration (if TLS transport used) Please refer to the ESP-TLS official documentation for more details on configuring the TLS options. You can open the respective docs with this idf.py command: `idf.py docs -sp api-reference/protocols/esp_tls.html`
|
||||||
|
|
||||||
|
### typedef `mosq_connect_cb_t`
|
||||||
|
|
||||||
|
```c
|
||||||
|
typedef int(* mosq_connect_cb_t) (const char *client_id, const char *username, const char *password, int password_len);
|
||||||
|
```
|
||||||
|
|
||||||
### typedef `mosq_message_cb_t`
|
### typedef `mosq_message_cb_t`
|
||||||
|
|
||||||
```c
|
```c
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ void mosq_broker_stop(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern mosq_message_cb_t g_mosq_message_callback;
|
extern mosq_message_cb_t g_mosq_message_callback;
|
||||||
|
extern mosq_connect_cb_t g_mosq_connect_callback;
|
||||||
|
|
||||||
int mosq_broker_run(struct mosq_broker_config *broker_config)
|
int mosq_broker_run(struct mosq_broker_config *broker_config)
|
||||||
{
|
{
|
||||||
@@ -130,6 +131,9 @@ int mosq_broker_run(struct mosq_broker_config *broker_config)
|
|||||||
if (broker_config->handle_message_cb) {
|
if (broker_config->handle_message_cb) {
|
||||||
g_mosq_message_callback = broker_config->handle_message_cb;
|
g_mosq_message_callback = broker_config->handle_message_cb;
|
||||||
}
|
}
|
||||||
|
if (broker_config->handle_connect_cb) {
|
||||||
|
g_mosq_connect_callback = broker_config->handle_connect_cb;
|
||||||
|
}
|
||||||
|
|
||||||
db.config = &config;
|
db.config = &config;
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
*
|
*
|
||||||
* SPDX-License-Identifier: EPL-2.0
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
*
|
*
|
||||||
* SPDX-FileContributor: 2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileContributor: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*/
|
*/
|
||||||
|
#include <string.h>
|
||||||
#include "mosquitto_internal.h"
|
#include "mosquitto_internal.h"
|
||||||
#include "mosquitto_broker.h"
|
#include "mosquitto_broker.h"
|
||||||
#include "memory_mosq.h"
|
#include "memory_mosq.h"
|
||||||
@@ -16,6 +17,7 @@
|
|||||||
#include "mosq_broker.h"
|
#include "mosq_broker.h"
|
||||||
|
|
||||||
mosq_message_cb_t g_mosq_message_callback = NULL;
|
mosq_message_cb_t g_mosq_message_callback = NULL;
|
||||||
|
mosq_connect_cb_t g_mosq_connect_callback = NULL;
|
||||||
|
|
||||||
int mosquitto_callback_register(
|
int mosquitto_callback_register(
|
||||||
mosquitto_plugin_id_t *identifier,
|
mosquitto_plugin_id_t *identifier,
|
||||||
@@ -51,3 +53,39 @@ int plugin__handle_message(struct mosquitto *context, struct mosquitto_msg_store
|
|||||||
}
|
}
|
||||||
return MOSQ_ERR_SUCCESS;
|
return MOSQ_ERR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __real_mosquitto_unpwd_check(struct mosquitto *context);
|
||||||
|
|
||||||
|
/* Wrapper function to intercept mosquitto_unpwd_check calls via linker wrapping */
|
||||||
|
int __wrap_mosquitto_unpwd_check(struct mosquitto *context)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
int password_len = 0;
|
||||||
|
|
||||||
|
/* Call user's connect callback if set */
|
||||||
|
if (g_mosq_connect_callback) {
|
||||||
|
/* Extract password length if password is present.
|
||||||
|
* Note: MQTT passwords are binary data, but mosquitto stores them as null-terminated strings.
|
||||||
|
* If password contains null bytes, strlen() will not return the full length.
|
||||||
|
* This matches how mosquitto itself handles passwords in some security functions. */
|
||||||
|
if (context->password) {
|
||||||
|
password_len = (int)strlen(context->password);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call user callback */
|
||||||
|
rc = g_mosq_connect_callback(
|
||||||
|
context->id ? context->id : "",
|
||||||
|
context->username ? context->username : NULL,
|
||||||
|
context->password ? context->password : NULL,
|
||||||
|
password_len
|
||||||
|
);
|
||||||
|
|
||||||
|
/* If callback rejects (returns non-zero), return AUTH error immediately */
|
||||||
|
if (rc != 0) {
|
||||||
|
return MOSQ_ERR_AUTH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call the original function */
|
||||||
|
return __real_mosquitto_unpwd_check(context);
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ extern "C" {
|
|||||||
struct mosquitto__config;
|
struct mosquitto__config;
|
||||||
|
|
||||||
typedef void (*mosq_message_cb_t)(char *client, char *topic, char *data, int len, int qos, int retain);
|
typedef void (*mosq_message_cb_t)(char *client, char *topic, char *data, int len, int qos, int retain);
|
||||||
|
|
||||||
|
typedef int (*mosq_connect_cb_t)(const char *client_id, const char *username, const char *password, int password_len);
|
||||||
/**
|
/**
|
||||||
* @brief Mosquitto configuration structure
|
* @brief Mosquitto configuration structure
|
||||||
*
|
*
|
||||||
@@ -33,6 +35,11 @@ struct mosq_broker_config {
|
|||||||
* On message callback. If configured, user function is called
|
* On message callback. If configured, user function is called
|
||||||
* whenever mosquitto processes a message.
|
* whenever mosquitto processes a message.
|
||||||
*/
|
*/
|
||||||
|
mosq_connect_cb_t handle_connect_cb; /*!< On connect callback. If configured, user function is called
|
||||||
|
* whenever a client attempts to connect. The callback receives
|
||||||
|
* client_id, username, password, and password length. Return 0 to
|
||||||
|
* accept the connection, non-zero to reject it.
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user