mirror of
https://github.com/eclipse-mosquitto/mosquitto.git
synced 2026-09-22 08:04:23 +08:00
Merge branch 'develop' into NorbertHeusser:develop
This commit is contained in:
+20
-1
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
@@ -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
@@ -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}")
|
||||
|
||||
@@ -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}")
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "plugin_common.h"
|
||||
#include "json_help.h"
|
||||
#include <mqtt_protocol.h>
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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")){
|
||||
|
||||
@@ -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
@@ -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}"
|
||||
)
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
add_subdirectory(broker)
|
||||
add_subdirectory(client)
|
||||
add_subdirectory(lib)
|
||||
add_subdirectory(unit)
|
||||
@@ -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())
|
||||
|
||||
@@ -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")
|
||||
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user