Add mosquitto_ext_auth_continue()

This commit is contained in:
Roger A. Light 2024-10-28 22:28:23 +00:00
parent dd2c25c1cf
commit a2fe980301
25 changed files with 574 additions and 2 deletions

View file

@ -170,6 +170,9 @@ Client library:
gives access to reason codes for each of the unsubscription requests. gives access to reason codes for each of the unsubscription requests.
- Add `mosquitto_property_remove`, for removing properties from property - Add `mosquitto_property_remove`, for removing properties from property
lists. lists.
- Add `on_ext_auth()` callback to allow handling MQTT v5 extended authentication.
- Add `mosquitto_ext_auth_continue()` function to continue an MQTT v5 extended
authentication.
Clients: Clients:
- Add `-W` timeout support to Windows. - Add `-W` timeout support to Windows.

View file

@ -56,6 +56,26 @@ extern "C" {
*/ */
libmosq_EXPORT int mosquitto_username_pw_set(struct mosquitto *mosq, const char *username, const char *password); libmosq_EXPORT int mosquitto_username_pw_set(struct mosquitto *mosq, const char *username, const char *password);
/*
* Function: mosquitto_ext_auth_continue
*
* Use within an on_ext_auth callback only.
*
* Call to continue the MQTT v5 extended authentication flow.
*
* Parameters:
* mosq - a valid mosquitto instance.
* auth_method - the authentication method as provided in the on_ext_auth callback
* auth_data - authentication data to send to the broker, or NULL
* auth_data_len - the length of auth_data, in bytes, or 0
*
* Returns:
* MOSQ_ERR_SUCCESS - on success.
* MOSQ_ERR_INVAL - if the input parameters were invalid.
* MOSQ_ERR_NOMEM - if an out of memory condition occurred.
*/
libmosq_EXPORT int mosquitto_ext_auth_continue(struct mosquitto *context, const char *auth_method, uint16_t auth_data_len, const void *auth_data, const mosquitto_property *props);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -410,6 +410,38 @@ libmosq_EXPORT void mosquitto_unsubscribe_v5_callback_set(struct mosquitto *mosq
*/ */
libmosq_EXPORT void mosquitto_unsubscribe2_v5_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int, int, const int *, const mosquitto_property *props)); libmosq_EXPORT void mosquitto_unsubscribe2_v5_callback_set(struct mosquitto *mosq, void (*on_unsubscribe)(struct mosquitto *, void *, int, int, const int *, const mosquitto_property *props));
/*
* Function: mosquitto_ext_auth_callback_set
*
* Set the callback for extended authentication. This should be used if you
* want to support MQTT v5.0 extended authentication.
*
* mosq - a valid mosquitto instance.
* on_ext_auth - a callback function in the following form:
* void callback(struct mosquitto *mosq, void *obj, const char *auth_method, int auth_data_len, const void *auth_data, const mosquitto_property *props)
*
* Callback Parameters:
* mosq - the mosquitto instance making the callback.
* obj - the user data provided in <mosquitto_new>
* auth_method - the authentication method provided by the broker
* auth_data_len - the length of auth_data in bytes
* auth_data - the authentication data, or NULL
* props - list of MQTT 5 properties sent
* note that this includes the auth-method and auth-data
* properties, so you cannot use it directly with
* mosquitto_ext_auth_continue and must instead create your
* own property list
*
* Callback Return:
* MOSQ_ERR_SUCCESS - if you accept the authentication data
* MOSQ_ERR_AUTH - if the authentication should fail
* MOSQ_ERR_NOMEM - on out of memory
*
* See Also:
* <mosquitto_ext_auth_continue>
*/
void mosquitto_ext_auth_callback_set(struct mosquitto *mosq, int (*on_auth)(struct mosquitto *, void *, const char *, uint16_t, const void *, const mosquitto_property *props));
/* /*
* Function: mosquitto_log_callback_set * Function: mosquitto_log_callback_set
* *

View file

@ -120,6 +120,7 @@ class mosqpp_EXPORT mosquittopp {
void message_retry_set(unsigned int message_retry); void message_retry_set(unsigned int message_retry);
void user_data_set(void *userdata); void user_data_set(void *userdata);
int tls_set(const char *cafile, const char *capath=NULL, const char *certfile=NULL, const char *keyfile=NULL, int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)=NULL); int tls_set(const char *cafile, const char *capath=NULL, const char *certfile=NULL, const char *keyfile=NULL, int (*pw_callback)(char *buf, int size, int rwflag, void *userdata)=NULL);
int ext_auth_continue(const char *auth_method, uint16_t auth_data_len=0, const void *auth_data=NULL, const mosquitto_property *properties=NULL);
int tls_opts_set(int cert_reqs, const char *tls_version=NULL, const char *ciphers=NULL); int tls_opts_set(int cert_reqs, const char *tls_version=NULL, const char *ciphers=NULL);
int tls_insecure_set(bool value); int tls_insecure_set(bool value);
int tls_psk_set(const char *psk, const char *identity, const char *ciphers=NULL); int tls_psk_set(const char *psk, const char *identity, const char *ciphers=NULL);
@ -156,6 +157,7 @@ class mosqpp_EXPORT mosquittopp {
virtual void on_unsubscribe_v5(int /*mid*/, const mosquitto_property * /*props*/) {return;} virtual void on_unsubscribe_v5(int /*mid*/, const mosquitto_property * /*props*/) {return;}
virtual void on_log(int /*level*/, const char * /*str*/) {return;} virtual void on_log(int /*level*/, const char * /*str*/) {return;}
virtual void on_error() {return;} virtual void on_error() {return;}
virtual int on_ext_auth(const char * /*auth_method*/, uint16_t /*auth_data_len*/, const void * /*auth_data*/, const mosquitto_property * /*props*/) {return MOSQ_ERR_AUTH;}
}; };
} }

View file

@ -10,6 +10,7 @@ set(C_SRC
alias_mosq.c alias_mosq.h alias_mosq.c alias_mosq.h
callbacks.c callbacks.c
connect.c connect.c
extended_auth.c
handle_auth.c handle_auth.c
handle_connack.c handle_connack.c
handle_disconnect.c handle_disconnect.c

View file

@ -46,6 +46,7 @@ OBJS= \
alias_mosq.o \ alias_mosq.o \
callbacks.o \ callbacks.o \
connect.o \ connect.o \
extended_auth.o \
handle_auth.o \ handle_auth.o \
handle_connack.o \ handle_connack.o \
handle_disconnect.o \ handle_disconnect.o \

View file

@ -136,6 +136,14 @@ void mosquitto_log_callback_set(struct mosquitto *mosq, void (*on_log)(struct mo
} }
void mosquitto_ext_auth_callback_set(struct mosquitto *mosq, int (*on_ext_auth)(struct mosquitto *, void *, const char *, uint16_t, const void *, const mosquitto_property *props))
{
pthread_mutex_lock(&mosq->callback_mutex);
mosq->on_ext_auth = on_ext_auth;
pthread_mutex_unlock(&mosq->callback_mutex);
}
void callback__on_pre_connect(struct mosquitto *mosq) void callback__on_pre_connect(struct mosquitto *mosq)
{ {
void (*on_pre_connect)(struct mosquitto *, void *userdata); void (*on_pre_connect)(struct mosquitto *, void *userdata);
@ -286,3 +294,20 @@ void callback__on_disconnect(struct mosquitto *mosq, int rc, const mosquitto_pro
} }
mosq->callback_depth--; mosq->callback_depth--;
} }
int callback__on_ext_auth(struct mosquitto *mosq, const char *auth_method, uint16_t auth_data_len, const void *auth_data, const mosquitto_property *properties)
{
int rc = MOSQ_ERR_AUTH;
int (*on_ext_auth)(struct mosquitto *, void *userdata, const char *, uint16_t, const void *, const mosquitto_property *props);
pthread_mutex_lock(&mosq->callback_mutex);
on_ext_auth = mosq->on_ext_auth;
pthread_mutex_unlock(&mosq->callback_mutex);
mosq->callback_depth++;
if(on_ext_auth){
rc = on_ext_auth(mosq, mosq->userdata, auth_method, auth_data_len, auth_data, properties);
}
mosq->callback_depth--;
return rc;
}

View file

@ -27,5 +27,6 @@ void callback__on_message(struct mosquitto *mosq, const struct mosquitto_message
void callback__on_subscribe(struct mosquitto *mosq, int mid, int qos_count, const int *granted_qos, const mosquitto_property *props); void callback__on_subscribe(struct mosquitto *mosq, int mid, int qos_count, const int *granted_qos, const mosquitto_property *props);
void callback__on_unsubscribe(struct mosquitto *mosq, int mid, int reason_code_count, const int *reason_codes, const mosquitto_property *props); void callback__on_unsubscribe(struct mosquitto *mosq, int mid, int reason_code_count, const int *reason_codes, const mosquitto_property *props);
void callback__on_disconnect(struct mosquitto *mosq, int rc, const mosquitto_property *props); void callback__on_disconnect(struct mosquitto *mosq, int rc, const mosquitto_property *props);
int callback__on_ext_auth(struct mosquitto *mosq, const char *auth_method, uint16_t auth_data_len, const void *auth_data, const mosquitto_property *properties);
#endif #endif

View file

@ -125,6 +125,14 @@ static void on_unsubscribe_v5_wrapper(struct mosquitto *mosq, void *userdata, in
} }
static int on_ext_auth_wrapper(struct mosquitto *mosq, void *userdata, const char *auth_method, uint16_t auth_data_len, const void *auth_data, const mosquitto_property *props)
{
class mosquittopp *m = (class mosquittopp *)userdata;
UNUSED(mosq);
return m->on_ext_auth(auth_method, auth_data_len, auth_data, props);
}
static void on_log_wrapper(struct mosquitto *mosq, void *userdata, int level, const char *str) static void on_log_wrapper(struct mosquitto *mosq, void *userdata, int level, const char *str)
{ {
class mosquittopp *m = (class mosquittopp *)userdata; class mosquittopp *m = (class mosquittopp *)userdata;
@ -273,6 +281,7 @@ void mosquitto_callbacks_set(struct mosquitto *mosq) {
mosquitto_subscribe_v5_callback_set(mosq, on_subscribe_v5_wrapper); mosquitto_subscribe_v5_callback_set(mosq, on_subscribe_v5_wrapper);
mosquitto_unsubscribe_callback_set(mosq, on_unsubscribe_wrapper); mosquitto_unsubscribe_callback_set(mosq, on_unsubscribe_wrapper);
mosquitto_unsubscribe_v5_callback_set(mosq, on_unsubscribe_v5_wrapper); mosquitto_unsubscribe_v5_callback_set(mosq, on_unsubscribe_v5_wrapper);
mosquitto_ext_auth_callback_set(mosq, on_ext_auth_wrapper);
mosquitto_log_callback_set(mosq, on_log_wrapper); mosquitto_log_callback_set(mosq, on_log_wrapper);
} }
} }
@ -345,6 +354,11 @@ int mosquittopp::disconnect_v5(int reason_code, const mosquitto_property *proper
return mosquitto_disconnect_v5(m_mosq, reason_code, properties); return mosquitto_disconnect_v5(m_mosq, reason_code, properties);
} }
int mosquittopp::ext_auth_continue(const char *auth_method, uint16_t auth_data_len, const void *auth_data, const mosquitto_property *properties)
{
return mosquitto_ext_auth_continue(m_mosq, auth_method, auth_data_len, auth_data, properties);
}
int mosquittopp::socket() int mosquittopp::socket()
{ {
return mosquitto_socket(m_mosq); return mosquitto_socket(m_mosq);

64
lib/extended_auth.c Normal file
View file

@ -0,0 +1,64 @@
/*
Copyright (c) 2019-2024 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.
*/
#include "config.h"
#include "mosquitto/mqtt_protocol.h"
#include "packet_mosq.h"
#include "property_mosq.h"
#include "util_mosq.h"
int mosquitto_ext_auth_continue(struct mosquitto *context, const char *auth_method, uint16_t auth_data_len, const void *auth_data, const mosquitto_property *input_props)
{
struct mosquitto__packet *packet = NULL;
int rc;
uint32_t remaining_length;
mosquitto_property *properties = NULL;
rc = mosquitto_property_copy_all(&properties, input_props);
if(rc) return rc;
if(!context || context->protocol != mosq_p_mqtt5 || !auth_method) return MOSQ_ERR_PROTOCOL;
remaining_length = 1;
rc = mosquitto_property_add_string(&properties, MQTT_PROP_AUTHENTICATION_METHOD, auth_method);
if(rc) goto error;
if(auth_data != NULL && auth_data_len > 0){
rc = mosquitto_property_add_binary(&properties, MQTT_PROP_AUTHENTICATION_DATA, auth_data, auth_data_len);
if(rc) goto error;
}
remaining_length += mosquitto_property_get_remaining_length(properties);
rc = packet__check_oversize(context, remaining_length);
if(rc) goto error;
rc = packet__alloc(&packet, CMD_AUTH, remaining_length);
if(rc) goto error;
packet__write_byte(packet, MQTT_RC_CONTINUE_AUTHENTICATION);
property__write_all(packet, properties, true);
mosquitto_property_free_all(&properties);
return packet__queue(context, packet);
error:
mosquitto_property_free_all(&properties);
return rc;
}

View file

@ -21,6 +21,7 @@ Contributors:
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "callbacks.h"
#include "logging_mosq.h" #include "logging_mosq.h"
#include "mosquitto_internal.h" #include "mosquitto_internal.h"
#include "mosquitto/mqtt_protocol.h" #include "mosquitto/mqtt_protocol.h"
@ -33,6 +34,9 @@ int handle__auth(struct mosquitto *mosq)
{ {
int rc = 0; int rc = 0;
uint8_t reason_code; uint8_t reason_code;
char *auth_method = NULL;
void *auth_data = NULL;
uint16_t auth_data_len = 0;
mosquitto_property *properties = NULL; mosquitto_property *properties = NULL;
if(!mosq) return MOSQ_ERR_INVAL; if(!mosq) return MOSQ_ERR_INVAL;
@ -49,7 +53,11 @@ int handle__auth(struct mosquitto *mosq)
rc = property__read_all(CMD_AUTH, &mosq->in_packet, &properties); rc = property__read_all(CMD_AUTH, &mosq->in_packet, &properties);
if(rc) return rc; if(rc) return rc;
mosquitto_property_free_all(&properties); /* FIXME - TEMPORARY UNTIL PROPERTIES PROCESSED */
return MOSQ_ERR_SUCCESS; mosquitto_property_read_string(properties, MQTT_PROP_AUTHENTICATION_METHOD, &auth_method, false);
mosquitto_property_read_binary(properties, MQTT_PROP_AUTHENTICATION_DATA, &auth_data, &auth_data_len, false);
rc = callback__on_ext_auth(mosq, auth_method, auth_data_len, auth_data, properties);
mosquitto_property_free_all(&properties);
return rc;
} }

View file

@ -144,6 +144,8 @@ MOSQ_1.7 {
MOSQ_2.1 { MOSQ_2.1 {
global: global:
mosquitto_ext_auth_callback_set;
mosquitto_ext_auth_continue;
mosquitto_pre_connect_callback_set; mosquitto_pre_connect_callback_set;
mosquitto_topic_matches_sub_with_pattern; mosquitto_topic_matches_sub_with_pattern;
mosquitto_sub_matches_acl; mosquitto_sub_matches_acl;

View file

@ -405,6 +405,7 @@ struct mosquitto {
void (*on_unsubscribe)(struct mosquitto *, void *userdata, int mid); void (*on_unsubscribe)(struct mosquitto *, void *userdata, int mid);
void (*on_unsubscribe_v5)(struct mosquitto *, void *userdata, int mid, const mosquitto_property *props); void (*on_unsubscribe_v5)(struct mosquitto *, void *userdata, int mid, const mosquitto_property *props);
void (*on_unsubscribe2_v5)(struct mosquitto *, void *userdata, int mid, int reason_code_count, const int *reason_codes, const mosquitto_property *props); void (*on_unsubscribe2_v5)(struct mosquitto *, void *userdata, int mid, int reason_code_count, const int *reason_codes, const mosquitto_property *props);
int (*on_ext_auth)(struct mosquitto *, void *userdata, const char *auth_method, uint16_t auth_data_len, const void *auth_data, const mosquitto_property *props);
void (*on_log)(struct mosquitto *, void *userdata, int level, const char *str); void (*on_log)(struct mosquitto *, void *userdata, int level, const char *str);
/*void (*on_error)();*/ /*void (*on_error)();*/
char *host; char *host;

View file

@ -0,0 +1,28 @@
#!/usr/bin/env python3
from mosq_test_helper import *
import mqtt5_rc
def do_test(conn, data):
props = mqtt5_props.gen_uint32_prop(mqtt5_props.PROP_MAXIMUM_PACKET_SIZE, 1000)
props += mqtt5_props.gen_uint16_prop(mqtt5_props.PROP_RECEIVE_MAXIMUM, 20)
connect_packet = mosq_test.gen_connect("01-extended-auth", proto_ver=5, properties=props)
props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_AUTHENTICATION_METHOD, "test-method")
props += mqtt5_props.gen_string_prop(mqtt5_props.PROP_AUTHENTICATION_DATA, "test-request") # This is really a binary property
auth_continue_b2c = mosq_test.gen_auth(reason_code=mqtt5_rc.MQTT_RC_CONTINUE_AUTHENTICATION, properties=props)
props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_AUTHENTICATION_METHOD, "test-method")
props += mqtt5_props.gen_string_prop(mqtt5_props.PROP_AUTHENTICATION_DATA, "test-reply") # This is really a binary property
auth_continue_c2b = mosq_test.gen_auth(reason_code=mqtt5_rc.MQTT_RC_CONTINUE_AUTHENTICATION, properties=props)
connack_packet = mosq_test.gen_connack(rc=0, proto_ver=5)
disconnect_packet = mosq_test.gen_disconnect(proto_ver=5)
mosq_test.do_receive_send(conn, connect_packet, auth_continue_b2c, "auth_b2c")
mosq_test.do_receive_send(conn, auth_continue_c2b, connack_packet, "connack")
mosq_test.expect_packet(conn, "disconnect", disconnect_packet)
mosq_test.client_test("c/01-extended-auth-continue.test", [], do_test, None)
mosq_test.client_test("cpp/01-extended-auth-continue.test", [], do_test, None)

View file

@ -0,0 +1,24 @@
#!/usr/bin/env python3
from mosq_test_helper import *
import mqtt5_rc
def do_test(conn, data):
props = mqtt5_props.gen_uint32_prop(mqtt5_props.PROP_MAXIMUM_PACKET_SIZE, 1000)
props += mqtt5_props.gen_uint16_prop(mqtt5_props.PROP_RECEIVE_MAXIMUM, 20)
connect_packet = mosq_test.gen_connect("01-extended-auth", proto_ver=5, properties=props)
props = mqtt5_props.gen_string_prop(mqtt5_props.PROP_AUTHENTICATION_METHOD, "test-method")
props += mqtt5_props.gen_string_prop(mqtt5_props.PROP_AUTHENTICATION_DATA, "test-request") # This is really a binary property
auth_continue_b2c = mosq_test.gen_auth(reason_code=mqtt5_rc.MQTT_RC_CONTINUE_AUTHENTICATION, properties=props)
disconnect_packet = mosq_test.gen_disconnect(proto_ver=5)
mosq_test.do_receive_send(conn, connect_packet, auth_continue_b2c, "auth_b2c")
p = conn.recv(1)
if len(p) == 1:
exit(1)
mosq_test.client_test("c/01-extended-auth-failure.test", [], do_test, None)
mosq_test.client_test("cpp/01-extended-auth-failure.test", [], do_test, None)

View file

@ -30,6 +30,8 @@ test : test-compile
./01-con-discon-will.py ./01-con-discon-will.py
./01-con-discon-will-v5.py ./01-con-discon-will-v5.py
./01-con-discon-will-clear.py ./01-con-discon-will-clear.py
./01-extended-auth-continue.py
./01-extended-auth-failure.py
./01-keepalive-pingreq.py ./01-keepalive-pingreq.py
./01-no-clean-session.py ./01-no-clean-session.py
./01-server-keepalive-pingreq.py ./01-server-keepalive-pingreq.py

View file

@ -0,0 +1,89 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mosquitto.h>
#include <mosquitto/mqtt_protocol.h>
static int run = -1;
static void on_connect(struct mosquitto *mosq, void *obj, int rc, int flags, const mosquitto_property *properties)
{
(void)obj;
(void)rc;
(void)flags;
(void)properties;
/* FIXME - should verify flags and all properties here. */
if(rc){
exit(1);
}else{
mosquitto_disconnect(mosq);
}
}
static int on_ext_auth(struct mosquitto *mosq, void *obj, const char *auth_method, uint16_t auth_data_len, const void *auth_data, const mosquitto_property *properties)
{
(void)obj;
(void)auth_data;
(void)auth_data_len;
(void)properties;
if(strcmp(auth_method, "test-method")){
run = 1;
return MOSQ_ERR_AUTH;
}
if(auth_data_len == 0 || (!auth_data || strcmp(auth_data, "test-request"))){
run = 1;
return MOSQ_ERR_AUTH;
}
return mosquitto_ext_auth_continue(mosq, auth_method, strlen("test-reply"), "test-reply", NULL);
}
static void on_disconnect(struct mosquitto *mosq, void *obj, int rc, const mosquitto_property *properties)
{
(void)mosq;
(void)obj;
(void)properties;
/* FIXME - should verify flags and all properties here. */
run = rc;
}
int main(int argc, char *argv[])
{
int rc;
struct mosquitto *mosq;
int port;
mosquitto_property *props = NULL;
if(argc < 2){
return 1;
}
port = atoi(argv[1]);
mosquitto_lib_init();
mosq = mosquitto_new("01-extended-auth", true, NULL);
if(mosq == NULL){
return 1;
}
mosquitto_int_option(mosq, MOSQ_OPT_PROTOCOL_VERSION, 5);
mosquitto_connect_v5_callback_set(mosq, on_connect);
mosquitto_ext_auth_callback_set(mosq, on_ext_auth);
mosquitto_disconnect_v5_callback_set(mosq, on_disconnect);
mosquitto_property_add_int32(&props, MQTT_PROP_MAXIMUM_PACKET_SIZE, 1000);
rc = mosquitto_connect_bind_v5(mosq, "localhost", port, 60, NULL, props);
mosquitto_property_free_all(&props);
if(rc != MOSQ_ERR_SUCCESS) return rc;
while(run == -1){
mosquitto_loop(mosq, -1, 1);
}
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return run;
}

View file

@ -0,0 +1,83 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mosquitto.h>
#include <mosquitto/mqtt_protocol.h>
static int run = -1;
static void on_connect(struct mosquitto *mosq, void *obj, int rc, int flags, const mosquitto_property *properties)
{
(void)obj;
(void)rc;
(void)flags;
(void)properties;
/* FIXME - should verify flags and all properties here. */
if(rc){
exit(1);
}else{
mosquitto_disconnect(mosq);
}
}
static int on_ext_auth(struct mosquitto *mosq, void *obj, const char *auth_method, uint16_t auth_data_len, const void *auth_data, const mosquitto_property *properties)
{
(void)mosq;
(void)obj;
(void)auth_method;
(void)auth_data;
(void)auth_data_len;
(void)properties;
return MOSQ_ERR_AUTH;
}
static void on_disconnect(struct mosquitto *mosq, void *obj, int rc, const mosquitto_property *properties)
{
(void)mosq;
(void)obj;
(void)properties;
/* FIXME - should verify flags and all properties here. */
run = rc;
}
int main(int argc, char *argv[])
{
int rc;
struct mosquitto *mosq;
int port;
mosquitto_property *props = NULL;
if(argc < 2){
return 1;
}
port = atoi(argv[1]);
mosquitto_lib_init();
mosq = mosquitto_new("01-extended-auth", true, NULL);
if(mosq == NULL){
return 1;
}
mosquitto_int_option(mosq, MOSQ_OPT_PROTOCOL_VERSION, 5);
mosquitto_connect_v5_callback_set(mosq, on_connect);
mosquitto_ext_auth_callback_set(mosq, on_ext_auth);
mosquitto_disconnect_v5_callback_set(mosq, on_disconnect);
mosquitto_property_add_int32(&props, MQTT_PROP_MAXIMUM_PACKET_SIZE, 1000);
rc = mosquitto_connect_bind_v5(mosq, "localhost", port, 60, NULL, props);
mosquitto_property_free_all(&props);
if(rc != MOSQ_ERR_SUCCESS) return rc;
while(run == -1){
mosquitto_loop(mosq, -1, 1);
}
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return run;
}

View file

@ -4,6 +4,8 @@ set(BINARIES
01-con-discon-will 01-con-discon-will
01-con-discon-will-clear 01-con-discon-will-clear
01-con-discon-will-v5 01-con-discon-will-v5
01-extended-auth-continue
01-extended-auth-failure
01-keepalive-pingreq 01-keepalive-pingreq
01-no-clean-session 01-no-clean-session
01-pre-connect-callback 01-pre-connect-callback

View file

@ -13,6 +13,8 @@ SRC = \
01-con-discon-will.c \ 01-con-discon-will.c \
01-con-discon-will-v5.c \ 01-con-discon-will-v5.c \
01-con-discon-will-clear.c \ 01-con-discon-will-clear.c \
01-extended-auth-continue.c \
01-extended-auth-failure.c \
01-keepalive-pingreq.c \ 01-keepalive-pingreq.c \
01-no-clean-session.c \ 01-no-clean-session.c \
01-pre-connect-callback.c \ 01-pre-connect-callback.c \

View file

@ -0,0 +1,84 @@
#include <cassert>
#include <cstring>
#include <mosquitto/libmosquittopp.h>
static int run = -1;
class mosquittopp_test : public mosqpp::mosquittopp
{
public:
mosquittopp_test(const char *id);
void on_connect_v5(int rc, int flags, const mosquitto_property *props);
void on_disconnect_v5(int rc, const mosquitto_property *props);
int on_ext_auth(const char *auth_method, uint16_t auth_data_len, const void *auth_data, const mosquitto_property *props);
};
mosquittopp_test::mosquittopp_test(const char *id) : mosqpp::mosquittopp(id)
{
}
void mosquittopp_test::on_connect_v5(int rc, int flags, const mosquitto_property *props)
{
assert(flags == 0);
assert(props);
assert(mosqpp::property_check_all(CMD_CONNACK, props) == MOSQ_ERR_SUCCESS);
if(rc){
exit(1);
}else{
disconnect();
}
}
void mosquittopp_test::on_disconnect_v5(int rc, const mosquitto_property *props)
{
assert(props == NULL);
run = rc;
}
int mosquittopp_test::on_ext_auth(const char *auth_method, uint16_t auth_data_len, const void *auth_data, const mosquitto_property *props)
{
assert(props != NULL);
if(strcmp(auth_method, "test-method")){
run = 1;
return MOSQ_ERR_AUTH;
}
if(auth_data_len == 0 || (!auth_data || strcmp((const char *)auth_data, "test-request"))){
run = 1;
return MOSQ_ERR_AUTH;
}
return ext_auth_continue(auth_method, strlen("test-reply"), "test-reply", NULL);
}
int main(int argc, char *argv[])
{
mosquittopp_test *mosq;
mosquitto_property *props = NULL;
int rc;
assert(argc == 2);
int port = atoi(argv[1]);
mosqpp::lib_init();
mosq = new mosquittopp_test("01-extended-auth");
mosq->int_option(MOSQ_OPT_PROTOCOL_VERSION, 5);
mosquitto_property_add_int32(&props, MQTT_PROP_MAXIMUM_PACKET_SIZE, 1000);
rc = mosq->connect_v5("localhost", port, 60, NULL, props);
mosquitto_property_free_all(&props);
if(rc != MOSQ_ERR_SUCCESS) return rc;
while(run == -1){
mosq->loop();
}
delete mosq;
mosqpp::lib_cleanup();
return run;
}

View file

@ -0,0 +1,78 @@
#include <cassert>
#include <cstring>
#include <mosquitto/libmosquittopp.h>
static int run = -1;
class mosquittopp_test : public mosqpp::mosquittopp
{
public:
mosquittopp_test(const char *id);
void on_connect_v5(int rc, int flags, const mosquitto_property *props);
void on_disconnect_v5(int rc, const mosquitto_property *props);
int on_ext_auth(const char *auth_method, uint16_t auth_data_len, const void *auth_data, const mosquitto_property *props);
};
mosquittopp_test::mosquittopp_test(const char *id) : mosqpp::mosquittopp(id)
{
}
void mosquittopp_test::on_connect_v5(int rc, int flags, const mosquitto_property *props)
{
assert(flags == 0);
assert(props);
assert(mosqpp::property_check_all(CMD_CONNACK, props) == MOSQ_ERR_SUCCESS);
if(rc){
exit(1);
}else{
disconnect();
}
}
void mosquittopp_test::on_disconnect_v5(int rc, const mosquitto_property *props)
{
assert(props == NULL);
run = rc;
}
int mosquittopp_test::on_ext_auth(const char *auth_method, uint16_t auth_data_len, const void *auth_data, const mosquitto_property *props)
{
(void)auth_method;
(void)auth_data_len;
(void)auth_data;
(void)props;
return MOSQ_ERR_AUTH;
}
int main(int argc, char *argv[])
{
mosquittopp_test *mosq;
mosquitto_property *props = NULL;
int rc;
assert(argc == 2);
int port = atoi(argv[1]);
mosqpp::lib_init();
mosq = new mosquittopp_test("01-extended-auth");
mosq->int_option(MOSQ_OPT_PROTOCOL_VERSION, 5);
mosquitto_property_add_int32(&props, MQTT_PROP_MAXIMUM_PACKET_SIZE, 1000);
rc = mosq->connect_v5("localhost", port, 60, NULL, props);
mosquitto_property_free_all(&props);
if(rc != MOSQ_ERR_SUCCESS) return rc;
while(run == -1){
mosq->loop();
}
delete mosq;
mosqpp::lib_cleanup();
return run;
}

View file

@ -4,6 +4,8 @@ set(BINARIES
01-con-discon-will-clear 01-con-discon-will-clear
01-con-discon-will 01-con-discon-will
01-con-discon-will-v5 01-con-discon-will-v5
01-extended-auth-continue
01-extended-auth-failure
01-keepalive-pingreq 01-keepalive-pingreq
01-no-clean-session 01-no-clean-session
01-pre-connect-callback 01-pre-connect-callback

View file

@ -12,6 +12,8 @@ SRC = \
01-con-discon-will-clear.cpp \ 01-con-discon-will-clear.cpp \
01-con-discon-will-v5.cpp \ 01-con-discon-will-v5.cpp \
01-con-discon-will.cpp \ 01-con-discon-will.cpp \
01-extended-auth-continue.cpp \
01-extended-auth-failure.cpp \
01-keepalive-pingreq.cpp \ 01-keepalive-pingreq.cpp \
01-no-clean-session.cpp \ 01-no-clean-session.cpp \
01-pre-connect-callback.cpp \ 01-pre-connect-callback.cpp \

View file

@ -9,6 +9,8 @@ tests = [
(1, './01-con-discon-will-clear.py'), (1, './01-con-discon-will-clear.py'),
(1, './01-con-discon-will-v5.py'), (1, './01-con-discon-will-v5.py'),
(1, './01-con-discon-will.py'), (1, './01-con-discon-will.py'),
(1, './01-extended-auth-complete.py'),
(1, './01-extended-auth-failure.py'),
(1, './01-keepalive-pingreq.py'), (1, './01-keepalive-pingreq.py'),
(1, './01-no-clean-session.py'), (1, './01-no-clean-session.py'),
(1, './01-server-keepalive-pingreq.py'), (1, './01-server-keepalive-pingreq.py'),