diff --git a/plugins/Makefile b/plugins/Makefile index f039b2c4..51d5670c 100644 --- a/plugins/Makefile +++ b/plugins/Makefile @@ -1,5 +1,6 @@ DIRS= \ auth-by-ip \ + deny-protocol-version \ dynamic-security \ message-timestamp \ payload-modification diff --git a/plugins/deny-protocol-version/CMakeLists.txt b/plugins/deny-protocol-version/CMakeLists.txt new file mode 100644 index 00000000..d998df75 --- /dev/null +++ b/plugins/deny-protocol-version/CMakeLists.txt @@ -0,0 +1,24 @@ +set (PLUGIN_NAME mosquitto_deny_protocol_version) + +add_library(${PLUGIN_NAME} MODULE + ${PLUGIN_NAME}.c +) + +target_include_directories(${PLUGIN_NAME} PRIVATE + "${OPENSSL_INCLUDE_DIR}" + "${STDBOOL_H_PATH} ${STDINT_H_PATH}" + "${mosquitto_SOURCE_DIR}" + "${mosquitto_SOURCE_DIR}/include" +) + +set_target_properties(${PLUGIN_NAME} PROPERTIES + PREFIX "" + POSITION_INDEPENDENT_CODE 1 +) + +if(WIN32) + target_link_libraries(${PLUGIN_NAME} PRIVATE mosquitto) +endif() + +# Don't install, these are example plugins only. +#install(TARGETS ${PLUGIN_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") diff --git a/plugins/deny-protocol-version/Makefile b/plugins/deny-protocol-version/Makefile new file mode 100644 index 00000000..42e6c806 --- /dev/null +++ b/plugins/deny-protocol-version/Makefile @@ -0,0 +1,29 @@ +R=../.. +include ${R}/config.mk + +.PHONY : all binary check clean reallyclean test install uninstall + +PLUGIN_NAME=mosquitto_deny_protocol_version +PLUGIN_CFLAGS+=-I${R}/include -I${R}/ + +all : binary + +binary : ${PLUGIN_NAME}.so + +${PLUGIN_NAME}.so : ${PLUGIN_NAME}.c + $(CROSS_COMPILE)$(CC) $(PLUGIN_CPPFLAGS) $(PLUGIN_CFLAGS) $(PLUGIN_LDFLAGS) -fPIC -shared $< -o $@ + +reallyclean : clean +clean: + -rm -f *.o ${PLUGIN_NAME}.so *.gcda *.gcno + +check: test +test: + +install: ${PLUGIN_NAME}.so + # Don't install, these are examples only. + #$(INSTALL) -d "${DESTDIR}$(libdir)" + #$(INSTALL) ${STRIP_OPTS} ${PLUGIN_NAME}.so "${DESTDIR}${libdir}/${PLUGIN_NAME}.so" + +uninstall : + -rm -f "${DESTDIR}${libdir}/${PLUGIN_NAME}.so" diff --git a/plugins/deny-protocol-version/mosquitto_deny_protocol_version.c b/plugins/deny-protocol-version/mosquitto_deny_protocol_version.c new file mode 100644 index 00000000..191cf710 --- /dev/null +++ b/plugins/deny-protocol-version/mosquitto_deny_protocol_version.c @@ -0,0 +1,110 @@ +/* +Copyright (c) 2022 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License 2.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + https://www.eclipse.org/legal/epl-2.0/ +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +SPDX-License-Identifier: EPL-2.0 OR EDL-1.0 + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +/* + * This is an example plugin showing how to deny access based on the version of + * the protocol spec a client connects with. It does no other authentication + * checks. + * + * It could be used with other authentication plugins by specifying it in the + * config file before another plugin, for example: + * + * plugin /usr/lib/mosquitto_deny_protocol_version.so + * plugin /usr/lib/mosquitto_dynamic_security.so + * + * or: + * + * plugin /usr/lib/mosquitto_deny_protocol_version.so + * password_file pwfile + * + * It will *not* work on its own. + * + * In Mosquitto 2.1, this can be achieved with the `accept_protocol_version` + * option instead. + * + * + * To compile: + * + * gcc -I -fPIC -shared mosquitto_deny_protocol_version.c -o mosquitto_deny_protocol_version.so + * + * Note that this only works on Mosquitto 2.0 or later. + */ +#include "config.h" + +#include +#include + +#include "mosquitto_broker.h" +#include "mosquitto_plugin.h" +#include "mosquitto.h" +#include "mqtt_protocol.h" + +static mosquitto_plugin_id_t *mosq_pid = NULL; + +int mosquitto_plugin_version(int supported_version_count, const int *supported_versions) +{ + int i; + + for(i=0; iclient); + + if(protocol_version == 5 || protocol_version == 4){ + /* Allow access to MQTT v5.0 and v3.1.1 - this passes on responsibility + * for the actual auth checks to the next plugin/password file in the + * config list. If no other plugins/password file is defined, then + * access will be denied. */ + return MOSQ_ERR_PLUGIN_DEFER; + }else{ + /* Deny access to all others */ + return MOSQ_ERR_AUTH; + } +} + +int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier, void **user_data, struct mosquitto_opt *opts, int opt_count) +{ + UNUSED(user_data); + UNUSED(opts); + UNUSED(opt_count); + + mosq_pid = identifier; + return mosquitto_callback_register(mosq_pid, MOSQ_EVT_BASIC_AUTH, basic_auth_callback, NULL, NULL); +} + +int mosquitto_plugin_cleanup(void *user_data, struct mosquitto_opt *opts, int opt_count) +{ + UNUSED(user_data); + UNUSED(opts); + UNUSED(opt_count); + + return mosquitto_callback_unregister(mosq_pid, MOSQ_EVT_MESSAGE, basic_auth_callback, NULL); +} diff --git a/plugins/deny-protocol-version/test.conf b/plugins/deny-protocol-version/test.conf new file mode 100644 index 00000000..01021314 --- /dev/null +++ b/plugins/deny-protocol-version/test.conf @@ -0,0 +1,4 @@ +listener 1883 + +plugin ./mosquitto_deny_protocol_version.so +password_file pwfile diff --git a/plugins/deny-protocol-version/test.sh b/plugins/deny-protocol-version/test.sh new file mode 100755 index 00000000..3005da50 --- /dev/null +++ b/plugins/deny-protocol-version/test.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +../../apps/mosquitto_passwd/mosquitto_passwd -c -b pwfile username password +../../src/mosquitto -c test.conf -v