Implement plugin wrappers for v2, v3, v4

This means the internal plugin interface is simpler and is translated to each of the older interfaces if needed.
pull/2438/head
Roger Light 4 years ago
parent cd07f1136b
commit dcff8dfd38

@ -43,7 +43,8 @@ set (MOSQ_SRCS
persist_read_v234.c persist_read_v5.c persist_read.c
persist_write_v5.c persist_write.c
persist.h
plugin.c plugin_connect.c plugin_disconnect.c plugin_message.c plugin_public.c plugin_tick.c
plugin.c plugin_v4.c plugin_v3.c plugin_v2.c
plugin_connect.c plugin_disconnect.c plugin_message.c plugin_public.c plugin_tick.c
property_broker.c
../lib/property_mosq.c ../lib/property_mosq.h
read_handle.c

@ -56,6 +56,9 @@ OBJS= mosquitto.o \
persist_write.o \
persist_write_v5.o \
plugin.o \
plugin_v2.o \
plugin_v3.o \
plugin_v4.o \
plugin_connect.o \
plugin_disconnect.o \
plugin_message.o \
@ -258,6 +261,15 @@ property_mosq.o : ../lib/property_mosq.c ../lib/property_mosq.h
plugin.o : plugin.c ../include/mosquitto_plugin.h mosquitto_broker_internal.h
${CROSS_COMPILE}${CC} $(BROKER_CPPFLAGS) $(BROKER_CFLAGS) -c $< -o $@
plugin_v2.o : plugin_v2.c ../include/mosquitto_plugin.h mosquitto_broker_internal.h
${CROSS_COMPILE}${CC} $(BROKER_CPPFLAGS) $(BROKER_CFLAGS) -c $< -o $@
plugin_v3.o : plugin_v3.c ../include/mosquitto_plugin.h mosquitto_broker_internal.h
${CROSS_COMPILE}${CC} $(BROKER_CPPFLAGS) $(BROKER_CFLAGS) -c $< -o $@
plugin_v4.o : plugin_v4.c ../include/mosquitto_plugin.h mosquitto_broker_internal.h
${CROSS_COMPILE}${CC} $(BROKER_CPPFLAGS) $(BROKER_CFLAGS) -c $< -o $@
plugin_connect.o : plugin_connect.c ../include/mosquitto_plugin.h mosquitto_broker_internal.h
${CROSS_COMPILE}${CC} $(BROKER_CPPFLAGS) $(BROKER_CFLAGS) -c $< -o $@

@ -830,6 +830,11 @@ void listeners__stop(void);
* Plugin related functions
* ============================================================ */
int plugin__load_v5(struct mosquitto__listener *listener, struct mosquitto__plugin *plugin, struct mosquitto_opt *auth_options, int auth_option_count, void *lib);
int plugin__load_v4(struct mosquitto__listener *listener, struct mosquitto__plugin_config *plugin_config, void *lib);
int plugin__load_v3(struct mosquitto__listener *listener, struct mosquitto__plugin_config *plugin_config, void *lib);
int plugin__load_v2(struct mosquitto__listener *listener, struct mosquitto__plugin_config *plugin_config, void *lib);
int acl__pre_check(struct mosquitto__plugin_config *plugin, struct mosquitto *context, int access);
void plugin__handle_connect(struct mosquitto *context);
void plugin__handle_disconnect(struct mosquitto *context, int reason);
int plugin__handle_message(struct mosquitto *context, struct mosquitto_msg_store *stored);

@ -0,0 +1,219 @@
/*
Copyright (c) 2011-2021 Roger Light <roger@atchoo.org>
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 BSD-3-Clause
Contributors:
Roger Light - initial implementation and documentation.
*/
/* This loads v2 plugins in a v5 wrapper to make the core code cleaner */
#include "config.h"
#include <stdio.h>
#include <string.h>
#include "mosquitto_broker.h"
#include "mosquitto_broker_internal.h"
#include "mosquitto_plugin.h"
#include "memory_mosq.h"
#include "lib_load.h"
#include "utlist.h"
typedef int (*FUNC_auth_plugin_version)(void);
typedef int (*FUNC_plugin_version)(int, const int *);
static int plugin_v2_basic_auth(int event, void *event_data, void *userdata)
{
struct mosquitto__plugin_config *plugin_config = userdata;
struct mosquitto_evt_basic_auth *ed = event_data;
UNUSED(event);
if(plugin_config->plugin.unpwd_check_v2 == NULL){
return MOSQ_ERR_INVAL;
}
return plugin_config->plugin.unpwd_check_v2(
plugin_config->plugin.user_data,
ed->username,
ed->password);
}
static int plugin_v2_acl_check(int event, void *event_data, void *userdata)
{
struct mosquitto__plugin_config *plugin_config = userdata;
struct mosquitto_evt_acl_check *ed = event_data;
int rc;
UNUSED(event);
if(plugin_config->plugin.acl_check_v2 == NULL){
return MOSQ_ERR_INVAL;
}
rc = acl__pre_check(plugin_config, ed->client, ed->access);
if(rc == MOSQ_ERR_PLUGIN_DEFER){
return plugin_config->plugin.acl_check_v2(
plugin_config->plugin.user_data,
ed->client->id,
ed->client->username,
ed->topic,
ed->access);
}else{
return rc;
}
}
static int plugin_v2_psk_key_get(int event, void *event_data, void *userdata)
{
struct mosquitto__plugin_config *plugin_config = userdata;
struct mosquitto_evt_psk_key *ed = event_data;
UNUSED(event);
if(plugin_config->plugin.psk_key_get_v2 == NULL){
return MOSQ_ERR_INVAL;
}
return plugin_config->plugin.psk_key_get_v2(
plugin_config->plugin.user_data,
ed->hint,
ed->identity,
ed->key,
ed->max_key_len);
}
static int plugin_v2_reload(int event, void *event_data, void *userdata)
{
struct mosquitto__plugin_config *plugin_config = userdata;
int rc;
UNUSED(event);
UNUSED(event_data);
rc = plugin_config->plugin.security_cleanup_v2(
plugin_config->plugin.user_data,
(struct mosquitto_auth_opt *)plugin_config->options,
plugin_config->option_count,
true);
if(rc) return rc;
rc = plugin_config->plugin.security_init_v2(
plugin_config->plugin.user_data,
(struct mosquitto_auth_opt *)plugin_config->options,
plugin_config->option_count,
true);
return rc;
}
int plugin__load_v2(struct mosquitto__listener *listener, struct mosquitto__plugin_config *plugin_config, void *lib)
{
mosquitto_plugin_id_t *pid;
int rc;
if(!(plugin_config->plugin.plugin_init_v2 = (FUNC_auth_plugin_init_v2)LIB_SYM(lib, "mosquitto_auth_plugin_init"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_plugin_init().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin_config->plugin.plugin_cleanup_v2 = (FUNC_auth_plugin_cleanup_v2)LIB_SYM(lib, "mosquitto_auth_plugin_cleanup"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_plugin_cleanup().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin_config->plugin.security_init_v2 = (FUNC_auth_plugin_security_init_v2)LIB_SYM(lib, "mosquitto_auth_security_init"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_security_init().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin_config->plugin.security_cleanup_v2 = (FUNC_auth_plugin_security_cleanup_v2)LIB_SYM(lib, "mosquitto_auth_security_cleanup"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_security_cleanup().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin_config->plugin.acl_check_v2 = (FUNC_auth_plugin_acl_check_v2)LIB_SYM(lib, "mosquitto_auth_acl_check"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_acl_check().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin_config->plugin.unpwd_check_v2 = (FUNC_auth_plugin_unpwd_check_v2)LIB_SYM(lib, "mosquitto_auth_unpwd_check"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_unpwd_check().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin_config->plugin.psk_key_get_v2 = (FUNC_auth_plugin_psk_key_get_v2)LIB_SYM(lib, "mosquitto_auth_psk_key_get"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_psk_key_get().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
pid = mosquitto__calloc(1, sizeof(mosquitto_plugin_id_t));
if(pid == NULL){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
LIB_CLOSE(lib);
return MOSQ_ERR_NOMEM;
}
pid->listener = listener;
plugin_config->plugin.lib = lib;
plugin_config->plugin.user_data = NULL;
plugin_config->plugin.identifier = pid;
if(plugin_config->plugin.plugin_init_v2){
rc = plugin_config->plugin.plugin_init_v2(
&plugin_config->plugin.user_data,
(struct mosquitto_auth_opt *)plugin_config->options,
plugin_config->option_count);
if(rc){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Authentication plugin returned %d when initialising.", rc);
return rc;
}
}
mosquitto_callback_register(pid, MOSQ_EVT_RELOAD, plugin_v2_reload, NULL, plugin_config);
if(plugin_config->plugin.unpwd_check_v2){
mosquitto_callback_register(pid, MOSQ_EVT_BASIC_AUTH, plugin_v2_basic_auth, NULL, plugin_config);
}
if(plugin_config->plugin.acl_check_v2){
mosquitto_callback_register(pid, MOSQ_EVT_ACL_CHECK, plugin_v2_acl_check, NULL, plugin_config);
}
if(plugin_config->plugin.psk_key_get_v2){
mosquitto_callback_register(pid, MOSQ_EVT_PSK_KEY, plugin_v2_psk_key_get, NULL, plugin_config);
}
return 0;
}

@ -0,0 +1,226 @@
/*
Copyright (c) 2011-2021 Roger Light <roger@atchoo.org>
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 BSD-3-Clause
Contributors:
Roger Light - initial implementation and documentation.
*/
/* This loads v3 plugins in a v5 wrapper to make the core code cleaner */
#include "config.h"
#include <stdio.h>
#include <string.h>
#include "mosquitto_broker.h"
#include "mosquitto_broker_internal.h"
#include "mosquitto_plugin.h"
#include "memory_mosq.h"
#include "lib_load.h"
#include "utlist.h"
typedef int (*FUNC_auth_plugin_version)(void);
typedef int (*FUNC_plugin_version)(int, const int *);
static int plugin_v3_basic_auth(int event, void *event_data, void *userdata)
{
struct mosquitto__plugin_config *plugin_config = userdata;
struct mosquitto_evt_basic_auth *ed = event_data;
UNUSED(event);
if(plugin_config->plugin.unpwd_check_v3 == NULL){
return MOSQ_ERR_INVAL;
}
return plugin_config->plugin.unpwd_check_v3(
plugin_config->plugin.user_data,
ed->client,
ed->username,
ed->password);
}
static int plugin_v3_acl_check(int event, void *event_data, void *userdata)
{
struct mosquitto__plugin_config *plugin_config = userdata;
struct mosquitto_evt_acl_check *ed = event_data;
struct mosquitto_acl_msg msg;
int rc;
UNUSED(event);
if(plugin_config->plugin.acl_check_v3 == NULL){
return MOSQ_ERR_INVAL;
}
memset(&msg, 0, sizeof(msg));
msg.topic = ed->topic;
msg.payloadlen = ed->payloadlen;
msg.payload = ed->payload;
msg.qos = ed->qos;
msg.retain = ed->retain;
rc = acl__pre_check(plugin_config, ed->client, ed->access);
if(rc == MOSQ_ERR_PLUGIN_DEFER){
return plugin_config->plugin.acl_check_v3(
plugin_config->plugin.user_data,
ed->access,
ed->client,
&msg);
}else{
return rc;
}
}
static int plugin_v3_psk_key_get(int event, void *event_data, void *userdata)
{
struct mosquitto__plugin_config *plugin_config = userdata;
struct mosquitto_evt_psk_key *ed = event_data;
UNUSED(event);
if(plugin_config->plugin.psk_key_get_v3 == NULL){
return MOSQ_ERR_INVAL;
}
return plugin_config->plugin.psk_key_get_v3(
plugin_config->plugin.user_data,
ed->client,
ed->hint,
ed->identity,
ed->key,
ed->max_key_len);
}
static int plugin_v3_reload(int event, void *event_data, void *userdata)
{
struct mosquitto__plugin_config *plugin_config = userdata;
int rc;
UNUSED(event);
UNUSED(event_data);
rc = plugin_config->plugin.security_cleanup_v3(
plugin_config->plugin.user_data,
plugin_config->options,
plugin_config->option_count,
true);
if(rc) return rc;
rc = plugin_config->plugin.security_init_v3(
plugin_config->plugin.user_data,
plugin_config->options,
plugin_config->option_count,
true);
return rc;
}
int plugin__load_v3(struct mosquitto__listener *listener, struct mosquitto__plugin_config *plugin_config, void *lib)
{
mosquitto_plugin_id_t *pid;
int rc;
if(!(plugin_config->plugin.plugin_init_v3 = (FUNC_auth_plugin_init_v3)LIB_SYM(lib, "mosquitto_auth_plugin_init"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_plugin_init().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin_config->plugin.plugin_cleanup_v3 = (FUNC_auth_plugin_cleanup_v3)LIB_SYM(lib, "mosquitto_auth_plugin_cleanup"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_plugin_cleanup().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin_config->plugin.security_init_v3 = (FUNC_auth_plugin_security_init_v3)LIB_SYM(lib, "mosquitto_auth_security_init"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_security_init().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin_config->plugin.security_cleanup_v3 = (FUNC_auth_plugin_security_cleanup_v3)LIB_SYM(lib, "mosquitto_auth_security_cleanup"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_security_cleanup().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin_config->plugin.acl_check_v3 = (FUNC_auth_plugin_acl_check_v3)LIB_SYM(lib, "mosquitto_auth_acl_check"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_acl_check().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin_config->plugin.unpwd_check_v3 = (FUNC_auth_plugin_unpwd_check_v3)LIB_SYM(lib, "mosquitto_auth_unpwd_check"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_unpwd_check().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin_config->plugin.psk_key_get_v3 = (FUNC_auth_plugin_psk_key_get_v3)LIB_SYM(lib, "mosquitto_auth_psk_key_get"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_psk_key_get().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
pid = mosquitto__calloc(1, sizeof(mosquitto_plugin_id_t));
if(pid == NULL){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
LIB_CLOSE(lib);
return MOSQ_ERR_NOMEM;
}
pid->listener = listener;
plugin_config->plugin.lib = lib;
plugin_config->plugin.user_data = NULL;
plugin_config->plugin.identifier = pid;
if(plugin_config->plugin.plugin_init_v3){
rc = plugin_config->plugin.plugin_init_v3(&plugin_config->plugin.user_data, plugin_config->options, plugin_config->option_count);
if(rc){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Authentication plugin returned %d when initialising.", rc);
return rc;
}
}
mosquitto_callback_register(pid, MOSQ_EVT_RELOAD, plugin_v3_reload, NULL, plugin_config);
if(plugin_config->plugin.unpwd_check_v3){
mosquitto_callback_register(pid, MOSQ_EVT_BASIC_AUTH, plugin_v3_basic_auth, NULL, plugin_config);
}
if(plugin_config->plugin.acl_check_v3){
mosquitto_callback_register(pid, MOSQ_EVT_ACL_CHECK, plugin_v3_acl_check, NULL, plugin_config);
}
if(plugin_config->plugin.psk_key_get_v3){
mosquitto_callback_register(pid, MOSQ_EVT_PSK_KEY, plugin_v3_psk_key_get, NULL, plugin_config);
}
return 0;
}

@ -0,0 +1,293 @@
/*
Copyright (c) 2011-2021 Roger Light <roger@atchoo.org>
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 BSD-3-Clause
Contributors:
Roger Light - initial implementation and documentation.
*/
/* This loads v4 plugins in a v5 wrapper to make the core code cleaner */
#include "config.h"
#include <stdio.h>
#include <string.h>
#include "mosquitto_broker.h"
#include "mosquitto_broker_internal.h"
#include "mosquitto_plugin.h"
#include "memory_mosq.h"
#include "lib_load.h"
#include "utlist.h"
typedef int (*FUNC_auth_plugin_version)(void);
typedef int (*FUNC_plugin_version)(int, const int *);
static int plugin_v4_basic_auth(int event, void *event_data, void *userdata)
{
struct mosquitto__plugin_config *plugin_config = userdata;
struct mosquitto_evt_basic_auth *ed = event_data;
UNUSED(event);
if(plugin_config->plugin.unpwd_check_v4 == NULL){
return MOSQ_ERR_PLUGIN_DEFER;
}
return plugin_config->plugin.unpwd_check_v4(
plugin_config->plugin.user_data,
ed->client,
ed->username,
ed->password);
}
static int plugin_v4_acl_check(int event, void *event_data, void *userdata)
{
struct mosquitto__plugin_config *plugin_config = userdata;
struct mosquitto_evt_acl_check *ed = event_data;
struct mosquitto_acl_msg msg;
int rc;
UNUSED(event);
if(plugin_config->plugin.acl_check_v4 == NULL){
return MOSQ_ERR_PLUGIN_DEFER;
}
memset(&msg, 0, sizeof(msg));
msg.topic = ed->topic;
msg.payloadlen = ed->payloadlen;
msg.payload = ed->payload;
msg.qos = ed->qos;
msg.retain = ed->retain;
rc = acl__pre_check(plugin_config, ed->client, ed->access);
if(rc == MOSQ_ERR_PLUGIN_DEFER){
return plugin_config->plugin.acl_check_v4(
plugin_config->plugin.user_data,
ed->access,
ed->client,
&msg);
}else{
return rc;
}
}
static int plugin_v4_auth_start(int event, void *event_data, void *userdata)
{
struct mosquitto__plugin_config *plugin_config = userdata;
struct mosquitto_evt_extended_auth *ed = event_data;
UNUSED(event);
if(plugin_config->plugin.auth_start_v4 == NULL){
return MOSQ_ERR_PLUGIN_DEFER;
}
return plugin_config->plugin.auth_start_v4(
plugin_config->plugin.user_data,
ed->client,
ed->client->auth_method,
false,
ed->data_in, ed->data_in_len,
&ed->data_out, &ed->data_out_len);
}
static int plugin_v4_auth_continue(int event, void *event_data, void *userdata)
{
struct mosquitto__plugin_config *plugin_config = userdata;
struct mosquitto_evt_extended_auth *ed = event_data;
UNUSED(event);
if(plugin_config->plugin.auth_continue_v4 == NULL){
return MOSQ_ERR_PLUGIN_DEFER;
}
return plugin_config->plugin.auth_continue_v4(
plugin_config->plugin.user_data,
ed->client,
ed->client->auth_method,
ed->data_in, ed->data_in_len,
&ed->data_out, &ed->data_out_len);
}
static int plugin_v4_psk_key_get(int event, void *event_data, void *userdata)
{
struct mosquitto__plugin_config *plugin_config = userdata;
struct mosquitto_evt_psk_key *ed = event_data;
UNUSED(event);
if(plugin_config->plugin.psk_key_get_v4 == NULL){
return MOSQ_ERR_PLUGIN_DEFER;
}
return plugin_config->plugin.psk_key_get_v4(
plugin_config->plugin.user_data,
ed->client,
ed->hint,
ed->identity,
ed->key,
ed->max_key_len);
}
static int plugin_v4_reload(int event, void *event_data, void *userdata)
{
struct mosquitto__plugin_config *plugin_config = userdata;
int rc;
UNUSED(event);
UNUSED(event_data);
rc = plugin_config->plugin.security_cleanup_v4(
plugin_config->plugin.user_data,
plugin_config->options,
plugin_config->option_count,
true);
if(rc) return rc;
rc = plugin_config->plugin.security_init_v4(
plugin_config->plugin.user_data,
plugin_config->options,
plugin_config->option_count,
true);
return rc;
}
int plugin__load_v4(struct mosquitto__listener *listener, struct mosquitto__plugin_config *plugin_config, void *lib)
{
int rc;
mosquitto_plugin_id_t *pid;
if(!(plugin_config->plugin.plugin_init_v4 = (FUNC_auth_plugin_init_v4)LIB_SYM(lib, "mosquitto_auth_plugin_init"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_plugin_init().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin_config->plugin.plugin_cleanup_v4 = (FUNC_auth_plugin_cleanup_v4)LIB_SYM(lib, "mosquitto_auth_plugin_cleanup"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_plugin_cleanup().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin_config->plugin.security_init_v4 = (FUNC_auth_plugin_security_init_v4)LIB_SYM(lib, "mosquitto_auth_security_init"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_security_init().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin_config->plugin.security_cleanup_v4 = (FUNC_auth_plugin_security_cleanup_v4)LIB_SYM(lib, "mosquitto_auth_security_cleanup"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_security_cleanup().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin_config->plugin.acl_check_v4 = (FUNC_auth_plugin_acl_check_v4)LIB_SYM(lib, "mosquitto_auth_acl_check"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_acl_check().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
plugin_config->plugin.unpwd_check_v4 = (FUNC_auth_plugin_unpwd_check_v4)LIB_SYM(lib, "mosquitto_auth_unpwd_check");
if(plugin_config->plugin.unpwd_check_v4){
log__printf(NULL, MOSQ_LOG_INFO,
" ├── Username/password checking enabled.");
}else{
log__printf(NULL, MOSQ_LOG_INFO,
" ├── Username/password checking not enabled.");
}
plugin_config->plugin.psk_key_get_v4 = (FUNC_auth_plugin_psk_key_get_v4)LIB_SYM(lib, "mosquitto_auth_psk_key_get");
if(plugin_config->plugin.psk_key_get_v4){
log__printf(NULL, MOSQ_LOG_INFO,
" ├── TLS-PSK checking enabled.");
}else{
log__printf(NULL, MOSQ_LOG_INFO,
" ├── TLS-PSK checking not enabled.");
}
plugin_config->plugin.auth_start_v4 = (FUNC_auth_plugin_auth_start_v4)LIB_SYM(lib, "mosquitto_auth_start");
plugin_config->plugin.auth_continue_v4 = (FUNC_auth_plugin_auth_continue_v4)LIB_SYM(lib, "mosquitto_auth_continue");
if(plugin_config->plugin.auth_start_v4){
if(plugin_config->plugin.auth_continue_v4){
log__printf(NULL, MOSQ_LOG_INFO,
" └── Extended authentication enabled.");
}else{
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Plugin has missing mosquitto_auth_continue() function.");
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
}else{
log__printf(NULL, MOSQ_LOG_INFO,
" └── Extended authentication not enabled.");
}
pid = mosquitto__calloc(1, sizeof(mosquitto_plugin_id_t));
if(pid == NULL){
log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory.");
LIB_CLOSE(lib);
return MOSQ_ERR_NOMEM;
}
pid->listener = listener;
plugin_config->plugin.lib = lib;
plugin_config->plugin.user_data = NULL;
plugin_config->plugin.identifier = pid;
if(plugin_config->plugin.plugin_init_v4){
rc = plugin_config->plugin.plugin_init_v4(&plugin_config->plugin.user_data, plugin_config->options, plugin_config->option_count);
if(rc){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Authentication plugin returned %d when initialising.", rc);
return rc;
}
}
mosquitto_callback_register(pid, MOSQ_EVT_RELOAD, plugin_v4_reload, NULL, plugin_config);
if(plugin_config->plugin.unpwd_check_v4){
mosquitto_callback_register(pid, MOSQ_EVT_BASIC_AUTH, plugin_v4_basic_auth, NULL, plugin_config);
}
if(plugin_config->plugin.acl_check_v4){
mosquitto_callback_register(pid, MOSQ_EVT_ACL_CHECK, plugin_v4_acl_check, NULL, plugin_config);
}
if(plugin_config->plugin.auth_start_v4){
mosquitto_callback_register(pid, MOSQ_EVT_EXT_AUTH_START, plugin_v4_auth_start, NULL, plugin_config);
}
if(plugin_config->plugin.auth_continue_v4){
mosquitto_callback_register(pid, MOSQ_EVT_EXT_AUTH_CONTINUE, plugin_v4_auth_continue, NULL, plugin_config);
}
if(plugin_config->plugin.psk_key_get_v4){
mosquitto_callback_register(pid, MOSQ_EVT_PSK_KEY, plugin_v4_psk_key_get, NULL, plugin_config);
}
return 0;
}

@ -47,246 +47,6 @@ void LIB_ERROR(void)
}
static int security__load_v2(struct mosquitto__plugin *plugin, struct mosquitto_auth_opt *auth_options, int auth_option_count, void *lib)
{
int rc;
if(!(plugin->plugin_init_v2 = (FUNC_auth_plugin_init_v2)LIB_SYM(lib, "mosquitto_auth_plugin_init"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_plugin_init().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin->plugin_cleanup_v2 = (FUNC_auth_plugin_cleanup_v2)LIB_SYM(lib, "mosquitto_auth_plugin_cleanup"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_plugin_cleanup().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin->security_init_v2 = (FUNC_auth_plugin_security_init_v2)LIB_SYM(lib, "mosquitto_auth_security_init"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_security_init().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin->security_cleanup_v2 = (FUNC_auth_plugin_security_cleanup_v2)LIB_SYM(lib, "mosquitto_auth_security_cleanup"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_security_cleanup().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin->acl_check_v2 = (FUNC_auth_plugin_acl_check_v2)LIB_SYM(lib, "mosquitto_auth_acl_check"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_acl_check().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin->unpwd_check_v2 = (FUNC_auth_plugin_unpwd_check_v2)LIB_SYM(lib, "mosquitto_auth_unpwd_check"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_unpwd_check().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin->psk_key_get_v2 = (FUNC_auth_plugin_psk_key_get_v2)LIB_SYM(lib, "mosquitto_auth_psk_key_get"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_psk_key_get().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
plugin->lib = lib;
plugin->user_data = NULL;
if(plugin->plugin_init_v2){
rc = plugin->plugin_init_v2(&plugin->user_data, auth_options, auth_option_count);
if(rc){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Authentication plugin returned %d when initialising.", rc);
return rc;
}
}
return 0;
}
static int security__load_v3(struct mosquitto__plugin *plugin, struct mosquitto_opt *auth_options, int auth_option_count, void *lib)
{
int rc;
if(!(plugin->plugin_init_v3 = (FUNC_auth_plugin_init_v3)LIB_SYM(lib, "mosquitto_auth_plugin_init"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_plugin_init().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin->plugin_cleanup_v3 = (FUNC_auth_plugin_cleanup_v3)LIB_SYM(lib, "mosquitto_auth_plugin_cleanup"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_plugin_cleanup().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin->security_init_v3 = (FUNC_auth_plugin_security_init_v3)LIB_SYM(lib, "mosquitto_auth_security_init"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_security_init().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin->security_cleanup_v3 = (FUNC_auth_plugin_security_cleanup_v3)LIB_SYM(lib, "mosquitto_auth_security_cleanup"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_security_cleanup().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin->acl_check_v3 = (FUNC_auth_plugin_acl_check_v3)LIB_SYM(lib, "mosquitto_auth_acl_check"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_acl_check().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin->unpwd_check_v3 = (FUNC_auth_plugin_unpwd_check_v3)LIB_SYM(lib, "mosquitto_auth_unpwd_check"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_unpwd_check().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin->psk_key_get_v3 = (FUNC_auth_plugin_psk_key_get_v3)LIB_SYM(lib, "mosquitto_auth_psk_key_get"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_psk_key_get().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
plugin->lib = lib;
plugin->user_data = NULL;
if(plugin->plugin_init_v3){
rc = plugin->plugin_init_v3(&plugin->user_data, auth_options, auth_option_count);
if(rc){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Authentication plugin returned %d when initialising.", rc);
return rc;
}
}
return 0;
}
static int security__load_v4(struct mosquitto__plugin *plugin, struct mosquitto_opt *auth_options, int auth_option_count, void *lib)
{
int rc;
if(!(plugin->plugin_init_v4 = (FUNC_auth_plugin_init_v4)LIB_SYM(lib, "mosquitto_auth_plugin_init"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_plugin_init().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin->plugin_cleanup_v4 = (FUNC_auth_plugin_cleanup_v4)LIB_SYM(lib, "mosquitto_auth_plugin_cleanup"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_plugin_cleanup().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin->security_init_v4 = (FUNC_auth_plugin_security_init_v4)LIB_SYM(lib, "mosquitto_auth_security_init"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_security_init().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin->security_cleanup_v4 = (FUNC_auth_plugin_security_cleanup_v4)LIB_SYM(lib, "mosquitto_auth_security_cleanup"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_security_cleanup().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
if(!(plugin->acl_check_v4 = (FUNC_auth_plugin_acl_check_v4)LIB_SYM(lib, "mosquitto_auth_acl_check"))){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unable to load auth plugin function mosquitto_auth_acl_check().");
LIB_ERROR();
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
plugin->unpwd_check_v4 = (FUNC_auth_plugin_unpwd_check_v4)LIB_SYM(lib, "mosquitto_auth_unpwd_check");
if(plugin->unpwd_check_v4){
log__printf(NULL, MOSQ_LOG_INFO,
" ├── Username/password checking enabled.");
}else{
log__printf(NULL, MOSQ_LOG_INFO,
" ├── Username/password checking not enabled.");
}
plugin->psk_key_get_v4 = (FUNC_auth_plugin_psk_key_get_v4)LIB_SYM(lib, "mosquitto_auth_psk_key_get");
if(plugin->psk_key_get_v4){
log__printf(NULL, MOSQ_LOG_INFO,
" ├── TLS-PSK checking enabled.");
}else{
log__printf(NULL, MOSQ_LOG_INFO,
" ├── TLS-PSK checking not enabled.");
}
plugin->auth_start_v4 = (FUNC_auth_plugin_auth_start_v4)LIB_SYM(lib, "mosquitto_auth_start");
plugin->auth_continue_v4 = (FUNC_auth_plugin_auth_continue_v4)LIB_SYM(lib, "mosquitto_auth_continue");
if(plugin->auth_start_v4){
if(plugin->auth_continue_v4){
log__printf(NULL, MOSQ_LOG_INFO,
" └── Extended authentication enabled.");
}else{
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Plugin has missing mosquitto_auth_continue() function.");
LIB_CLOSE(lib);
return MOSQ_ERR_UNKNOWN;
}
}else{
log__printf(NULL, MOSQ_LOG_INFO,
" └── Extended authentication not enabled.");
}
plugin->lib = lib;
plugin->user_data = NULL;
if(plugin->plugin_init_v4){
rc = plugin->plugin_init_v4(&plugin->user_data, auth_options, auth_option_count);
if(rc){
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Authentication plugin returned %d when initialising.", rc);
return rc;
}
}
return 0;
}
static int security__module_init_single(struct mosquitto__listener *listener, struct mosquitto__security_options *opts)
{
void *lib;
@ -341,35 +101,14 @@ static int security__module_init_single(struct mosquitto__listener *listener, st
return rc;
}
}else if(version == 4){
rc = security__load_v4(
&opts->plugin_configs[i].plugin,
opts->plugin_configs[i].options,
opts->plugin_configs[i].option_count,
lib);
if(rc){
return rc;
}
rc = plugin__load_v4(listener, &opts->plugin_configs[i], lib);
if(rc) return rc;
}else if(version == 3){
rc = security__load_v3(
&opts->plugin_configs[i].plugin,
opts->plugin_configs[i].options,
opts->plugin_configs[i].option_count,
lib);
if(rc){
return rc;
}
rc = plugin__load_v3(listener, &opts->plugin_configs[i], lib);
if(rc) return rc;
}else if(version == 2){
rc = security__load_v2(
&opts->plugin_configs[i].plugin,
(struct mosquitto_auth_opt *)opts->plugin_configs[i].options,
opts->plugin_configs[i].option_count,
lib);
if(rc){
return rc;
}
rc = plugin__load_v2(listener, &opts->plugin_configs[i], lib);
if(rc) return rc;
}else{
log__printf(NULL, MOSQ_LOG_ERR,
"Error: Unsupported auth plugin version (got %d, expected %d).",
@ -419,17 +158,6 @@ static void security__module_cleanup_single(struct mosquitto__security_options *
conf->options,
conf->option_count);
}
plugin__callback_unregister_all(conf->plugin.identifier);
mosquitto__free(conf->plugin.identifier->plugin_name);
mosquitto__free(conf->plugin.identifier->plugin_version);
DL_FOREACH_SAFE(conf->plugin.identifier->control_endpoints, ep, tmp){
DL_DELETE(conf->plugin.identifier->control_endpoints, ep);
mosquitto__free(ep);
}
mosquitto__free(conf->plugin.identifier);
conf->plugin.identifier = NULL;
}else if(conf->plugin.version == 4){
conf->plugin.plugin_cleanup_v4(
conf->plugin.user_data,
@ -449,6 +177,18 @@ static void security__module_cleanup_single(struct mosquitto__security_options *
conf->option_count);
}
plugin__callback_unregister_all(conf->plugin.identifier);
if(conf->plugin.identifier){
mosquitto__free(conf->plugin.identifier->plugin_name);
mosquitto__free(conf->plugin.identifier->plugin_version);
DL_FOREACH_SAFE(conf->plugin.identifier->control_endpoints, ep, tmp){
DL_DELETE(conf->plugin.identifier->control_endpoints, ep);
mosquitto__free(ep);
}
mosquitto__free(conf->plugin.identifier);
conf->plugin.identifier = NULL;
}
if(conf->plugin.lib){
LIB_CLOSE(conf->plugin.lib);
}
@ -610,11 +350,9 @@ int mosquitto_security_cleanup(bool reload)
}
/* int mosquitto_acl_check(struct mosquitto *context, const char *topic, int access) */
static int acl__check_single(struct mosquitto__plugin_config *plugin, struct mosquitto *context, struct mosquitto_acl_msg *msg, int access)
int acl__pre_check(struct mosquitto__plugin_config *plugin, struct mosquitto *context, int access)
{
const char *username;
const char *topic = msg->topic;
username = mosquitto_client_username(context);
if(plugin->deny_special_chars == true){
@ -638,20 +376,16 @@ static int acl__check_single(struct mosquitto__plugin_config *plugin, struct mos
if(access == MOSQ_ACL_UNSUBSCRIBE){
return MOSQ_ERR_SUCCESS;
}
return plugin->plugin.acl_check_v4(plugin->plugin.user_data, access, context, msg);
}else if(plugin->plugin.version == 3){
if(access == MOSQ_ACL_UNSUBSCRIBE){
return MOSQ_ERR_SUCCESS;
}
return plugin->plugin.acl_check_v3(plugin->plugin.user_data, access, context, msg);
}else if(plugin->plugin.version == 2){
if(access == MOSQ_ACL_SUBSCRIBE || access == MOSQ_ACL_UNSUBSCRIBE){
return MOSQ_ERR_SUCCESS;
}
return plugin->plugin.acl_check_v2(plugin->plugin.user_data, context->id, username, topic, access);
}else{
return MOSQ_ERR_INVAL;
}
return MOSQ_ERR_PLUGIN_DEFER;
}
@ -728,9 +462,6 @@ int mosquitto_acl_check(struct mosquitto *context, const char *topic, uint32_t p
{
int rc;
int rc_final;
int i;
struct mosquitto__security_options *opts;
struct mosquitto_acl_msg msg;
if(!context->id){
return MOSQ_ERR_ACL_DENIED;
@ -779,30 +510,6 @@ int mosquitto_acl_check(struct mosquitto *context, const char *topic, uint32_t p
}else{
return MOSQ_ERR_ACL_DENIED;
}
opts = &context->listener->security_options;
}else{
opts = &db.config->security_options;
}
/* Old plugin version checks */
memset(&msg, 0, sizeof(msg));
msg.topic = topic;
msg.payloadlen = payloadlen;
msg.payload = payload;
msg.qos = qos;
msg.retain = retain;
for(i=0; i<opts->plugin_config_count; i++){
if(opts->plugin_configs[i].plugin.version < 5){
rc = acl__check_single(&opts->plugin_configs[i], context, &msg, access);
if(rc == MOSQ_ERR_PLUGIN_IGNORE){
/* Do nothing, this is as if the plugin doesn't exist */
}else if(rc == MOSQ_ERR_PLUGIN_DEFER){
rc_final = MOSQ_ERR_PLUGIN_DEFER;
}else{
return rc;
}
}
}
/* If all plugins deferred, this is a denial. If rc == MOSQ_ERR_SUCCESS
@ -842,19 +549,8 @@ static int plugin__unpwd_check(struct mosquitto__security_options *opts, struct
int mosquitto_unpwd_check(struct mosquitto *context)
{
int rc;
int i;
struct mosquitto__security_options *opts;
bool plugin_used = false;
if(db.config->per_listener_settings){
if(context->listener == NULL){
return MOSQ_ERR_AUTH;
}
opts = &context->listener->security_options;
}else{
opts = &db.config->security_options;
}
/* Global plugins */
if(db.config->security_options.plugin_callbacks.basic_auth){
rc = plugin__unpwd_check(&db.config->security_options, context);
@ -886,46 +582,6 @@ int mosquitto_unpwd_check(struct mosquitto *context)
}
}
/* Old plugin checks */
for(i=0; i<opts->plugin_config_count; i++){
if(opts->plugin_configs[i].plugin.version == 5){
continue;
}else if(opts->plugin_configs[i].plugin.version == 4){
if(opts->plugin_configs[i].plugin.unpwd_check_v4){
rc = opts->plugin_configs[i].plugin.unpwd_check_v4(
opts->plugin_configs[i].plugin.user_data,
context,
context->username,
context->password);
}else{
rc = MOSQ_ERR_PLUGIN_IGNORE;
}
}else if(opts->plugin_configs[i].plugin.version == 3){
rc = opts->plugin_configs[i].plugin.unpwd_check_v3(
opts->plugin_configs[i].plugin.user_data,
context,
context->username,
context->password);
}else if(opts->plugin_configs[i].plugin.version == 2){
rc = opts->plugin_configs[i].plugin.unpwd_check_v2(
opts->plugin_configs[i].plugin.user_data,
context->username,
context->password);
}else{
rc = MOSQ_ERR_INVAL;
}
if(rc == MOSQ_ERR_PLUGIN_IGNORE){
/* Do nothing */
}else if(rc == MOSQ_ERR_PLUGIN_DEFER){
plugin_used = true;
}else{
return rc;
}
}
/* If all plugins deferred, this is a denial. plugin_used == false
* here, then no plugins were configured.
* anonymous logins are allowed. */
@ -985,17 +641,6 @@ int mosquitto_psk_key_get(struct mosquitto *context, const char *hint, const cha
{
int rc;
int rc_final = MOSQ_ERR_SUCCESS;
int i;
struct mosquitto__security_options *opts;
if(db.config->per_listener_settings){
if(context->listener == NULL){
return MOSQ_ERR_AUTH;
}
opts = &context->listener->security_options;
}else{
opts = &db.config->security_options;
}
/* Global plugins */
if(db.config->security_options.plugin_callbacks.psk_key){
@ -1030,47 +675,6 @@ int mosquitto_psk_key_get(struct mosquitto *context, const char *hint, const cha
}
}
/* Old plugins */
for(i=0; i<opts->plugin_config_count; i++){
if(opts->plugin_configs[i].plugin.version == 4
&& opts->plugin_configs[i].plugin.psk_key_get_v4){
rc = opts->plugin_configs[i].plugin.psk_key_get_v4(
opts->plugin_configs[i].plugin.user_data,
context,
hint,
identity,
key,
max_key_len);
}else if(opts->plugin_configs[i].plugin.version == 3){
rc = opts->plugin_configs[i].plugin.psk_key_get_v3(
opts->plugin_configs[i].plugin.user_data,
context,
hint,
identity,
key,
max_key_len);
}else if(opts->plugin_configs[i].plugin.version == 2){
rc = opts->plugin_configs[i].plugin.psk_key_get_v2(
opts->plugin_configs[i].plugin.user_data,
hint,
identity,
key,
max_key_len);
}else{
rc = MOSQ_ERR_INVAL;
}
if(rc == MOSQ_ERR_PLUGIN_IGNORE){
/* Do nothing */
}else if(rc == MOSQ_ERR_PLUGIN_DEFER){
rc_final = MOSQ_ERR_PLUGIN_DEFER;
}else{
return rc;
}
}
rc = mosquitto_psk_key_get_default(context, hint, identity, key, max_key_len);
if(rc != MOSQ_ERR_PLUGIN_DEFER){
return rc;
@ -1128,21 +732,10 @@ static int plugin__ext_auth_start(struct mosquitto__security_options *opts, stru
int mosquitto_security_auth_start(struct mosquitto *context, bool reauth, const void *data_in, uint16_t data_in_len, void **data_out, uint16_t *data_out_len)
{
int rc;
int i;
struct mosquitto__security_options *opts;
if(!context || !context->listener || !context->auth_method) return MOSQ_ERR_INVAL;
if(!data_out || !data_out_len) return MOSQ_ERR_INVAL;
if(db.config->per_listener_settings){
if(context->listener == NULL){
return MOSQ_ERR_AUTH;
}
opts = &context->listener->security_options;
}else{
opts = &db.config->security_options;
}
/* Global plugins */
if(db.config->security_options.plugin_callbacks.ext_auth_start){
rc = plugin__ext_auth_start(&db.config->security_options, context,
@ -1172,30 +765,6 @@ int mosquitto_security_auth_start(struct mosquitto *context, bool reauth, const
}
}
/* Old plugins */
for(i=0; i<opts->plugin_config_count; i++){
if(opts->plugin_configs[i].plugin.auth_start_v4){
*data_out = NULL;
*data_out_len = 0;
rc = opts->plugin_configs[i].plugin.auth_start_v4(
opts->plugin_configs[i].plugin.user_data,
context,
context->auth_method,
reauth,
data_in, data_in_len,
data_out, data_out_len);
if(rc == MOSQ_ERR_SUCCESS){
return MOSQ_ERR_SUCCESS;
}else if(rc == MOSQ_ERR_AUTH_CONTINUE){
return MOSQ_ERR_AUTH_CONTINUE;
}else if(rc != MOSQ_ERR_NOT_SUPPORTED){
return rc;
}
}
}
return MOSQ_ERR_NOT_SUPPORTED;
}
@ -1230,21 +799,10 @@ static int plugin__ext_auth_continue(struct mosquitto__security_options *opts, s
int mosquitto_security_auth_continue(struct mosquitto *context, const void *data_in, uint16_t data_in_len, void **data_out, uint16_t *data_out_len)
{
int rc;
int i;
struct mosquitto__security_options *opts;
if(!context || !context->listener || !context->auth_method) return MOSQ_ERR_INVAL;
if(!data_out || !data_out_len) return MOSQ_ERR_INVAL;
if(db.config->per_listener_settings){
if(context->listener == NULL){
return MOSQ_ERR_AUTH;
}
opts = &context->listener->security_options;
}else{
opts = &db.config->security_options;
}
/* Global plugins */
if(db.config->security_options.plugin_callbacks.ext_auth_continue){
rc = plugin__ext_auth_continue(&db.config->security_options, context,
@ -1274,28 +832,5 @@ int mosquitto_security_auth_continue(struct mosquitto *context, const void *data
}
}
/* Old plugins */
for(i=0; i<opts->plugin_config_count; i++){
if(opts->plugin_configs[i].plugin.auth_continue_v4){
*data_out = NULL;
*data_out_len = 0;
rc = opts->plugin_configs[i].plugin.auth_continue_v4(
opts->plugin_configs[i].plugin.user_data,
context,
context->auth_method,
data_in, data_in_len,
data_out, data_out_len);
if(rc == MOSQ_ERR_SUCCESS){
return MOSQ_ERR_SUCCESS;
}else if(rc == MOSQ_ERR_AUTH_CONTINUE){
return MOSQ_ERR_AUTH_CONTINUE;
}else if(rc != MOSQ_ERR_NOT_SUPPORTED){
return rc;
}
}
}
return MOSQ_ERR_NOT_SUPPORTED;
}

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# Test whether a connection is successful with correct username and password
# when using a simple auth_plugin.
from mosq_test_helper import *
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
f.write("auth_plugin c/auth_plugin_v3.so\n")
f.write("allow_anonymous false\n")
port = mosq_test.get_port()
conf_file = os.path.basename(__file__).replace('.py', '.conf')
write_config(conf_file, port)
rc = 1
keepalive = 10
connect_packet = mosq_test.gen_connect("connect-uname-pwd-test", keepalive=keepalive, username="test-username", password="wrong")
connack_packet = mosq_test.gen_connack(rc=5)
broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port)
try:
sock = mosq_test.do_client_connect(connect_packet, connack_packet, timeout=20, port=port)
rc = 0
sock.close()
except mosq_test.TestError:
pass
finally:
os.remove(conf_file)
broker.terminate()
broker.wait()
(stdo, stde) = broker.communicate()
if rc:
print(stde.decode('utf-8'))
exit(rc)

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# Test whether a connection is successful with correct username and password
# when using a simple auth_plugin.
from mosq_test_helper import *
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
f.write("auth_plugin c/auth_plugin_v3.so\n")
f.write("allow_anonymous false\n")
port = mosq_test.get_port()
conf_file = os.path.basename(__file__).replace('.py', '.conf')
write_config(conf_file, port)
rc = 1
keepalive = 10
connect_packet = mosq_test.gen_connect("connect-uname-pwd-test", keepalive=keepalive, username="test-username", password="cnwTICONIURW")
connack_packet = mosq_test.gen_connack(rc=0)
broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port)
try:
sock = mosq_test.do_client_connect(connect_packet, connack_packet, timeout=20, port=port)
rc = 0
sock.close()
except mosq_test.TestError:
pass
finally:
os.remove(conf_file)
broker.terminate()
broker.wait()
(stdo, stde) = broker.communicate()
if rc:
print(stde.decode('utf-8'))
exit(rc)

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# Test whether a connection is successful with correct username and password
# when using a simple auth_plugin.
from mosq_test_helper import *
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
f.write("auth_plugin c/auth_plugin_v4.so\n")
f.write("allow_anonymous false\n")
port = mosq_test.get_port()
conf_file = os.path.basename(__file__).replace('.py', '.conf')
write_config(conf_file, port)
rc = 1
keepalive = 10
connect_packet = mosq_test.gen_connect("connect-uname-pwd-test", keepalive=keepalive, username="test-username", password="wrong")
connack_packet = mosq_test.gen_connack(rc=5)
broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port)
try:
sock = mosq_test.do_client_connect(connect_packet, connack_packet, timeout=20, port=port)
rc = 0
sock.close()
except mosq_test.TestError:
pass
finally:
os.remove(conf_file)
broker.terminate()
broker.wait()
(stdo, stde) = broker.communicate()
if rc:
print(stde.decode('utf-8'))
exit(rc)

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# Test whether a connection is successful with correct username and password
# when using a simple auth_plugin.
from mosq_test_helper import *
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
f.write("auth_plugin c/auth_plugin_v4.so\n")
f.write("allow_anonymous false\n")
port = mosq_test.get_port()
conf_file = os.path.basename(__file__).replace('.py', '.conf')
write_config(conf_file, port)
rc = 1
keepalive = 10
connect_packet = mosq_test.gen_connect("connect-uname-pwd-test", keepalive=keepalive, username="test-username", password="cnwTICONIURW")
connack_packet = mosq_test.gen_connack(rc=0)
broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port)
try:
sock = mosq_test.do_client_connect(connect_packet, connack_packet, timeout=20, port=port)
rc = 0
sock.close()
except mosq_test.TestError:
pass
finally:
os.remove(conf_file)
broker.terminate()
broker.wait()
(stdo, stde) = broker.communicate()
if rc:
print(stde.decode('utf-8'))
exit(rc)

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# Test whether a connection is successful with correct username and password
# when using a simple auth_plugin.
from mosq_test_helper import *
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
f.write("auth_plugin c/auth_plugin_v5.so\n")
f.write("allow_anonymous false\n")
port = mosq_test.get_port()
conf_file = os.path.basename(__file__).replace('.py', '.conf')
write_config(conf_file, port)
rc = 1
keepalive = 10
connect_packet = mosq_test.gen_connect("connect-uname-pwd-test", keepalive=keepalive, username="test-username", password="wrong")
connack_packet = mosq_test.gen_connack(rc=5)
broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port)
try:
sock = mosq_test.do_client_connect(connect_packet, connack_packet, timeout=20, port=port)
rc = 0
sock.close()
except mosq_test.TestError:
pass
finally:
os.remove(conf_file)
broker.terminate()
broker.wait()
(stdo, stde) = broker.communicate()
if rc:
print(stde.decode('utf-8'))
exit(rc)

@ -0,0 +1,40 @@
#!/usr/bin/env python3
# Test whether a connection is successful with correct username and password
# when using a simple auth_plugin.
from mosq_test_helper import *
def write_config(filename, port):
with open(filename, 'w') as f:
f.write("listener %d\n" % (port))
f.write("auth_plugin c/auth_plugin_v5.so\n")
f.write("allow_anonymous false\n")
port = mosq_test.get_port()
conf_file = os.path.basename(__file__).replace('.py', '.conf')
write_config(conf_file, port)
rc = 1
keepalive = 10
connect_packet = mosq_test.gen_connect("connect-uname-pwd-test", keepalive=keepalive, username="test-username", password="cnwTICONIURW")
connack_packet = mosq_test.gen_connack(rc=0)
broker = mosq_test.start_broker(filename=os.path.basename(__file__), use_conf=True, port=port)
try:
sock = mosq_test.do_client_connect(connect_packet, connack_packet, timeout=20, port=port)
rc = 0
sock.close()
except mosq_test.TestError:
pass
finally:
os.remove(conf_file)
broker.terminate()
broker.wait()
(stdo, stde) = broker.communicate()
if rc:
print(stde.decode('utf-8'))
exit(rc)

@ -191,6 +191,12 @@ endif
./09-plugin-auth-unpwd-success.py
./09-plugin-auth-v2-unpwd-fail.py
./09-plugin-auth-v2-unpwd-success.py
./09-plugin-auth-v3-unpwd-fail.py
./09-plugin-auth-v3-unpwd-success.py
./09-plugin-auth-v4-unpwd-fail.py
./09-plugin-auth-v4-unpwd-success.py
./09-plugin-auth-v5-unpwd-fail.py
./09-plugin-auth-v5-unpwd-success.py
./09-plugin-delayed-auth.py
./09-plugin-publish.py
./09-pwfile-parse-invalid.py

@ -16,6 +16,7 @@ PLUGIN_SRC = \
auth_plugin_publish.c \
auth_plugin_pwd.c \
auth_plugin_v2.c \
auth_plugin_v3.c \
auth_plugin_v4.c \
auth_plugin_v5.c \
auth_plugin_v5_handle_message.c \

@ -0,0 +1,101 @@
#include <stdio.h>
#include <string.h>
#include <mosquitto.h>
#include <mosquitto_broker.h>
#include <mosquitto_plugin.h>
int mosquitto_auth_plugin_version(void)
{
return 3;
}
int mosquitto_auth_plugin_init(void **user_data, struct mosquitto_opt *auth_opts, int auth_opt_count)
{
(void)user_data;
(void)auth_opts;
(void)auth_opt_count;
return MOSQ_ERR_SUCCESS;
}
int mosquitto_auth_plugin_cleanup(void *user_data, struct mosquitto_opt *auth_opts, int auth_opt_count)
{
(void)user_data;
(void)auth_opts;
(void)auth_opt_count;
return MOSQ_ERR_SUCCESS;
}
int mosquitto_auth_security_init(void *user_data, struct mosquitto_opt *auth_opts, int auth_opt_count, bool reload)
{
(void)user_data;
(void)auth_opts;
(void)auth_opt_count;
(void)reload;
return MOSQ_ERR_SUCCESS;
}
int mosquitto_auth_security_cleanup(void *user_data, struct mosquitto_opt *auth_opts, int auth_opt_count, bool reload)
{
(void)user_data;
(void)auth_opts;
(void)auth_opt_count;
(void)reload;
return MOSQ_ERR_SUCCESS;
}
int mosquitto_auth_acl_check(void *user_data, int access, struct mosquitto *client, const struct mosquitto_acl_msg *msg)
{
const char *username = mosquitto_client_username(client);
(void)user_data;
if(username && !strcmp(username, "readonly") && access == MOSQ_ACL_READ){
return MOSQ_ERR_SUCCESS;
}else if(username && !strcmp(username, "readonly") && access == MOSQ_ACL_SUBSCRIBE &&!strchr(msg->topic, '#') && !strchr(msg->topic, '+')) {
return MOSQ_ERR_SUCCESS;
}else if(username && !strcmp(username, "readwrite")){
if((!strcmp(msg->topic, "readonly") && access == MOSQ_ACL_READ)
|| !strcmp(msg->topic, "writeable")){
return MOSQ_ERR_SUCCESS;
}else{
return MOSQ_ERR_ACL_DENIED;
}
}else{
return MOSQ_ERR_ACL_DENIED;
}
}
int mosquitto_auth_unpwd_check(void *user_data, struct mosquitto *client, const char *username, const char *password)
{
(void)user_data;
(void)client;
if(!strcmp(username, "test-username") && password && !strcmp(password, "cnwTICONIURW")){
return MOSQ_ERR_SUCCESS;
}else if(!strcmp(username, "readonly") || !strcmp(username, "readwrite")){
return MOSQ_ERR_SUCCESS;
}else if(!strcmp(username, "test-username@v2")){
return MOSQ_ERR_PLUGIN_DEFER;
}else{
return MOSQ_ERR_AUTH;
}
}
int mosquitto_auth_psk_key_get(void *user_data, struct mosquitto *client, const char *hint, const char *identity, char *key, int max_key_len)
{
(void)user_data;
(void)client;
(void)hint;
(void)identity;
(void)key;
(void)max_key_len;
return MOSQ_ERR_AUTH;
}

@ -161,6 +161,12 @@ tests = [
(1, './09-plugin-auth-unpwd-success.py'),
(1, './09-plugin-auth-v2-unpwd-fail.py'),
(1, './09-plugin-auth-v2-unpwd-success.py'),
(1, './09-plugin-auth-v3-unpwd-fail.py'),
(1, './09-plugin-auth-v3-unpwd-success.py'),
(1, './09-plugin-auth-v4-unpwd-fail.py'),
(1, './09-plugin-auth-v4-unpwd-success.py'),
(1, './09-plugin-auth-v5-unpwd-fail.py'),
(1, './09-plugin-auth-v5-unpwd-success.py'),
(1, './09-plugin-delayed-auth.py'),
(1, './09-plugin-publish.py'),
(1, './09-pwfile-parse-invalid.py'),

Loading…
Cancel
Save