Merge branch 'develop' into NorbertHeusser:develop

This commit is contained in:
Norbert Heusser
2022-07-08 09:30:53 +00:00
212 changed files with 1726 additions and 702 deletions
+20 -1
View File
@@ -33,6 +33,7 @@ option(WITH_BUNDLED_DEPS "Build with bundled dependencies?" ON)
option(WITH_TLS "Include SSL/TLS support?" ON)
option(WITH_TLS_PSK "Include TLS-PSK support (requires WITH_TLS)?" ON)
option(WITH_EC "Include Elliptic Curve support (requires WITH_TLS)?" ON)
option(WITH_TESTS "Enable tests" ON)
if (WITH_TLS)
find_package(OpenSSL REQUIRED)
add_definitions("-DWITH_TLS")
@@ -104,6 +105,21 @@ option(WITH_APPS "Build apps?" ON)
option(WITH_PLUGINS "Build plugins?" ON)
option(DOCUMENTATION "Build documentation?" ON)
add_library(config-header INTERFACE)
target_sources(config-header INTERFACE config.h)
target_include_directories(config-header
INTERFACE
${mosquitto_SOURCE_DIR}
)
if(WITH_TLS)
target_include_directories(config-header
INTERFACE
"${OPENSSL_INCLUDE_DIR}"
)
endif()
add_subdirectory(lib)
if(WITH_CLIENTS)
add_subdirectory(client)
@@ -145,4 +161,7 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libmosquittopp.pc" DESTINATION "${CMA
# ========================================
# Testing
# ========================================
enable_testing()
if(WITH_TESTS)
enable_testing()
add_subdirectory(test)
endif()
+4
View File
@@ -57,6 +57,8 @@ Broker:
to trust default CA certificates. Closes #2473.
- Add `--test-config` option which can be used to test a configuration file
before trying to use it in a live broker. Closes #2521.
- Print messages in mosquitto_passwd when adding/updating passwords.
Closes #2544.
Plugins / plugin interface:
- Add persist-sqlite plugin.
@@ -84,6 +86,8 @@ Plugins / plugin interface:
- The dynamic security plugin now supports `%c` and `%u` patterns for
substituting client id and username respectively, in all ACLs except for
subscribeLiteral and unsubscribeLiteral.
- The dynamic security plugin now supports multiple ways to initialise the
first configuration file.
- Add `mosquitto_sub_matches_acl()`, which can match one topic filter (a
subscription) against another topic filter (an ACL).
- Registration of the MOSQ_EVT_CONTROL plugin event is now handled globally
+1 -2
View File
@@ -17,7 +17,6 @@ if(WITH_TLS AND CJSON_FOUND)
)
target_include_directories(mosquitto_ctrl PRIVATE
"${OPENSSL_INCLUDE_DIR}"
"${STDBOOL_H_PATH}"
"${STDINT_H_PATH}"
"${mosquitto_SOURCE_DIR}"
@@ -57,7 +56,7 @@ if(WITH_TLS AND CJSON_FOUND)
target_link_libraries(mosquitto_ctrl
PRIVATE
${OPENSSL_LIBRARIES}
OpenSSL::SSL
cJSON
)
+1 -2
View File
@@ -10,7 +10,6 @@ if(WITH_TLS)
)
target_include_directories(mosquitto_passwd PRIVATE
"${OPENSSL_INCLUDE_DIR}"
"${STDBOOL_H_PATH}"
"${STDINT_H_PATH}"
"${mosquitto_SOURCE_DIR}"
@@ -22,7 +21,7 @@ if(WITH_TLS)
target_link_libraries(mosquitto_passwd
PRIVATE
${OPENSSL_LIBRARIES}
OpenSSL::SSL
)
install(TARGETS mosquitto_passwd
+3
View File
@@ -336,8 +336,10 @@ static int update_pwuser(FILE *fptr, FILE *ftmp, const char *username, const cha
rc = pwfile_iterate(fptr, ftmp, update_pwuser_cb, &helper);
if(helper.found){
printf("Updating password for user %s\n", username);
return rc;
}else{
printf("Adding password for user %s\n", username);
return output_new_password(ftmp, username, password, iterations);
}
}
@@ -606,6 +608,7 @@ int main(int argc, char *argv[])
return 1;
}
free(password_file);
printf("Adding password for user %s\n", username);
rc = output_new_password(fptr, username, password_cmd, iterations);
fclose(fptr);
return rc;
+2 -1
View File
@@ -426,7 +426,8 @@ static void formatted_print_blank(char pad, int field_width)
static int formatted_print_float(const unsigned char *payload, int payloadlen, char format, char align, char pad, int field_width, int precision)
{
float float_value;
double value;
double value = 0.0;
if (format == 'f'){
if (sizeof(float_value) != payloadlen) {
return -1;
+36
View File
@@ -0,0 +1,36 @@
find_package(PkgConfig)
pkg_check_modules(PC_CUnit QUIET cunit)
find_path(CUnit_INCLUDE_DIR
NAMES CUnit/CUnit.h
PATHS ${PC_CUnit_INCLUDE_DIRS}
)
find_library(CUnit_LIBRARY
NAMES cunit
PATHS ${PC_CUnit_LIBRARY_DIRS}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CUnit
FOUND_VAR CUnit_FOUND
REQUIRED_VARS
CUnit_LIBRARY
CUnit_INCLUDE_DIR
VERSION_VAR CUnit_VERSION
)
if(CUnit_FOUND)
set(CUnit_LIBRARIES ${CUnit_LIBRARY})
set(CUnit_INCLUDE_DIRS ${CUnit_INCLUDE_DIR})
set(CUnit_DEFINITIONS ${PC_CUnit_CFLAGS_OTHER})
endif()
if(CUnit_FOUND AND NOT TARGET CUnit::CUnit)
add_library(CUnit::CUnit UNKNOWN IMPORTED)
set_target_properties(CUnit::CUnit PROPERTIES
IMPORTED_LOCATION "${CUnit_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${PC_CUnit_CFLAGS_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${CUnit_INCLUDE_DIR}"
)
endif()
+1 -1
View File
@@ -88,7 +88,7 @@
#endif
#define WS_IS_LWS 1
#define WS_IS_WSLAY 2
#define WS_IS_BUILTIN 2
#ifdef WITH_BROKER
# ifdef __GNUC__
+5 -5
View File
@@ -58,7 +58,9 @@ if (WITH_THREADING AND WIN32)
list(APPEND C_SRC "../common/winthread_mosq.c" "../common/winthread_mosq.h")
endif()
set (LIBRARIES ${OPENSSL_LIBRARIES})
if(WITH_TLS)
set (LIBRARIES OpenSSL::SSL)
endif()
if(UNIX AND NOT APPLE AND NOT ANDROID)
find_library(LIBRT rt)
@@ -104,7 +106,6 @@ endif()
target_include_directories(libmosquitto
PUBLIC
"${mosquitto_SOURCE_DIR}/include"
"${OPENSSL_INCLUDE_DIR}"
PRIVATE
"${STDBOOL_H_PATH}"
"${STDINT_H_PATH}"
@@ -152,7 +153,6 @@ if(WITH_STATIC_LIBRARIES)
target_link_libraries(libmosquitto_static PRIVATE ${LIBRARIES})
target_include_directories(libmosquitto_static PRIVATE
"${OPENSSL_INCLUDE_DIR}"
"${STDBOOL_H_PATH}"
"${STDINT_H_PATH}"
"${mosquitto_SOURCE_DIR}"
@@ -171,5 +171,5 @@ if(WITH_STATIC_LIBRARIES)
)
endif()
install(FILES ../include/mosquitto.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(FILES ../include/mqtt_protocol.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(FILES ${mosquitto_SOURCE_DIR}/include/mosquitto.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(FILES ${mosquitto_SOURCE_DIR}/include/mqtt_protocol.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
+1 -1
View File
@@ -69,4 +69,4 @@ if(WITH_STATIC_LIBRARIES)
)
endif()
install(FILES mosquittopp.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(FILES ${mosquitto_SOURCE_DIR}/include/mosquittopp.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
+1
View File
@@ -26,6 +26,7 @@ Contributors:
#include "mosquitto_internal.h"
#include "base64_mosq.h"
#include "http_client.h"
#include "memory_mosq.h"
#include "mqtt_protocol.h"
#include "net_mosq.h"
+1
View File
@@ -183,6 +183,7 @@ int mosquitto_reinitialise(struct mosquitto *mosq, const char *id, bool clean_st
packet__cleanup(&mosq->in_packet);
mosq->out_packet = NULL;
mosq->out_packet_count = 0;
mosq->out_packet_bytes = 0;
mosq->last_msg_in = mosquitto_time();
mosq->next_msg_out = mosquitto_time() + mosq->keepalive;
mosq->ping_t = 0;
+3 -2
View File
@@ -243,7 +243,7 @@ struct mosquitto_msg_data{
#define WS_PING 0x09
#define WS_PONG 0x0A
#if defined(WITH_WEBSOCKETS) && WITH_WEBSOCKETS == LWS_IS_BUILTIN
#if defined(WITH_WEBSOCKETS) && WITH_WEBSOCKETS == WS_IS_BUILTIN
struct ws_data{
struct mosquitto__packet *out_packet;
char *http_path;
@@ -281,7 +281,7 @@ struct mosquitto {
struct gaicb *adns; /* For getaddrinfo_a */
#endif
uint64_t last_cmsg_id;
#if defined(WITH_WEBSOCKETS) && WITH_WEBSOCKETS == LWS_IS_BUILTIN
#if defined(WITH_WEBSOCKETS) && WITH_WEBSOCKETS == WS_IS_BUILTIN
struct ws_data wsd;
#endif
enum mosquitto__protocol protocol;
@@ -307,6 +307,7 @@ struct mosquitto {
uint16_t alias_max_l2r;
uint32_t will_delay_interval;
int out_packet_count;
int64_t out_packet_bytes;
time_t will_delay_time;
#ifdef WITH_TLS
SSL *ssl;
+1 -1
View File
@@ -204,7 +204,7 @@ static ssize_t read_ws_payloadlen_extended(struct mosquitto *mosq)
}
ssize_t read_ws_mask(struct mosquitto *mosq)
static ssize_t read_ws_mask(struct mosquitto *mosq)
{
ssize_t len;
+2 -2
View File
@@ -504,7 +504,7 @@ int mosquitto_int_option(struct mosquitto *mosq, enum mosq_opt_t option, int val
break;
case MOSQ_OPT_TRANSPORT:
#if defined(WITH_WEBSOCKETS) && WITH_WEBSOCKETS == LWS_IS_BUILTIN
#if defined(WITH_WEBSOCKETS) && WITH_WEBSOCKETS == WS_IS_BUILTIN
if(value == mosq_t_tcp || value == mosq_t_ws){
mosq->transport = (uint8_t)value;
}else{
@@ -516,7 +516,7 @@ int mosquitto_int_option(struct mosquitto *mosq, enum mosq_opt_t option, int val
break;
case MOSQ_OPT_HTTP_HEADER_SIZE:
#if defined(WITH_WEBSOCKETS) && WITH_WEBSOCKETS == LWS_IS_BUILTIN
#if defined(WITH_WEBSOCKETS) && WITH_WEBSOCKETS == WS_IS_BUILTIN
if(value < 100){ /* arbitrary limit */
return MOSQ_ERR_INVAL;
}else if(mosq->http_request){
+31 -18
View File
@@ -46,6 +46,10 @@ Contributors:
# define G_BYTES_SENT_INC(A)
# define G_MSGS_SENT_INC(A)
# define G_PUB_MSGS_SENT_INC(A)
# define G_OUT_PACKET_COUNT_INC(A)
# define G_OUT_PACKET_COUNT_DEC(A)
# define G_OUT_PACKET_BYTES_INC(A)
# define G_OUT_PACKET_BYTES_DEC(A)
#endif
int packet__alloc(struct mosquitto__packet **packet, uint8_t command, uint32_t remaining_length)
@@ -120,7 +124,10 @@ void packet__cleanup_all_no_locks(struct mosquitto *mosq)
mosquitto__FREE(packet);
}
G_OUT_PACKET_COUNT_DEC(mosq->out_packet_count);
G_OUT_PACKET_BYTES_DEC(mosq->out_packet_bytes);
mosq->out_packet_count = 0;
mosq->out_packet_bytes = 0;
mosq->out_packet_last = NULL;
packet__cleanup(&mosq->in_packet);
@@ -134,6 +141,23 @@ void packet__cleanup_all(struct mosquitto *mosq)
}
static void packet__queue_append(struct mosquitto *mosq, struct mosquitto__packet *packet)
{
pthread_mutex_lock(&mosq->out_packet_mutex);
if(mosq->out_packet){
mosq->out_packet_last->next = packet;
}else{
mosq->out_packet = packet;
}
mosq->out_packet_last = packet;
mosq->out_packet_count++;
mosq->out_packet_bytes += packet->packet_length;
G_OUT_PACKET_COUNT_INC(1);
G_OUT_PACKET_BYTES_INC(packet->packet_length);
pthread_mutex_unlock(&mosq->out_packet_mutex);
}
int packet__queue(struct mosquitto *mosq, struct mosquitto__packet *packet)
{
#ifndef WITH_BROKER
@@ -148,15 +172,7 @@ int packet__queue(struct mosquitto *mosq, struct mosquitto__packet *packet)
packet->pos = WS_PACKET_OFFSET;
packet->to_process = packet->packet_length - WS_PACKET_OFFSET;
pthread_mutex_lock(&mosq->out_packet_mutex);
if(mosq->out_packet){
mosq->out_packet_last->next = packet;
}else{
mosq->out_packet = packet;
}
mosq->out_packet_last = packet;
mosq->out_packet_count++;
pthread_mutex_unlock(&mosq->out_packet_mutex);
packet__queue_append(mosq, packet);
lws_callback_on_writable(mosq->wsi);
return MOSQ_ERR_SUCCESS;
@@ -173,14 +189,7 @@ int packet__queue(struct mosquitto *mosq, struct mosquitto__packet *packet)
packet->to_process = packet->packet_length - WS_PACKET_OFFSET;
}
pthread_mutex_lock(&mosq->out_packet_mutex);
if(mosq->out_packet){
mosq->out_packet_last->next = packet;
}else{
mosq->out_packet = packet;
}
mosq->out_packet_last = packet;
pthread_mutex_unlock(&mosq->out_packet_mutex);
packet__queue_append(mosq, packet);
#ifdef WITH_BROKER
return packet__write(mosq);
@@ -225,11 +234,15 @@ struct mosquitto__packet *packet__get_next_out(struct mosquitto *mosq)
pthread_mutex_lock(&mosq->out_packet_mutex);
if(mosq->out_packet){
mosq->out_packet_count--;
mosq->out_packet_bytes -= mosq->out_packet->packet_length;
G_OUT_PACKET_COUNT_DEC(1);
G_OUT_PACKET_BYTES_DEC(mosq->out_packet->packet_length);
mosq->out_packet = mosq->out_packet->next;
if(!mosq->out_packet){
mosq->out_packet_last = NULL;
}
mosq->out_packet_count--;
packet = mosq->out_packet;
}
pthread_mutex_unlock(&mosq->out_packet_mutex);
+22
View File
@@ -556,6 +556,28 @@
<para>The total number of messages of any type sent since the broker started.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>$SYS/broker/packet/out/count</option></term>
<listitem>
<para>
The current number of packets queued for delivery across
all clients. A large and increasing value here may
indicate messages are being sent faster than the network
can handle.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>$SYS/broker/packet/out/bytes</option></term>
<listitem>
<para>
The current number of bytes in packets queued for
delivery across all clients. A large and increasing
value here may indicate messages are being sent faster
than the network can handle.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>$SYS/broker/publish/messages/dropped</option></term>
<listitem>
+16
View File
@@ -191,6 +191,22 @@
<itemizedlist mark="circle">
<listitem><para>mosquitto_passwd <literal>-c</literal> /etc/mosquitto/passwd <literal>ral</literal></para></listitem>
</itemizedlist>
<para>Add a user to an existing password file:</para>
<itemizedlist mark="circle">
<listitem><para>mosquitto_passwd /etc/mosquitto/passwd <literal>ral</literal></para></listitem>
</itemizedlist>
<para>Add a user to an existing password file, passing the password on the command line:</para>
<itemizedlist mark="circle">
<listitem><para>mosquitto_passwd -b /etc/mosquitto/passwd <literal>ral</literal> <literal>z2Dr0BsvtZ</literal></para></listitem>
</itemizedlist>
<para>Update the password for a user in an existing password file:</para>
<itemizedlist mark="circle">
<listitem><para>mosquitto_passwd /etc/mosquitto/passwd <literal>ral</literal></para></listitem>
</itemizedlist>
<para>Add a user to an existing password file using the sha512 hash for Mosquitto 1.6 compatibility:</para>
<itemizedlist mark="circle">
<listitem><para>mosquitto_passwd -H sha512 /etc/mosquitto/passwd <literal>ral</literal></para></listitem>
</itemizedlist>
<para>Delete a user from a password file</para>
<itemizedlist mark="circle">
<listitem><para>mosquitto_passwd <literal>-D</literal> /etc/mosquitto/passwd <literal>ral</literal></para></listitem>
+2
View File
@@ -1,3 +1,5 @@
#include "config.h"
#include "plugin_common.h"
#include "json_help.h"
#include <mqtt_protocol.h>
+2 -4
View File
@@ -98,7 +98,7 @@ int dynsec__config_from_json(struct dynsec__data *data, const char *json_str)
tree = cJSON_Parse(json_str);
if(tree == NULL){
mosquitto_log_printf(MOSQ_LOG_ERR, "Error loading Dynamic security plugin config: File is not valid JSON.\n");
mosquitto_log_printf(MOSQ_LOG_ERR, "Error loading Dynamic security plugin config: File is not valid JSON.");
return 1;
}
@@ -128,9 +128,7 @@ int dynsec__config_load(struct dynsec__data *data)
fptr = fopen(data->config_file, "rb");
if(fptr == NULL){
/* Attempt to initialise a new config file */
if(dynsec__config_init(data->config_file) == MOSQ_ERR_SUCCESS){
mosquitto_log_printf(MOSQ_LOG_INFO, "Dynamic security plugin config not found, generating a default config.");
mosquitto_log_printf(MOSQ_LOG_INFO, " Generated passwords are at %s.pw", data->config_file);
if(dynsec__config_init(data) == MOSQ_ERR_SUCCESS){
/* If it works, try to open the file again */
fptr = fopen(data->config_file, "rb");
}
+102 -31
View File
@@ -19,6 +19,7 @@ Contributors:
#include "config.h"
#include <cjson/cJSON.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -63,7 +64,56 @@ static int add_default_access(cJSON *j_tree)
}
static int generate_password(int iterations, char **password, char **password_hash, char **salt)
static int get_password_from_init_file(struct dynsec__data *data, char **pw)
{
FILE *fptr;
char buf[1024];
int pos;
if(data->password_init_file == NULL){
*pw = NULL;
return MOSQ_ERR_SUCCESS;
}
fptr = fopen(data->password_init_file, "rt");
if(!fptr){
mosquitto_log_printf(MOSQ_LOG_ERR, "Error: Unable to get initial password from '%s', file not accessible.", data->password_init_file);
return MOSQ_ERR_INVAL;
}
if(!fgets(buf, sizeof(buf), fptr)){
fclose(fptr);
mosquitto_log_printf(MOSQ_LOG_ERR, "Error: Unable to get initial password from '%s', file empty.", data->password_init_file);
return MOSQ_ERR_INVAL;
}
fclose(fptr);
pos = (int)strlen(buf)-1;
while(pos >= 0 && isspace(buf[pos])){
buf[pos] = '\0';
pos--;
}
if(strlen(buf) == 0){
mosquitto_log_printf(MOSQ_LOG_ERR, "Error: Unable to get initial password from '%s', password is empty.", data->password_init_file);
return MOSQ_ERR_INVAL;
}
*pw = strdup(buf);
if(!*pw){
mosquitto_log_printf(MOSQ_LOG_ERR, "Error: Unable to get initial password from '%s', out of memory.", data->password_init_file);
return MOSQ_ERR_NOMEM;
}else{
return MOSQ_ERR_SUCCESS;
}
}
/* Generate a password for the admin user
*
* Uses passwords from, in order:
*
* * The password defined in the plugin_opt_password_init_file file
* * The contents of the MOSQUITTO_DYNSEC_PASSWORD environment variable
* * Randomly generated passwords for "admin", "user", stored in plain text at '<plugin_opt_config_file>.pw'
*/
static int generate_password(struct dynsec__data *data, int iterations, char **password, char **password_hash, char **salt)
{
struct mosquitto_pw pw;
int i;
@@ -75,9 +125,13 @@ static int generate_password(int iterations, char **password, char **password_ha
memset(&pw, 0, sizeof(struct mosquitto_pw));
pw.hashtype = pw_sha512_pbkdf2;
pwenv = getenv("MOSQUITTO_DYNSEC_PASSWORD");
if(pwenv){
if(strlen(pwenv) < 12){
if(data->init_mode == dpwim_file){
if(get_password_from_init_file(data, password)){
return MOSQ_ERR_INVAL;
}
}else if(data->init_mode == dpwim_env){
pwenv = getenv("MOSQUITTO_DYNSEC_PASSWORD");
if(pwenv == NULL || strlen(pwenv) < 12){
mosquitto_log_printf(MOSQ_LOG_ERR, "Error: Not generating dynsec config, MOSQUITTO_DYNSEC_PASSWORD must be at least 12 characters.");
return MOSQ_ERR_INVAL;
}
@@ -140,14 +194,14 @@ static int client_role_add(cJSON *j_roles, const char *rolename)
}
static int client_add_admin(FILE *pwfile, cJSON *j_clients)
static int client_add_admin(struct dynsec__data *data, FILE *pwfile, cJSON *j_clients)
{
cJSON *j_client, *j_roles;
char *password = NULL;
char *password_hash = NULL;
char *salt = NULL;
if(generate_password(10000, &password, &password_hash, &salt)){
if(generate_password(data, 10000, &password, &password_hash, &salt)){
return MOSQ_ERR_UNKNOWN;
}
@@ -181,23 +235,25 @@ static int client_add_admin(FILE *pwfile, cJSON *j_clients)
return MOSQ_ERR_NOMEM;
}
fprintf(pwfile, "admin %s\n", password);
if(data->init_mode == dpwim_random){
fprintf(pwfile, "admin %s\n", password);
}
free(password);
return MOSQ_ERR_SUCCESS;
}
static int client_add_user(FILE *pwfile, cJSON *j_clients)
static int client_add_user(struct dynsec__data *data, FILE *pwfile, cJSON *j_clients)
{
cJSON *j_client, *j_roles;
char *password = NULL;
char *password_hash = NULL;
char *salt = NULL;
if(getenv("MOSQUITTO_DYNSEC_PASSWORD")){
if(data->init_mode != dpwim_random){
return MOSQ_ERR_SUCCESS;
}
if(generate_password(10000, &password, &password_hash, &salt)){
if(generate_password(data, 10000, &password, &password_hash, &salt)){
return MOSQ_ERR_UNKNOWN;
}
@@ -234,40 +290,42 @@ static int client_add_user(FILE *pwfile, cJSON *j_clients)
return MOSQ_ERR_SUCCESS;
}
static int add_clients(const char *filename, cJSON *j_tree)
static int add_clients(struct dynsec__data *data, cJSON *j_tree)
{
cJSON *j_clients;
char *pwfile;
size_t len;
FILE *fptr;
FILE *fptr = NULL;
len = strlen(filename) + 5;
pwfile = malloc(len);
if(pwfile == NULL){
return MOSQ_ERR_NOMEM;
}
snprintf(pwfile, len, "%s.pw", filename);
fptr = mosquitto__fopen(pwfile, "wb", true);
free(pwfile);
if(fptr == NULL){
return MOSQ_ERR_UNKNOWN;
if(data->init_mode == dpwim_random){
len = strlen(data->config_file) + 5;
pwfile = malloc(len);
if(pwfile == NULL){
return MOSQ_ERR_NOMEM;
}
snprintf(pwfile, len, "%s.pw", data->config_file);
fptr = mosquitto__fopen(pwfile, "wb", true);
free(pwfile);
if(fptr == NULL){
return MOSQ_ERR_UNKNOWN;
}
}
j_clients = cJSON_AddArrayToObject(j_tree, "clients");
if(j_clients == NULL){
fclose(fptr);
if(fptr) fclose(fptr);
return MOSQ_ERR_NOMEM;
}
if(client_add_admin(fptr, j_clients)
|| client_add_user(fptr, j_clients)
if(client_add_admin(data, fptr, j_clients)
|| client_add_user(data, fptr, j_clients)
){
fclose(fptr);
if(fptr) fclose(fptr);
return MOSQ_ERR_NOMEM;
}
fclose(fptr);
if(fptr) fclose(fptr);
return MOSQ_ERR_SUCCESS;
}
@@ -416,7 +474,7 @@ static int role_add_topic_observe(cJSON *j_roles)
if(cJSON_AddStringToObject(j_role, "rolename", "topic-observe") == NULL
|| cJSON_AddStringToObject(j_role, "textdescription",
"Read/write access to the full application topic hierarchy.") == NULL
"Read only access to the full application topic hierarchy.") == NULL
|| (j_acls = cJSON_AddArrayToObject(j_role, "acls")) == NULL
){
@@ -455,19 +513,32 @@ static int add_roles(cJSON *j_tree)
}
int dynsec__config_init(const char *filename)
int dynsec__config_init(struct dynsec__data *data)
{
FILE *fptr;
cJSON *j_tree;
char *json_str;
mosquitto_log_printf(MOSQ_LOG_INFO, "Dynamic security plugin config not found, generating a default config.");
if(data->password_init_file){
mosquitto_log_printf(MOSQ_LOG_INFO, " Using admin password from file '%s'", data->password_init_file);
data->init_mode = dpwim_file;
}else if(getenv("MOSQUITTO_DYNSEC_PASSWORD")){
mosquitto_log_printf(MOSQ_LOG_INFO, " Using admin password from MOSQUITTO_DYNSEC_PASSWORD environment variable");
data->init_mode = dpwim_env;
}else{
mosquitto_log_printf(MOSQ_LOG_INFO, " Generated passwords are at %s.pw", data->config_file);
data->init_mode = dpwim_random;
}
j_tree = cJSON_CreateObject();
if(j_tree == NULL){
return MOSQ_ERR_NOMEM;
}
if(add_default_access(j_tree) != MOSQ_ERR_SUCCESS
|| add_clients(filename, j_tree) != MOSQ_ERR_SUCCESS
|| add_clients(data, j_tree) != MOSQ_ERR_SUCCESS
|| add_groups(j_tree) != MOSQ_ERR_SUCCESS
|| add_roles(j_tree) != MOSQ_ERR_SUCCESS
|| cJSON_AddStringToObject(j_tree, "anonymousGroup", "unauthenticated") == NULL
@@ -483,7 +554,7 @@ int dynsec__config_init(const char *filename)
return MOSQ_ERR_NOMEM;
}
fptr = mosquitto__fopen(filename, "wb", true);
fptr = mosquitto__fopen(data->config_file, "wb", true);
if(fptr == NULL){
return MOSQ_ERR_UNKNOWN;
}
+9 -1
View File
@@ -136,14 +136,22 @@ struct dynsec__acl_default_access{
bool unsubscribe;
};
enum dynsec_pw_init_mode{
dpwim_file = 1,
dpwim_env = 2,
dpwim_random = 3,
};
struct dynsec__data{
char *config_file;
char *password_init_file;
struct dynsec__client *clients;
struct dynsec__group *groups;
struct dynsec__role *roles;
struct dynsec__group *anonymous_group;
struct dynsec__kicklist *kicklist;
struct dynsec__acl_default_access default_access;
int init_mode;
};
/* ################################################################
@@ -152,7 +160,7 @@ struct dynsec__data{
* #
* ################################################################ */
int dynsec__config_init(const char *filename);
int dynsec__config_init(struct dynsec__data *data);
void dynsec__config_save(struct dynsec__data *data);
int dynsec__config_load(struct dynsec__data *data);
char *dynsec__config_to_json(struct dynsec__data *data);
+9 -1
View File
@@ -50,7 +50,11 @@ int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier, void **user_data, s
if(dynsec_data.config_file == NULL){
return MOSQ_ERR_NOMEM;
}
break;
}else if(!strcasecmp(options[i].key, "password_init_file")){
dynsec_data.password_init_file = mosquitto_strdup(options[i].value);
if(dynsec_data.password_init_file == NULL){
return MOSQ_ERR_NOMEM;
}
}
}
if(dynsec_data.config_file == NULL){
@@ -82,5 +86,9 @@ int mosquitto_plugin_cleanup(void *user_data, struct mosquitto_opt *options, int
mosquitto_free(dynsec_data.config_file);
dynsec_data.config_file = NULL;
mosquitto_free(dynsec_data.password_init_file);
dynsec_data.password_init_file = NULL;
return MOSQ_ERR_SUCCESS;
}
@@ -7,7 +7,6 @@ add_library(${PLUGIN_NAME} MODULE
target_include_directories(${PLUGIN_NAME} PRIVATE
"${STDBOOL_H_PATH}"
"${STDINT_H_PATH}"
"${mosquitto_SOURCE_DIR}"
"${mosquitto_SOURCE_DIR}/include"
)
@@ -7,7 +7,6 @@ add_library(${PLUGIN_NAME} MODULE
target_include_directories(${PLUGIN_NAME} PRIVATE
"${STDBOOL_H_PATH}"
"${STDINT_H_PATH}"
"${mosquitto_SOURCE_DIR}"
"${mosquitto_SOURCE_DIR}/deps"
"${mosquitto_SOURCE_DIR}/include"
)
@@ -7,7 +7,6 @@ add_library(${PLUGIN_NAME} MODULE
target_include_directories(${PLUGIN_NAME} PRIVATE
"${STDBOOL_H_PATH}"
"${STDINT_H_PATH}"
"${mosquitto_SOURCE_DIR}"
"${mosquitto_SOURCE_DIR}/include"
)
@@ -7,7 +7,6 @@ add_library(${PLUGIN_NAME} MODULE
target_include_directories(${PLUGIN_NAME} PRIVATE
"${STDBOOL_H_PATH}"
"${STDINT_H_PATH}"
"${mosquitto_SOURCE_DIR}"
"${mosquitto_SOURCE_DIR}/include"
)
@@ -7,7 +7,6 @@ add_library(${PLUGIN_NAME} MODULE
target_include_directories(${PLUGIN_NAME} PRIVATE
"${STDBOOL_H_PATH}"
"${STDINT_H_PATH}"
"${mosquitto_SOURCE_DIR}"
"${mosquitto_SOURCE_DIR}/include"
)
@@ -7,7 +7,6 @@ add_library(${PLUGIN_NAME} MODULE
target_include_directories(${PLUGIN_NAME} PRIVATE
"${STDBOOL_H_PATH}"
"${STDINT_H_PATH}"
"${mosquitto_SOURCE_DIR}"
"${mosquitto_SOURCE_DIR}/include"
)
-1
View File
@@ -2,7 +2,6 @@ if(SQLITE3_FOUND AND CJSON_FOUND)
set(CLIENT_INC
"${STDBOOL_H_PATH}"
"${STDINT_H_PATH}"
"${mosquitto_SOURCE_DIR}"
"${mosquitto_SOURCE_DIR}/deps"
"${mosquitto_SOURCE_DIR}/include"
"${mosquitto_SOURCE_DIR}/src"
+28 -11
View File
@@ -31,6 +31,8 @@ Contributors:
#include "persist_sqlite.h"
MOSQUITTO_PLUGIN_DECLARE_VERSION(5);
static mosquitto_plugin_id_t *plg_id = NULL;
static struct mosquitto_sqlite plg_data;
@@ -57,16 +59,32 @@ static void set_defaults(void)
plg_data.page_size = 4 * 1024;
}
int mosquitto_plugin_version(int supported_version_count, const int *supported_versions)
static int get_db_file(struct mosquitto_opt *options, int option_count)
{
const char *persistence_location;
int i;
for(i=0; i<supported_version_count; i++){
if(supported_versions[i] == 5){
return 5;
persistence_location = mosquitto_persistence_location();
if(persistence_location){
mkdir(persistence_location, 0770);
plg_data.db_file = malloc(strlen(persistence_location) + 1 + strlen("/mosquitto.sqlite3"));
if(!plg_data.db_file){
mosquitto_log_printf(MOSQ_LOG_INFO, "Sqlite persistence: Out of memory.");
return MOSQ_ERR_NOMEM;
}
sprintf(plg_data.db_file, "%s/mosquitto.sqlite3", persistence_location);
}else{
for(i=0; i<option_count; i++){
if(!strcasecmp(options[i].key, "db_file")){
plg_data.db_file = mosquitto_strdup(options[i].value);
if(plg_data.db_file == NULL){
return MOSQ_ERR_NOMEM;
}
}
}
}
return -1;
return MOSQ_ERR_SUCCESS;
}
int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier, void **user_data, struct mosquitto_opt *options, int option_count)
@@ -79,13 +97,12 @@ int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier, void **user_data, s
memset(&plg_data, 0,sizeof(struct mosquitto_sqlite));
set_defaults();
if(get_db_file(options, option_count)){
return MOSQ_ERR_UNKNOWN;
}
for(i=0; i<option_count; i++){
if(!strcasecmp(options[i].key, "db_file")){
plg_data.db_file = mosquitto_strdup(options[i].value);
if(plg_data.db_file == NULL){
return MOSQ_ERR_NOMEM;
}
}else if(!strcasecmp(options[i].key, "sync")){
if(!strcasecmp(options[i].key, "sync")){
if(!strcasecmp(options[i].value, "extra")){
plg_data.synchronous = 3;
}else if(!strcasecmp(options[i].value, "full")){
+2 -2
View File
@@ -1,4 +1,4 @@
persistence_location .
plugin ./mosquitto_persist_sqlite.so
plugin_opt_db_file test.sqlite3
plugin_opt_page_size 4096
plugin_opt_flush_period 5
plugin_opt_flush_period 5
+14 -7
View File
@@ -148,7 +148,9 @@ endif()
add_definitions (-DWITH_BROKER)
set (MOSQ_LIBS ${MOSQ_LIBS} ${OPENSSL_LIBRARIES})
if(WITH_TLS)
set (MOSQ_LIBS ${MOSQ_LIBS} OpenSSL::SSL)
endif()
# Check for getaddrinfo_a
include(CheckLibraryExists)
check_library_exists(anl getaddrinfo_a "" HAVE_GETADDRINFO_A)
@@ -186,7 +188,7 @@ endif()
if(WITH_WEBSOCKETS)
if(WITH_WEBSOCKETS_BUILTIN)
add_definitions("-DWITH_WEBSOCKETS=WS_IS_BUILTIN")
set(MOSQ_SRCS ${MOSQ_SRCS} ../deps/picohttpparser/picohttpparser.c)
set(MOSQ_SRCS ${MOSQ_SRCS} ${mosquitto_SOURCE_DIR}/deps/picohttpparser/picohttpparser.c)
else()
find_package(libwebsockets)
add_definitions("-DWITH_WEBSOCKETS=WS_IS_LWS")
@@ -225,11 +227,9 @@ endif()
target_include_directories(mosquitto
PUBLIC
"${mosquitto_SOURCE_DIR}/include"
"${OPENSSL_INCLUDE_DIR}"
PRIVATE
"${STDBOOL_H_PATH}"
"${STDINT_H_PATH}"
"${mosquitto_SOURCE_DIR}"
"${mosquitto_SOURCE_DIR}/common"
"${mosquitto_SOURCE_DIR}/lib"
"${mosquitto_SOURCE_DIR}/src"
@@ -241,8 +241,10 @@ if(WITH_BUNDLED_DEPS)
endif()
target_link_libraries(mosquitto
PRIVATE
${MOSQ_LIBS}
PUBLIC
config-header
PRIVATE
${MOSQ_LIBS}
)
if (WITH_THREADING AND NOT WIN32)
@@ -271,4 +273,9 @@ endif()
install(TARGETS mosquitto
RUNTIME DESTINATION "${CMAKE_INSTALL_SBINDIR}"
)
install(FILES ../include/mosquitto_broker.h ../include/mosquitto_plugin.h DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(
FILES
${mosquitto_SOURCE_DIR}/include/mosquitto_broker.h
${mosquitto_SOURCE_DIR}/include/mosquitto_plugin.h
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
)
+4
View File
@@ -49,6 +49,7 @@ Contributors:
#include "memory_mosq.h"
#include "packet_mosq.h"
#include "send_mosq.h"
#include "sys_tree.h"
#include "time_mosq.h"
#include "tls_mosq.h"
#include "util_mosq.h"
@@ -847,7 +848,10 @@ static void bridge__packet_cleanup(struct mosquitto *context)
}
context->out_packet = NULL;
context->out_packet_last = NULL;
G_OUT_PACKET_COUNT_DEC(context->out_packet_count);
G_OUT_PACKET_BYTES_DEC(context->out_packet_bytes);
context->out_packet_count = 0;
context->out_packet_bytes = 0;
packet__cleanup(&(context->in_packet));
}
+6 -3
View File
@@ -1365,12 +1365,12 @@ static int config__read_file_core(struct mosquitto__config *config, bool reload,
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Bridge support not available.");
#endif
}else if(!strcmp(token, "bridge_tcp_user_timeout")){
#if defined(WITH_BRIDGE) && defined(WITH_TCP_USER_TIMEOUT)
#ifdef WITH_BRIDGE
if(!cur_bridge){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid bridge configuration.");
return MOSQ_ERR_INVAL;
}
#ifdef TCP_USER_TIMEOUT
if(conf__parse_int(&token, "bridge_tcp_user_timeout", &tmp_int, &saveptr)) return MOSQ_ERR_INVAL;
if(tmp_int < 0) {
log__printf(NULL, MOSQ_LOG_ERR, "Error: invalid TCP user timeout value.");
@@ -1378,7 +1378,10 @@ static int config__read_file_core(struct mosquitto__config *config, bool reload,
}
cur_bridge->tcp_user_timeout = tmp_int;
#else
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Bridge and/or TCP user timeout support not available.");
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Bridge TCP user timeout support not available.");
#endif
#else
log__printf(NULL, MOSQ_LOG_WARNING, "Warning: Bridge support not available.");
#endif
}else if(!strcmp(token, "bridge_tls_use_os_certs")){
#if defined(WITH_BRIDGE) && defined(WITH_TLS)
+6 -1
View File
@@ -29,6 +29,7 @@ Contributors:
#include "memory_mosq.h"
#include "packet_mosq.h"
#include "property_mosq.h"
#include "sys_tree.h"
#include "time_mosq.h"
#include "util_mosq.h"
#include "will_mosq.h"
@@ -99,6 +100,7 @@ struct mosquitto *context__init(void)
packet__cleanup(&context->in_packet);
context->out_packet = NULL;
context->out_packet_count = 0;
context->out_packet_bytes = 0;
context->address = NULL;
context->bridge = NULL;
@@ -163,7 +165,10 @@ void context__cleanup(struct mosquitto *context, bool force_free)
context->out_packet = context->out_packet->next;
mosquitto__FREE(packet);
}
G_OUT_PACKET_COUNT_DEC(context->out_packet_count);
G_OUT_PACKET_BYTES_DEC(context->out_packet_bytes);
context->out_packet_count = 0;
context->out_packet_bytes = 0;
#if defined(WITH_BROKER) && defined(__GLIBC__) && defined(WITH_ADNS)
if(context->adns){
gai_cancel(context->adns);
@@ -219,7 +224,7 @@ void context__disconnect(struct mosquitto *context)
return;
}
#if defined(WITH_WEBSOCKETS) && WITH_WEBSOCKETS == LWS_IS_BUILTIN
#if defined(WITH_WEBSOCKETS) && WITH_WEBSOCKETS == WS_IS_BUILTIN
if(context->transport == mosq_t_ws){
uint8_t buf[4] = {0x88, 0x02, 0x03, context->wsd.disconnect_reason};
/* Send the disconnect reason, but don't care if it fails */
+110 -104
View File
@@ -460,6 +460,114 @@ static int check_protocol_version(struct mosquitto__listener *listener, int prot
}
#ifdef WITH_TLS
static int get_username_from_cert(struct mosquitto *context)
{
int i;
X509 *client_cert = NULL;
X509_NAME *name;
X509_NAME_ENTRY *name_entry;
ASN1_STRING *name_asn1 = NULL;
BIO *subject_bio;
char *data_start;
long name_length;
char *subject;
client_cert = SSL_get_peer_certificate(context->ssl);
if(!client_cert){
if(context->protocol == mosq_p_mqtt5){
send__connack(context, 0, MQTT_RC_BAD_USERNAME_OR_PASSWORD, NULL);
}else{
send__connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD, NULL);
}
return MOSQ_ERR_AUTH;
}
name = X509_get_subject_name(client_cert);
if(!name){
if(context->protocol == mosq_p_mqtt5){
send__connack(context, 0, MQTT_RC_BAD_USERNAME_OR_PASSWORD, NULL);
}else{
send__connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD, NULL);
}
X509_free(client_cert);
return MOSQ_ERR_AUTH;
}
if(context->listener->use_identity_as_username){ /* use_identity_as_username */
i = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
if(i == -1){
if(context->protocol == mosq_p_mqtt5){
send__connack(context, 0, MQTT_RC_BAD_USERNAME_OR_PASSWORD, NULL);
}else{
send__connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD, NULL);
}
X509_free(client_cert);
return MOSQ_ERR_AUTH;
}
name_entry = X509_NAME_get_entry(name, i);
if(name_entry){
name_asn1 = X509_NAME_ENTRY_get_data(name_entry);
if (name_asn1 == NULL) {
if(context->protocol == mosq_p_mqtt5){
send__connack(context, 0, MQTT_RC_BAD_USERNAME_OR_PASSWORD, NULL);
}else{
send__connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD, NULL);
}
X509_free(client_cert);
return MOSQ_ERR_AUTH;
}
#if OPENSSL_VERSION_NUMBER < 0x10100000L
context->username = mosquitto__strdup((char *) ASN1_STRING_data(name_asn1));
#else
context->username = mosquitto__strdup((char *) ASN1_STRING_get0_data(name_asn1));
#endif
if(!context->username){
if(context->protocol == mosq_p_mqtt5){
send__connack(context, 0, MQTT_RC_SERVER_UNAVAILABLE, NULL);
}else{
send__connack(context, 0, CONNACK_REFUSED_SERVER_UNAVAILABLE, NULL);
}
X509_free(client_cert);
return MOSQ_ERR_NOMEM;
}
/* Make sure there isn't an embedded NUL character in the CN */
if ((size_t)ASN1_STRING_length(name_asn1) != strlen(context->username)) {
if(context->protocol == mosq_p_mqtt5){
send__connack(context, 0, MQTT_RC_BAD_USERNAME_OR_PASSWORD, NULL);
}else{
send__connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD, NULL);
}
X509_free(client_cert);
return MOSQ_ERR_AUTH;
}
}
} else { /* use_subject_as_username */
subject_bio = BIO_new(BIO_s_mem());
X509_NAME_print_ex(subject_bio, X509_get_subject_name(client_cert), 0, XN_FLAG_RFC2253);
data_start = NULL;
name_length = BIO_get_mem_data(subject_bio, &data_start);
subject = mosquitto__malloc(sizeof(char)*(size_t)(name_length+1));
if(!subject){
BIO_free(subject_bio);
X509_free(client_cert);
return MOSQ_ERR_NOMEM;
}
memcpy(subject, data_start, (size_t)name_length);
subject[name_length] = '\0';
BIO_free(subject_bio);
context->username = subject;
}
if(!context->username){
X509_free(client_cert);
return MOSQ_ERR_AUTH;
}
X509_free(client_cert);
client_cert = NULL;
return MOSQ_ERR_SUCCESS;
}
#endif
int handle__connect(struct mosquitto *context)
{
char protocol_name[7];
@@ -479,17 +587,6 @@ int handle__connect(struct mosquitto *context)
void *auth_data_out = NULL;
uint16_t auth_data_out_len = 0;
bool allow_zero_length_clientid;
#ifdef WITH_TLS
int i;
X509 *client_cert = NULL;
X509_NAME *name;
X509_NAME_ENTRY *name_entry;
ASN1_STRING *name_asn1 = NULL;
BIO *subject_bio;
char *data_start;
long name_length;
char *subject;
#endif
G_CONNECTION_COUNT_INC();
@@ -807,96 +904,8 @@ int handle__connect(struct mosquitto *context)
}
}else{
#endif /* FINAL_WITH_TLS_PSK */
client_cert = SSL_get_peer_certificate(context->ssl);
if(!client_cert){
if(context->protocol == mosq_p_mqtt5){
send__connack(context, 0, MQTT_RC_BAD_USERNAME_OR_PASSWORD, NULL);
}else{
send__connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD, NULL);
}
rc = MOSQ_ERR_AUTH;
goto handle_connect_error;
}
name = X509_get_subject_name(client_cert);
if(!name){
if(context->protocol == mosq_p_mqtt5){
send__connack(context, 0, MQTT_RC_BAD_USERNAME_OR_PASSWORD, NULL);
}else{
send__connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD, NULL);
}
rc = MOSQ_ERR_AUTH;
goto handle_connect_error;
}
if (context->listener->use_identity_as_username) { /* use_identity_as_username */
i = X509_NAME_get_index_by_NID(name, NID_commonName, -1);
if(i == -1){
if(context->protocol == mosq_p_mqtt5){
send__connack(context, 0, MQTT_RC_BAD_USERNAME_OR_PASSWORD, NULL);
}else{
send__connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD, NULL);
}
rc = MOSQ_ERR_AUTH;
goto handle_connect_error;
}
name_entry = X509_NAME_get_entry(name, i);
if(name_entry){
name_asn1 = X509_NAME_ENTRY_get_data(name_entry);
if (name_asn1 == NULL) {
if(context->protocol == mosq_p_mqtt5){
send__connack(context, 0, MQTT_RC_BAD_USERNAME_OR_PASSWORD, NULL);
}else{
send__connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD, NULL);
}
rc = MOSQ_ERR_AUTH;
goto handle_connect_error;
}
#if OPENSSL_VERSION_NUMBER < 0x10100000L
context->username = mosquitto__strdup((char *) ASN1_STRING_data(name_asn1));
#else
context->username = mosquitto__strdup((char *) ASN1_STRING_get0_data(name_asn1));
#endif
if(!context->username){
if(context->protocol == mosq_p_mqtt5){
send__connack(context, 0, MQTT_RC_SERVER_UNAVAILABLE, NULL);
}else{
send__connack(context, 0, CONNACK_REFUSED_SERVER_UNAVAILABLE, NULL);
}
rc = MOSQ_ERR_NOMEM;
goto handle_connect_error;
}
/* Make sure there isn't an embedded NUL character in the CN */
if ((size_t)ASN1_STRING_length(name_asn1) != strlen(context->username)) {
if(context->protocol == mosq_p_mqtt5){
send__connack(context, 0, MQTT_RC_BAD_USERNAME_OR_PASSWORD, NULL);
}else{
send__connack(context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD, NULL);
}
rc = MOSQ_ERR_AUTH;
goto handle_connect_error;
}
}
} else { /* use_subject_as_username */
subject_bio = BIO_new(BIO_s_mem());
X509_NAME_print_ex(subject_bio, X509_get_subject_name(client_cert), 0, XN_FLAG_RFC2253);
data_start = NULL;
name_length = BIO_get_mem_data(subject_bio, &data_start);
subject = mosquitto__malloc(sizeof(char)*(size_t)(name_length+1));
if(!subject){
BIO_free(subject_bio);
rc = MOSQ_ERR_NOMEM;
goto handle_connect_error;
}
memcpy(subject, data_start, (size_t)name_length);
subject[name_length] = '\0';
BIO_free(subject_bio);
context->username = subject;
}
if(!context->username){
rc = MOSQ_ERR_AUTH;
goto handle_connect_error;
}
X509_free(client_cert);
client_cert = NULL;
rc = get_username_from_cert(context);
if(rc) goto handle_connect_error;
#ifdef FINAL_WITH_TLS_PSK
}
#endif /* FINAL_WITH_TLS_PSK */
@@ -1022,9 +1031,6 @@ handle_connect_error:
mosquitto__FREE(will_struct);
}
context->will = NULL;
#ifdef WITH_TLS
if(client_cert) X509_free(client_cert);
#endif
/* We return an error here which means the client is freed later on. */
context->clean_start = true;
context->session_expiry_interval = 0;
+2 -2
View File
@@ -57,7 +57,7 @@ Contributors:
extern int g_run;
#if defined(WITH_WEBSOCKETS) && WITH_WEBSOCKETS == WS_IS_WEBSOCKETS && LWS_LIBRARY_VERSION_NUMBER == 3002000
#if defined(WITH_WEBSOCKETS) && WITH_WEBSOCKETS == WS_IS_LWS && LWS_LIBRARY_VERSION_NUMBER == 3002000
void lws__sul_callback(struct lws_sorted_usec_list *l)
{
}
@@ -175,7 +175,7 @@ int mosquitto_main_loop(struct mosquitto__listener_sock *listensock, int listens
int rc;
#if defined(WITH_WEBSOCKETS) && WITH_WEBSOCKETS == WS_IS_WEBSOCKETS && LWS_LIBRARY_VERSION_NUMBER == 3002000
#if defined(WITH_WEBSOCKETS) && WITH_WEBSOCKETS == WS_IS_LWS && LWS_LIBRARY_VERSION_NUMBER == 3002000
memset(&sul, 0, sizeof(struct lws_sorted_usec_list));
#endif
-1
View File
@@ -977,7 +977,6 @@ int http__context_init(struct mosquitto *context);
int http__context_cleanup(struct mosquitto *context);
int http__read(struct mosquitto *context);
int http__write(struct mosquitto *context);
void ws__context_init(struct mosquitto *context);
#endif
void do_disconnect(struct mosquitto *context, int reason);
+3 -2
View File
@@ -323,6 +323,7 @@ BROKER_EXPORT int mosquitto_set_clientid(struct mosquitto *client, const char *c
struct mosquitto *found_client;
char *id_dup;
bool in_by_id;
int clientid_len;
if(!client || !clientid) return MOSQ_ERR_INVAL;
@@ -343,7 +344,7 @@ BROKER_EXPORT int mosquitto_set_clientid(struct mosquitto *client, const char *c
}
}
int clientid_len = (int)strlen(clientid);
clientid_len = (int)strlen(clientid);
if(mosquitto_validate_utf8(clientid, clientid_len)){
return MOSQ_ERR_INVAL;
}
@@ -601,7 +602,7 @@ BROKER_EXPORT int mosquitto_persist_client_delete(const char *client_id)
}
struct mosquitto_base_msg *find_store_msg(uint64_t store_id)
static struct mosquitto_base_msg *find_store_msg(uint64_t store_id)
{
struct mosquitto_base_msg *base_msg;
+16
View File
@@ -37,11 +37,13 @@ uint64_t g_bytes_received = 0;
uint64_t g_bytes_sent = 0;
uint64_t g_pub_bytes_received = 0;
uint64_t g_pub_bytes_sent = 0;
int64_t g_out_packet_bytes = 0;
unsigned long g_msgs_received = 0;
unsigned long g_msgs_sent = 0;
unsigned long g_pub_msgs_received = 0;
unsigned long g_pub_msgs_sent = 0;
unsigned long g_msgs_dropped = 0;
long g_out_packet_count = 0;
unsigned int g_clients_expired = 0;
unsigned int g_socket_connections = 0;
unsigned int g_connection_count = 0;
@@ -179,6 +181,8 @@ void sys_tree__update(void)
static int subscription_count = INT_MAX;
static int shared_subscription_count = INT_MAX;
static int retained_count = INT_MAX;
static long out_packet_count = LONG_MAX;
static long long out_packet_bytes = LLONG_MAX;
static double msgs_received_load1 = 0;
static double msgs_received_load5 = 0;
@@ -391,6 +395,18 @@ void sys_tree__update(void)
db__messages_easy_queue(NULL, "$SYS/broker/publish/bytes/sent", SYS_TREE_QOS, len, buf, 1, 60, NULL);
}
if(out_packet_count != g_out_packet_count){
out_packet_count = g_out_packet_count;
len = (uint32_t)snprintf(buf, BUFLEN, "%lu", out_packet_count);
db__messages_easy_queue(NULL, "$SYS/broker/packet/out/count", SYS_TREE_QOS, len, buf, 1, 60, NULL);
}
if(out_packet_bytes != g_out_packet_bytes){
out_packet_bytes = g_out_packet_bytes;
len = (uint32_t)snprintf(buf, BUFLEN, "%llu", out_packet_bytes);
db__messages_easy_queue(NULL, "$SYS/broker/packet/out/bytes", SYS_TREE_QOS, len, buf, 1, 60, NULL);
}
last_update = db.now_s;
}
}
+10
View File
@@ -24,11 +24,13 @@ extern uint64_t g_bytes_received;
extern uint64_t g_bytes_sent;
extern uint64_t g_pub_bytes_received;
extern uint64_t g_pub_bytes_sent;
extern int64_t g_out_packet_bytes;
extern unsigned long g_msgs_received;
extern unsigned long g_msgs_sent;
extern unsigned long g_pub_msgs_received;
extern unsigned long g_pub_msgs_sent;
extern unsigned long g_msgs_dropped;
extern long g_out_packet_count;
extern unsigned int g_clients_expired;
extern unsigned int g_socket_connections;
extern unsigned int g_connection_count;
@@ -45,6 +47,10 @@ extern unsigned int g_connection_count;
#define G_CLIENTS_EXPIRED_INC() (g_clients_expired++)
#define G_SOCKET_CONNECTIONS_INC() (g_socket_connections++)
#define G_CONNECTION_COUNT_INC() (g_connection_count++)
#define G_OUT_PACKET_COUNT_INC(A) (g_out_packet_count+=(A))
#define G_OUT_PACKET_COUNT_DEC(A) (g_out_packet_count-=(A))
#define G_OUT_PACKET_BYTES_INC(A) (g_out_packet_bytes+=(A))
#define G_OUT_PACKET_BYTES_DEC(A) (g_out_packet_bytes-=(A))
#else
@@ -60,6 +66,10 @@ extern unsigned int g_connection_count;
#define G_CLIENTS_EXPIRED_INC()
#define G_SOCKET_CONNECTIONS_INC()
#define G_CONNECTION_COUNT_INC()
#define G_OUT_PACKET_COUNT_INC(A)
#define G_OUT_PACKET_COUNT_DEC(A)
#define G_OUT_PACKET_BYTES_INC(A)
#define G_OUT_PACKET_BYTES_DEC(A)
#endif
+1 -7
View File
@@ -43,13 +43,7 @@ static void client_cost(FILE *fptr, struct mosquitto *context, int fn_index)
long tBytes;
pkt_count = 1;
pkt_bytes = context->in_packet.packet_length;
pkt_tmp = context->out_packet;
while(pkt_tmp){
pkt_count++;
pkt_bytes += pkt_tmp->packet_length;
pkt_tmp = pkt_tmp->next;
}
pkt_bytes = context->in_packet.packet_length + context->out_packet_bytes;
cmsg_count = context->msgs_in.inflight_count + context->msgs_in.queued_count;
cmsg_bytes = context->msgs_in.inflight_bytes + context->msgs_in.queued_bytes;
+4
View File
@@ -0,0 +1,4 @@
add_subdirectory(broker)
add_subdirectory(client)
add_subdirectory(lib)
add_subdirectory(unit)
+4 -5
View File
@@ -37,7 +37,7 @@ def do_test():
# Try to open an 11th connection
try:
sock_bad = mosq_test.do_client_connect(connect_packet_bad, connack_packet_bad, port=port)
except ConnectionResetError:
except (ConnectionResetError, BrokenPipeError):
# Expected behaviour
pass
@@ -50,7 +50,7 @@ def do_test():
# Try to open an 11th connection
try:
sock_bad = mosq_test.do_client_connect(connect_packet_bad, connack_packet_bad, port=port)
except ConnectionResetError:
except (ConnectionResetError, BrokenPipeError):
# Expected behaviour
pass
@@ -68,7 +68,6 @@ def do_test():
(stdo, stde) = broker.communicate()
if rc:
print(stde.decode('utf-8'))
exit(rc)
return rc
do_test()
exit(0)
sys.exit(do_test())
@@ -36,7 +36,7 @@ def do_test():
# Try to open an 11th connection
try:
sock_bad = mosq_test.do_client_connect(connect_packet_bad, connack_packet_bad, port=port)
except ConnectionResetError:
except (ConnectionResetError, BrokenPipeError):
# Expected behaviour
pass
@@ -53,7 +53,7 @@ def do_test():
# Try to open an 11th connection
try:
sock_bad = mosq_test.do_client_connect(connect_packet_bad, connack_packet_bad, port=port)
except ConnectionResetError:
except (ConnectionResetError, BrokenPipeError):
# Expected behaviour
pass
@@ -75,7 +75,6 @@ def do_test():
(stdo, stde) = broker.communicate()
if rc:
print(stde.decode('utf-8'))
exit(rc)
return rc
do_test()
exit(0)
sys.exit(do_test())
+4 -5
View File
@@ -36,7 +36,7 @@ def do_test():
# Try to open an 11th connection
try:
sock_bad = mosq_test.do_client_connect(connect_packet_bad, connack_packet_bad, port=port)
except ConnectionResetError:
except (ConnectionResetError, BrokenPipeError):
# Expected behaviour
pass
@@ -53,7 +53,7 @@ def do_test():
# Try to open an 11th connection
try:
sock_bad = mosq_test.do_client_connect(connect_packet_bad, connack_packet_bad, port=port)
except ConnectionResetError:
except (ConnectionResetError, BrokenPipeError):
# Expected behaviour
pass
@@ -75,7 +75,6 @@ def do_test():
(stdo, stde) = broker.communicate()
if rc:
print(stde.decode('utf-8'))
exit(rc)
return rc
do_test()
exit(0)
sys.exit(do_test())
@@ -8,7 +8,7 @@ from mosq_test_helper import *
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
f.write("password_file %s\n" % (filename.replace('.conf', '.pwfile')))
f.write("password_file %s/%s\n" % (Path(__file__).resolve().parent, filename.replace('.conf', '.pwfile')))
f.write("allow_anonymous false\n")
+1 -1
View File
@@ -12,7 +12,7 @@ def write_config(filename, port, allow_anonymous, password_file):
else:
f.write("allow_anonymous false\n")
if password_file:
f.write("password_file %s\n" % (filename.replace('.conf', '.pwfile')))
f.write("password_file %s/%s\n" % (Path(__file__).resolve().parent, filename.replace('.conf', '.pwfile')))
def do_test(allow_anonymous, password_file, username, expect_success):
port = mosq_test.get_port()
@@ -8,7 +8,7 @@ from mosq_test_helper import *
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
f.write("password_file %s\n" % (filename.replace('.conf', '.pwfile')))
f.write("password_file %s/%s\n" % (Path(__file__).resolve().parent, filename.replace('.conf', '.pwfile')))
f.write("allow_anonymous false\n")

Some files were not shown because too many files have changed in this diff Show More