From cbbc4a0ea30b658b8b77e4195ddc400f0c7e4c6b Mon Sep 17 00:00:00 2001 From: Frank Villaro-Dixon Date: Mon, 23 May 2022 22:20:59 +0200 Subject: [PATCH] Auth: add authentication via env variable This commit provides a "cloud-native" way of authenticating clients by comparing the provided password to the MOSQUITTO_PASSWORD environment variable. This allows to quickly and easily adding authentication by simply providing the password to the environment variable of the docker container / kubernetes pod. Signed-off-by: Frank Villaro-Dixon --- plugins/CMakeLists.txt | 1 + plugins/auth-by-env/CMakeLists.txt | 11 +++ plugins/auth-by-env/mosquitto_auth_by_env.c | 104 ++++++++++++++++++++ 3 files changed, 116 insertions(+) create mode 100644 plugins/auth-by-env/CMakeLists.txt create mode 100644 plugins/auth-by-env/mosquitto_auth_by_env.c diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 2ecbadb2..ad2b3220 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(auth-by-env) add_subdirectory(dynamic-security) add_subdirectory(persist-sqlite) add_subdirectory(examples) diff --git a/plugins/auth-by-env/CMakeLists.txt b/plugins/auth-by-env/CMakeLists.txt new file mode 100644 index 00000000..d8214e7d --- /dev/null +++ b/plugins/auth-by-env/CMakeLists.txt @@ -0,0 +1,11 @@ +include_directories(${mosquitto_SOURCE_DIR} ${mosquitto_SOURCE_DIR}/include + ${OPENSSL_INCLUDE_DIR} ${STDBOOL_H_PATH} ${STDINT_H_PATH}) + +add_library(mosquitto_auth_by_env MODULE mosquitto_auth_by_env.c) +set_target_properties(mosquitto_auth_by_env PROPERTIES + POSITION_INDEPENDENT_CODE 1 +) +set_target_properties(mosquitto_auth_by_env PROPERTIES PREFIX "") + +# Don't install, these are example plugins only. XXX +#install(TARGETS mosquitto_auth_by_env RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") diff --git a/plugins/auth-by-env/mosquitto_auth_by_env.c b/plugins/auth-by-env/mosquitto_auth_by_env.c new file mode 100644 index 00000000..c81cefaf --- /dev/null +++ b/plugins/auth-by-env/mosquitto_auth_by_env.c @@ -0,0 +1,104 @@ +/* +Copyright (c) 2021 Frank Villaro-Dixon + +This plugin is under the WTFPL. Do what you want with it. + +SPDX-License-Identifier: WTFPL + +Contributors: + Frank Villaro-Dixon - initial implementation and documentation. +*/ + +/* + * This plugin allows users to authenticate with any username, as long as + * the provided password matches the MOSQUITTO_PASSWORD environment variable. + * If the MOSQUITTO_PASSWORD env variable is empty, then authentication is rejected. + * + * Compile with: + * gcc -I -fPIC -shared mosquitto_auth_by_env.c -o mosquitto_auth_by_env.so + * + * Use in config with: + * + * plugin /path/to/mosquitto_auth_by_env.so + * + * Note that this only works on Mosquitto 2.0 or later. + */ +#include "config.h" + +#include +#include +#include + +#include "mosquitto_broker.h" +#include "mosquitto_plugin.h" +#include "mosquitto.h" +#include "mqtt_protocol.h" + +#define ENV_MOSQUITTO_PASSWORD "MOSQUITTO_PASSWORD" + +static mosquitto_plugin_id_t *mosq_pid = NULL; +static char *environment_password; + +static int basic_auth_callback(int event, void *event_data, void *userdata) +{ + struct mosquitto_evt_basic_auth *ed = event_data; + + UNUSED(event); + UNUSED(userdata); + + if(!environment_password || !ed->password){ + return MOSQ_ERR_PLUGIN_DEFER; + } + if(!strcmp(ed->password, environment_password)){ + /* Password matched MOSQUITTO_PASSWORD */ + return MOSQ_ERR_SUCCESS; + } + else{ + return MOSQ_ERR_PLUGIN_DEFER; + } +} + +int mosquitto_plugin_version(int supported_version_count, const int *supported_versions) +{ + int i; + + for(i=0; i 0){ + environment_password = strdup(env_var_content); + return mosquitto_callback_register(mosq_pid, MOSQ_EVT_BASIC_AUTH, basic_auth_callback, NULL, NULL); + } + } + + log__printf(NULL, MOSQ_LOG_INFO, "Auth-by-env plugin called, but "ENV_MOSQUITTO_PASSWORD" env var is empty\n"); + return 0; +} + +int mosquitto_plugin_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count) +{ + UNUSED(user_data); + UNUSED(opts); + UNUSED(opt_count); + + free(environment_password); + + return mosquitto_callback_unregister(mosq_pid, MOSQ_EVT_BASIC_AUTH, basic_auth_callback, NULL); +}