From 6dd63d30000c558694ecaaf51d9aaa450218b9ad Mon Sep 17 00:00:00 2001 From: Pierre Fersing Date: Tue, 12 Sep 2017 16:18:24 +0200 Subject: [PATCH] Add more test for auth-plugin Tests for: * MOSQ_ACL_SUBSCRIBE acl check * MOSQ_ERR_PLUGIN_DEFER with 2 auth-plugin * Binary compatibility with v2 of auth-plugin Signed-off-by: Pierre Fersing --- test/broker/09-plugin-auth-acl-sub.conf | 3 + test/broker/09-plugin-auth-acl-sub.py | 47 ++++ .../09-plugin-auth-defer-unpwd-fail.conf | 3 + .../broker/09-plugin-auth-defer-unpwd-fail.py | 33 +++ .../09-plugin-auth-defer-unpwd-success.conf | 4 + .../09-plugin-auth-defer-unpwd-success.py | 34 +++ test/broker/09-plugin-auth-v2-unpwd-fail.conf | 3 + test/broker/09-plugin-auth-v2-unpwd-fail.py | 33 +++ .../09-plugin-auth-v2-unpwd-success.conf | 3 + .../broker/09-plugin-auth-v2-unpwd-success.py | 33 +++ test/broker/Makefile | 5 + test/broker/c/Makefile | 5 +- test/broker/c/auth_plugin.c | 4 + test/broker/c/auth_plugin_v2.c | 67 +++++ test/broker/c/auth_plugin_v2.so | Bin 0 -> 8512 bytes test/broker/c/mosquitto_plugin_v2.h | 228 ++++++++++++++++++ 16 files changed, 504 insertions(+), 1 deletion(-) create mode 100644 test/broker/09-plugin-auth-acl-sub.conf create mode 100755 test/broker/09-plugin-auth-acl-sub.py create mode 100644 test/broker/09-plugin-auth-defer-unpwd-fail.conf create mode 100755 test/broker/09-plugin-auth-defer-unpwd-fail.py create mode 100644 test/broker/09-plugin-auth-defer-unpwd-success.conf create mode 100755 test/broker/09-plugin-auth-defer-unpwd-success.py create mode 100644 test/broker/09-plugin-auth-v2-unpwd-fail.conf create mode 100755 test/broker/09-plugin-auth-v2-unpwd-fail.py create mode 100644 test/broker/09-plugin-auth-v2-unpwd-success.conf create mode 100755 test/broker/09-plugin-auth-v2-unpwd-success.py create mode 100644 test/broker/c/auth_plugin_v2.c create mode 100755 test/broker/c/auth_plugin_v2.so create mode 100644 test/broker/c/mosquitto_plugin_v2.h diff --git a/test/broker/09-plugin-auth-acl-sub.conf b/test/broker/09-plugin-auth-acl-sub.conf new file mode 100644 index 00000000..fca62763 --- /dev/null +++ b/test/broker/09-plugin-auth-acl-sub.conf @@ -0,0 +1,3 @@ +port 1888 +allow_anonymous false +auth_plugin c/auth_plugin.so diff --git a/test/broker/09-plugin-auth-acl-sub.py b/test/broker/09-plugin-auth-acl-sub.py new file mode 100755 index 00000000..631a68a7 --- /dev/null +++ b/test/broker/09-plugin-auth-acl-sub.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python + +# Test topic subscription. All topic are allowed but not using wildcard in subscribe. + +import inspect, os, sys +# From http://stackoverflow.com/questions/279237/python-import-a-module-from-a-folder +cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],".."))) +if cmd_subfolder not in sys.path: + sys.path.insert(0, cmd_subfolder) + +import mosq_test + +rc = 1 +keepalive = 10 +connect_packet = mosq_test.gen_connect("connect-uname-pwd-test", keepalive=keepalive, username="readonly") +connack_packet = mosq_test.gen_connack(rc=0) + +mid = 53 +subscribe_packet = mosq_test.gen_subscribe(mid, "qos0/test", 0) +suback_packet = mosq_test.gen_suback(mid, 0) + +mid_fail = 54 +subscribe_packet_fail = mosq_test.gen_subscribe(mid_fail, "#", 0) +suback_packet_fail = mosq_test.gen_suback(mid_fail, 0x80) + +broker = mosq_test.start_broker(filename=os.path.basename(__file__)) + +try: + sock = mosq_test.do_client_connect(connect_packet, connack_packet, timeout=20) + sock.send(subscribe_packet) + + if mosq_test.expect_packet(sock, "suback", suback_packet): + sock.send(subscribe_packet_fail) + if mosq_test.expect_packet(sock, "suback", suback_packet_fail): + rc = 0 + + sock.close() +finally: + broker.terminate() + broker.wait() + if rc: + (stdo, stde) = broker.communicate() + print(stde) + + +exit(rc) + diff --git a/test/broker/09-plugin-auth-defer-unpwd-fail.conf b/test/broker/09-plugin-auth-defer-unpwd-fail.conf new file mode 100644 index 00000000..fca62763 --- /dev/null +++ b/test/broker/09-plugin-auth-defer-unpwd-fail.conf @@ -0,0 +1,3 @@ +port 1888 +allow_anonymous false +auth_plugin c/auth_plugin.so diff --git a/test/broker/09-plugin-auth-defer-unpwd-fail.py b/test/broker/09-plugin-auth-defer-unpwd-fail.py new file mode 100755 index 00000000..367b07b3 --- /dev/null +++ b/test/broker/09-plugin-auth-defer-unpwd-fail.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python + +# Test whether a connection fail when using a auth_plugin that defer authentication. + +import inspect, os, sys +# From http://stackoverflow.com/questions/279237/python-import-a-module-from-a-folder +cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],".."))) +if cmd_subfolder not in sys.path: + sys.path.insert(0, cmd_subfolder) + +import mosq_test + +rc = 1 +keepalive = 10 +connect_packet = mosq_test.gen_connect("connect-uname-pwd-test", keepalive=keepalive, username="test-username@v2", password="doesNotMatter") +connack_packet = mosq_test.gen_connack(rc=5) + +broker = mosq_test.start_broker(filename=os.path.basename(__file__)) + +try: + sock = mosq_test.do_client_connect(connect_packet, connack_packet, timeout=20) + rc = 0 + sock.close() +finally: + broker.terminate() + broker.wait() + if rc: + (stdo, stde) = broker.communicate() + print(stde) + + +exit(rc) + diff --git a/test/broker/09-plugin-auth-defer-unpwd-success.conf b/test/broker/09-plugin-auth-defer-unpwd-success.conf new file mode 100644 index 00000000..55f98121 --- /dev/null +++ b/test/broker/09-plugin-auth-defer-unpwd-success.conf @@ -0,0 +1,4 @@ +port 1888 +allow_anonymous false +auth_plugin c/auth_plugin.so +auth_plugin c/auth_plugin_v2.so diff --git a/test/broker/09-plugin-auth-defer-unpwd-success.py b/test/broker/09-plugin-auth-defer-unpwd-success.py new file mode 100755 index 00000000..a99d27dd --- /dev/null +++ b/test/broker/09-plugin-auth-defer-unpwd-success.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python + +# Test whether a connection is successful with correct username and password +# when using a two auth_plugin (first will defer, second will accept). + +import inspect, os, sys +# From http://stackoverflow.com/questions/279237/python-import-a-module-from-a-folder +cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],".."))) +if cmd_subfolder not in sys.path: + sys.path.insert(0, cmd_subfolder) + +import mosq_test + +rc = 1 +keepalive = 10 +connect_packet = mosq_test.gen_connect("connect-uname-pwd-test", keepalive=keepalive, username="test-username@v2", password="doesNotMatter") +connack_packet = mosq_test.gen_connack(rc=0) + +broker = mosq_test.start_broker(filename=os.path.basename(__file__)) + +try: + sock = mosq_test.do_client_connect(connect_packet, connack_packet, timeout=20) + rc = 0 + sock.close() +finally: + broker.terminate() + broker.wait() + if rc: + (stdo, stde) = broker.communicate() + print(stde) + + +exit(rc) + diff --git a/test/broker/09-plugin-auth-v2-unpwd-fail.conf b/test/broker/09-plugin-auth-v2-unpwd-fail.conf new file mode 100644 index 00000000..98bb0b51 --- /dev/null +++ b/test/broker/09-plugin-auth-v2-unpwd-fail.conf @@ -0,0 +1,3 @@ +port 1888 +allow_anonymous false +auth_plugin c/auth_plugin_v2.so diff --git a/test/broker/09-plugin-auth-v2-unpwd-fail.py b/test/broker/09-plugin-auth-v2-unpwd-fail.py new file mode 100755 index 00000000..b1d7b17d --- /dev/null +++ b/test/broker/09-plugin-auth-v2-unpwd-fail.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python + +# Test whether a connection is successful with correct username and password +# when using a simple auth_plugin. + +import inspect, os, sys +# From http://stackoverflow.com/questions/279237/python-import-a-module-from-a-folder +cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],".."))) +if cmd_subfolder not in sys.path: + sys.path.insert(0, cmd_subfolder) + +import mosq_test + +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__)) + +try: + sock = mosq_test.do_client_connect(connect_packet, connack_packet, timeout=20) + rc = 0 + + sock.close() +finally: + broker.terminate() + broker.wait() + if rc: + (stdo, stde) = broker.communicate() + print(stde) + +exit(rc) diff --git a/test/broker/09-plugin-auth-v2-unpwd-success.conf b/test/broker/09-plugin-auth-v2-unpwd-success.conf new file mode 100644 index 00000000..98bb0b51 --- /dev/null +++ b/test/broker/09-plugin-auth-v2-unpwd-success.conf @@ -0,0 +1,3 @@ +port 1888 +allow_anonymous false +auth_plugin c/auth_plugin_v2.so diff --git a/test/broker/09-plugin-auth-v2-unpwd-success.py b/test/broker/09-plugin-auth-v2-unpwd-success.py new file mode 100755 index 00000000..d87f1fe8 --- /dev/null +++ b/test/broker/09-plugin-auth-v2-unpwd-success.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python + +# Test whether a connection is successful with correct username and password +# when using a simple auth_plugin. + +import inspect, os, sys +# From http://stackoverflow.com/questions/279237/python-import-a-module-from-a-folder +cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],".."))) +if cmd_subfolder not in sys.path: + sys.path.insert(0, cmd_subfolder) + +import mosq_test + +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__)) + +try: + sock = mosq_test.do_client_connect(connect_packet, connack_packet, timeout=20) + rc = 0 + sock.close() +finally: + broker.terminate() + broker.wait() + if rc: + (stdo, stde) = broker.communicate() + print(stde) + + +exit(rc) diff --git a/test/broker/Makefile b/test/broker/Makefile index f23c174c..35228406 100644 --- a/test/broker/Makefile +++ b/test/broker/Makefile @@ -100,6 +100,11 @@ endif 09 : ./09-plugin-auth-unpwd-success.py ./09-plugin-auth-unpwd-fail.py + ./09-plugin-auth-acl-sub.py + ./09-plugin-auth-v2-unpwd-success.py + ./09-plugin-auth-v2-unpwd-fail.py + ./09-plugin-auth-defer-unpwd-success.py + ./09-plugin-auth-defer-unpwd-fail.py 10 : ./10-listener-mount-point.py diff --git a/test/broker/c/Makefile b/test/broker/c/Makefile index 4e43637c..bbbfc1ae 100644 --- a/test/broker/c/Makefile +++ b/test/broker/c/Makefile @@ -2,13 +2,16 @@ CFLAGS=-I../../../lib -I../../../src -Wall -Werror -all : auth_plugin.so 08 +all : auth_plugin.so auth_plugin_v2.so 08 08 : 08-tls-psk-pub.test 08-tls-psk-bridge.test auth_plugin.so : auth_plugin.c $(CC) ${CFLAGS} -fPIC -shared $^ -o $@ +auth_plugin_v2.so : auth_plugin_v2.c + $(CC) ${CFLAGS} -fPIC -shared $^ -o $@ + 08-tls-psk-pub.test : 08-tls-psk-pub.c $(CC) ${CFLAGS} $^ -o $@ ../../../lib/libmosquitto.so.1 diff --git a/test/broker/c/auth_plugin.c b/test/broker/c/auth_plugin.c index d0f645f5..65728cbf 100644 --- a/test/broker/c/auth_plugin.c +++ b/test/broker/c/auth_plugin.c @@ -36,6 +36,8 @@ int mosquitto_auth_acl_check(void *user_data, int access, const struct mosquitto printf("%s\n", username); 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{ return MOSQ_ERR_ACL_DENIED; } @@ -47,6 +49,8 @@ int mosquitto_auth_unpwd_check(void *user_data, const struct mosquitto *client, return MOSQ_ERR_SUCCESS; }else if(!strcmp(username, "readonly")){ return MOSQ_ERR_SUCCESS; + }else if(!strcmp(username, "test-username@v2")){ + return MOSQ_ERR_PLUGIN_DEFER; }else{ return MOSQ_ERR_AUTH; } diff --git a/test/broker/c/auth_plugin_v2.c b/test/broker/c/auth_plugin_v2.c new file mode 100644 index 00000000..3b039ef5 --- /dev/null +++ b/test/broker/c/auth_plugin_v2.c @@ -0,0 +1,67 @@ +#include +#include +#include "mosquitto_plugin_v2.h" + +/* + * Following constant come from mosquitto.h + * + * They are copied here to fix value of those constant at the time of MOSQ_AUTH_PLUGIN_VERSION == 2 + */ +enum mosq_err_t { + MOSQ_ERR_SUCCESS = 0, + MOSQ_ERR_AUTH = 11, + MOSQ_ERR_ACL_DENIED = 12 +}; + +int mosquitto_auth_plugin_version(void) +{ + return MOSQ_AUTH_PLUGIN_VERSION; +} + +int mosquitto_auth_plugin_init(void **user_data, struct mosquitto_auth_opt *auth_opts, int auth_opt_count) +{ + return MOSQ_ERR_SUCCESS; +} + +int mosquitto_auth_plugin_cleanup(void *user_data, struct mosquitto_auth_opt *auth_opts, int auth_opt_count) +{ + return MOSQ_ERR_SUCCESS; +} + +int mosquitto_auth_security_init(void *user_data, struct mosquitto_auth_opt *auth_opts, int auth_opt_count, bool reload) +{ + return MOSQ_ERR_SUCCESS; +} + +int mosquitto_auth_security_cleanup(void *user_data, struct mosquitto_auth_opt *auth_opts, int auth_opt_count, bool reload) +{ + return MOSQ_ERR_SUCCESS; +} + +int mosquitto_auth_acl_check(void *user_data, const char *clientid, const char *username, const char *topic, int access) +{ + if(!strcmp(username, "readonly") && access == MOSQ_ACL_READ){ + return MOSQ_ERR_SUCCESS; + }else{ + return MOSQ_ERR_ACL_DENIED; + } +} + +int mosquitto_auth_unpwd_check(void *user_data, const char *username, const char *password) +{ + if(!strcmp(username, "test-username") && password && !strcmp(password, "cnwTICONIURW")){ + return MOSQ_ERR_SUCCESS; + }else if(!strcmp(username, "readonly")){ + return MOSQ_ERR_SUCCESS; + }else if(!strcmp(username, "test-username@v2")){ + return MOSQ_ERR_SUCCESS; + }else{ + return MOSQ_ERR_AUTH; + } +} + +int mosquitto_auth_psk_key_get(void *user_data, const char *hint, const char *identity, char *key, int max_key_len) +{ + return MOSQ_ERR_AUTH; +} + diff --git a/test/broker/c/auth_plugin_v2.so b/test/broker/c/auth_plugin_v2.so new file mode 100755 index 0000000000000000000000000000000000000000..3b7d95e5ac902c098ee6ec8d92df921e286be94b GIT binary patch literal 8512 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 literal 0 HcmV?d00001 diff --git a/test/broker/c/mosquitto_plugin_v2.h b/test/broker/c/mosquitto_plugin_v2.h new file mode 100644 index 00000000..5b6449c0 --- /dev/null +++ b/test/broker/c/mosquitto_plugin_v2.h @@ -0,0 +1,228 @@ +/* +Copyright (c) 2012-2014 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ + +#ifndef MOSQUITTO_PLUGIN_H +#define MOSQUITTO_PLUGIN_H + +#define MOSQ_AUTH_PLUGIN_VERSION 2 + +#define MOSQ_ACL_NONE 0x00 +#define MOSQ_ACL_READ 0x01 +#define MOSQ_ACL_WRITE 0x02 + +struct mosquitto_auth_opt { + char *key; + char *value; +}; + +/* + * To create an authentication plugin you must include this file then implement + * the functions listed below. The resulting code should then be compiled as a + * shared library. Using gcc this can be achieved as follows: + * + * gcc -I -fPIC -shared plugin.c -o plugin.so + * + * On Mac OS X: + * + * gcc -I -fPIC -shared plugin.c -undefined dynamic_lookup -o plugin.so + * + */ + +/* ========================================================================= + * + * Utility Functions + * + * Use these functions from within your plugin. + * + * There are also very useful functions in libmosquitto. + * + * ========================================================================= */ + +/* + * Function: mosquitto_log_printf + * + * Write a log message using the broker configured logging. + * + * Parameters: + * level - Log message priority. Can currently be one of: + * + * MOSQ_LOG_INFO + * MOSQ_LOG_NOTICE + * MOSQ_LOG_WARNING + * MOSQ_LOG_ERR + * MOSQ_LOG_DEBUG + * MOSQ_LOG_SUBSCRIBE (not recommended for use by plugins) + * MOSQ_LOG_UNSUBSCRIBE (not recommended for use by plugins) + * + * These values are defined in mosquitto.h. + * + * fmt, ... - printf style format and arguments. + */ +void mosquitto_log_printf(int level, const char *fmt, ...); + + + +/* ========================================================================= + * + * Plugin Functions + * + * You must implement these functions in your plugin. + * + * ========================================================================= */ + +/* + * Function: mosquitto_auth_plugin_version + * + * The broker will call this function immediately after loading the plugin to + * check it is a supported plugin version. Your code must simply return + * MOSQ_AUTH_PLUGIN_VERSION. + */ +int mosquitto_auth_plugin_version(void); + +/* + * Function: mosquitto_auth_plugin_init + * + * Called after the plugin has been loaded and + * has been called. This will only ever be called once and can be used to + * initialise the plugin. + * + * Parameters: + * + * user_data : The pointer set here will be passed to the other plugin + * functions. Use to hold connection information for example. + * auth_opts : Pointer to an array of struct mosquitto_auth_opt, which + * provides the plugin options defined in the configuration file. + * auth_opt_count : The number of elements in the auth_opts array. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_plugin_init(void **user_data, struct mosquitto_auth_opt *auth_opts, int auth_opt_count); + +/* + * Function: mosquitto_auth_plugin_cleanup + * + * Called when the broker is shutting down. This will only ever be called once. + * Note that will be called directly before + * this function. + * + * Parameters: + * + * user_data : The pointer provided in . + * auth_opts : Pointer to an array of struct mosquitto_auth_opt, which + * provides the plugin options defined in the configuration file. + * auth_opt_count : The number of elements in the auth_opts array. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_plugin_cleanup(void *user_data, struct mosquitto_auth_opt *auth_opts, int auth_opt_count); + +/* + * Function: mosquitto_auth_security_init + * + * Called when the broker initialises the security functions when it starts up. + * If the broker is requested to reload its configuration whilst running, + * will be called, followed by this function. + * In this situation, the reload parameter will be true. + * + * Parameters: + * + * user_data : The pointer provided in . + * auth_opts : Pointer to an array of struct mosquitto_auth_opt, which + * provides the plugin options defined in the configuration file. + * auth_opt_count : The number of elements in the auth_opts array. + * reload : If set to false, this is the first time the function has + * been called. If true, the broker has received a signal + * asking to reload its configuration. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_security_init(void *user_data, struct mosquitto_auth_opt *auth_opts, int auth_opt_count, bool reload); + +/* + * Function: mosquitto_auth_security_cleanup + * + * Called when the broker cleans up the security functions when it shuts down. + * If the broker is requested to reload its configuration whilst running, + * this function will be called, followed by . + * In this situation, the reload parameter will be true. + * + * Parameters: + * + * user_data : The pointer provided in . + * auth_opts : Pointer to an array of struct mosquitto_auth_opt, which + * provides the plugin options defined in the configuration file. + * auth_opt_count : The number of elements in the auth_opts array. + * reload : If set to false, this is the first time the function has + * been called. If true, the broker has received a signal + * asking to reload its configuration. + * + * Return value: + * Return 0 on success + * Return >0 on failure. + */ +int mosquitto_auth_security_cleanup(void *user_data, struct mosquitto_auth_opt *auth_opts, int auth_opt_count, bool reload); + +/* + * Function: mosquitto_auth_acl_check + * + * Called by the broker when topic access must be checked. access will be one + * of MOSQ_ACL_READ (for subscriptions) or MOSQ_ACL_WRITE (for publish). Return + * MOSQ_ERR_SUCCESS if access was granted, MOSQ_ERR_ACL_DENIED if access was + * not granted, or MOSQ_ERR_UNKNOWN for an application specific error. + */ +int mosquitto_auth_acl_check(void *user_data, const char *clientid, const char *username, const char *topic, int access); + +/* + * Function: mosquitto_auth_unpwd_check + * + * Called by the broker when a username/password must be checked. Return + * MOSQ_ERR_SUCCESS if the user is authenticated, MOSQ_ERR_AUTH if + * authentication failed, or MOSQ_ERR_UNKNOWN for an application specific + * error. + */ +int mosquitto_auth_unpwd_check(void *user_data, const char *username, const char *password); + +/* + * Function: mosquitto_psk_key_get + * + * Called by the broker when a client connects to a listener using TLS/PSK. + * This is used to retrieve the pre-shared-key associated with a client + * identity. + * + * Examine hint and identity to determine the required PSK (which must be a + * hexadecimal string with no leading "0x") and copy this string into key. + * + * Parameters: + * user_data : the pointer provided in . + * hint : the psk_hint for the listener the client is connecting to. + * identity : the identity string provided by the client + * key : a string where the hex PSK should be copied + * max_key_len : the size of key + * + * Return value: + * Return 0 on success. + * Return >0 on failure. + * Return >0 if this function is not required. + */ +int mosquitto_auth_psk_key_get(void *user_data, const char *hint, const char *identity, char *key, int max_key_len); + +#endif