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
parent
cd07f1136b
commit
dcff8dfd38
@ -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;
|
||||
}
|
@ -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)
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue