mirror of
https://github.com/eclipse-mosquitto/mosquitto.git
synced 2026-05-21 12:24:29 +02:00
Add mosquitto_ext_auth_continue()
This commit is contained in:
parent
dd2c25c1cf
commit
a2fe980301
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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;}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 \
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
64
lib/extended_auth.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
28
test/lib/01-extended-auth-continue.py
Executable file
28
test/lib/01-extended-auth-continue.py
Executable 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)
|
||||||
24
test/lib/01-extended-auth-failure.py
Executable file
24
test/lib/01-extended-auth-failure.py
Executable 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)
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
89
test/lib/c/01-extended-auth-continue.c
Normal file
89
test/lib/c/01-extended-auth-continue.c
Normal 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;
|
||||||
|
}
|
||||||
83
test/lib/c/01-extended-auth-failure.c
Normal file
83
test/lib/c/01-extended-auth-failure.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 \
|
||||||
|
|
|
||||||
84
test/lib/cpp/01-extended-auth-continue.cpp
Normal file
84
test/lib/cpp/01-extended-auth-continue.cpp
Normal 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;
|
||||||
|
}
|
||||||
78
test/lib/cpp/01-extended-auth-failure.cpp
Normal file
78
test/lib/cpp/01-extended-auth-failure.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 \
|
||||||
|
|
|
||||||
|
|
@ -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'),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue