diff --git a/src/handle_connect.c b/src/handle_connect.c index 088ea051..ad737b8f 100644 --- a/src/handle_connect.c +++ b/src/handle_connect.c @@ -132,6 +132,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) int i; struct mosquitto__security_options *security_opts; mosquitto_property *properties = NULL; + mosquitto_property *connack_props = NULL; #ifdef WITH_TLS X509 *client_cert = NULL; X509_NAME *name; @@ -179,7 +180,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) log__printf(NULL, MOSQ_LOG_INFO, "Invalid protocol version %d in CONNECT from %s.", protocol_version, context->address); } - send__connack(db, context, 0, CONNACK_REFUSED_PROTOCOL_VERSION); + send__connack(db, context, 0, CONNACK_REFUSED_PROTOCOL_VERSION, NULL); rc = MOSQ_ERR_PROTOCOL; goto handle_connect_error; } @@ -194,7 +195,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) log__printf(NULL, MOSQ_LOG_INFO, "Invalid protocol version %d in CONNECT from %s.", protocol_version, context->address); } - send__connack(db, context, 0, CONNACK_REFUSED_PROTOCOL_VERSION); + send__connack(db, context, 0, CONNACK_REFUSED_PROTOCOL_VERSION, NULL); rc = MOSQ_ERR_PROTOCOL; goto handle_connect_error; } @@ -238,7 +239,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) if(will && will_retain && db->config->retain_available == false){ if(protocol_version == mosq_p_mqtt5){ - send__connack(db, context, 0, MQTT_RC_RETAIN_NOT_SUPPORTED); + send__connack(db, context, 0, MQTT_RC_RETAIN_NOT_SUPPORTED, NULL); } rc = 1; goto handle_connect_error; @@ -265,7 +266,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) if(slen == 0){ if(context->protocol == mosq_p_mqtt31){ - send__connack(db, context, 0, CONNACK_REFUSED_IDENTIFIER_REJECTED); + send__connack(db, context, 0, CONNACK_REFUSED_IDENTIFIER_REJECTED, NULL); rc = MOSQ_ERR_PROTOCOL; goto handle_connect_error; }else{ /* mqtt311/mqtt5 */ @@ -279,7 +280,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) allow_zero_length_clientid = db->config->security_options.allow_zero_length_clientid; } if(clean_start == 0 || allow_zero_length_clientid == false){ - send__connack(db, context, 0, CONNACK_REFUSED_IDENTIFIER_REJECTED); + send__connack(db, context, 0, CONNACK_REFUSED_IDENTIFIER_REJECTED, NULL); rc = MOSQ_ERR_PROTOCOL; goto handle_connect_error; }else{ @@ -292,6 +293,12 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) rc = MOSQ_ERR_NOMEM; goto handle_connect_error; } + if(context->protocol == mosq_p_mqtt5){ + if(mosquitto_property_add_string(&connack_props, MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER, client_id)){ + rc = MOSQ_ERR_NOMEM; + goto handle_connect_error; + } + } } } } @@ -299,7 +306,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) /* clientid_prefixes check */ if(db->config->clientid_prefixes){ if(strncmp(db->config->clientid_prefixes, client_id, strlen(db->config->clientid_prefixes))){ - send__connack(db, context, 0, CONNACK_REFUSED_NOT_AUTHORIZED); + send__connack(db, context, 0, CONNACK_REFUSED_NOT_AUTHORIZED, NULL); rc = 1; goto handle_connect_error; } @@ -425,7 +432,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) password = NULL; if(!context->ssl){ - send__connack(db, context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD); + send__connack(db, context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD, NULL); rc = 1; goto handle_connect_error; } @@ -433,7 +440,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) if(context->listener->psk_hint){ /* Client should have provided an identity to get this far. */ if(!context->username){ - send__connack(db, context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD); + send__connack(db, context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD, NULL); rc = 1; goto handle_connect_error; } @@ -441,20 +448,20 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) #endif /* WITH_TLS_PSK */ client_cert = SSL_get_peer_certificate(context->ssl); if(!client_cert){ - send__connack(db, context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD); + send__connack(db, context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD, NULL); rc = 1; goto handle_connect_error; } name = X509_get_subject_name(client_cert); if(!name){ - send__connack(db, context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD); + send__connack(db, context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD, NULL); rc = 1; goto handle_connect_error; } if (context->listener->use_identity_as_username) { //use_identity_as_username i = X509_NAME_get_index_by_NID(name, NID_commonName, -1); if(i == -1){ - send__connack(db, context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD); + send__connack(db, context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD, NULL); rc = 1; goto handle_connect_error; } @@ -462,19 +469,19 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) if(name_entry){ name_asn1 = X509_NAME_ENTRY_get_data(name_entry); if (name_asn1 == NULL) { - send__connack(db, context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD); + send__connack(db, context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD, NULL); rc = 1; goto handle_connect_error; } context->username = mosquitto__strdup((char *) ASN1_STRING_data(name_asn1)); if(!context->username){ - send__connack(db, context, 0, CONNACK_REFUSED_SERVER_UNAVAILABLE); + send__connack(db, context, 0, CONNACK_REFUSED_SERVER_UNAVAILABLE, NULL); rc = MOSQ_ERR_NOMEM; goto handle_connect_error; } /* Make sure there isn't an embedded NUL character in the CN */ if ((size_t)ASN1_STRING_length(name_asn1) != strlen(context->username)) { - send__connack(db, context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD); + send__connack(db, context, 0, CONNACK_REFUSED_BAD_USERNAME_PASSWORD, NULL); rc = 1; goto handle_connect_error; } @@ -518,7 +525,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) case MOSQ_ERR_SUCCESS: break; case MOSQ_ERR_AUTH: - send__connack(db, context, 0, CONNACK_REFUSED_NOT_AUTHORIZED); + send__connack(db, context, 0, CONNACK_REFUSED_NOT_AUTHORIZED, NULL); context__disconnect(db, context); rc = 1; goto handle_connect_error; @@ -539,7 +546,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) if((db->config->per_listener_settings && context->listener->security_options.allow_anonymous == false) || (!db->config->per_listener_settings && db->config->security_options.allow_anonymous == false)){ - send__connack(db, context, 0, CONNACK_REFUSED_NOT_AUTHORIZED); + send__connack(db, context, 0, CONNACK_REFUSED_NOT_AUTHORIZED, NULL); rc = 1; goto handle_connect_error; } @@ -557,7 +564,7 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) goto handle_connect_error; } }else{ - send__connack(db, context, 0, CONNACK_REFUSED_NOT_AUTHORIZED); + send__connack(db, context, 0, CONNACK_REFUSED_NOT_AUTHORIZED, NULL); rc = 1; goto handle_connect_error; } @@ -710,7 +717,9 @@ int handle__connect(struct mosquitto_db *db, struct mosquitto *context) } #endif context->state = mosq_cs_connected; - return send__connack(db, context, connect_ack, CONNACK_ACCEPTED); + rc = send__connack(db, context, connect_ack, CONNACK_ACCEPTED, connack_props); + mosquitto_property_free_all(&connack_props); + return rc; handle_connect_error: mosquitto__free(client_id); @@ -721,6 +730,7 @@ handle_connect_error: if(will_struct){ mosquitto_property_free_all(&will_struct->properties); } + mosquitto_property_free_all(&connack_props); mosquitto__free(will_struct); #ifdef WITH_TLS if(client_cert) X509_free(client_cert); diff --git a/src/mosquitto_broker_internal.h b/src/mosquitto_broker_internal.h index 3cfe0738..7a1b6bd7 100644 --- a/src/mosquitto_broker_internal.h +++ b/src/mosquitto_broker_internal.h @@ -512,7 +512,7 @@ int restore_privileges(void); /* ============================================================ * Server send functions * ============================================================ */ -int send__connack(struct mosquitto_db *db, struct mosquitto *context, int ack, int reason_code); +int send__connack(struct mosquitto_db *db, struct mosquitto *context, int ack, int reason_code, const mosquitto_property *properties); int send__suback(struct mosquitto *context, uint16_t mid, uint32_t payloadlen, const void *payload); int send__unsuback(struct mosquitto *context, uint16_t mid, const mosquitto_property *properties); diff --git a/src/send_connack.c b/src/send_connack.c index 0891af60..1c20820c 100644 --- a/src/send_connack.c +++ b/src/send_connack.c @@ -23,13 +23,18 @@ Contributors: #include "property_mosq.h" #include "util_mosq.h" -int send__connack(struct mosquitto_db *db, struct mosquitto *context, int ack, int reason_code) +int send__connack(struct mosquitto_db *db, struct mosquitto *context, int ack, int reason_code, const mosquitto_property *properties) { struct mosquitto__packet *packet = NULL; int rc; - mosquitto_property *properties = NULL; + mosquitto_property *connack_props = NULL; int proplen, varbytes; + rc = mosquitto_property_copy_all(&connack_props, properties); + if(rc){ + return rc; + } + if(context){ if(context->id){ log__printf(NULL, MOSQ_LOG_DEBUG, "Sending CONNACK to %s (%d, %d)", context->id, ack, reason_code); @@ -45,25 +50,25 @@ int send__connack(struct mosquitto_db *db, struct mosquitto *context, int ack, i packet->remaining_length = 2; if(context->protocol == mosq_p_mqtt5){ if(reason_code < 128 && db->config->retain_available == false){ - rc = mosquitto_property_add_byte(&properties, MQTT_PROP_RETAIN_AVAILABLE, 0); + rc = mosquitto_property_add_byte(&connack_props, MQTT_PROP_RETAIN_AVAILABLE, 0); if(rc){ mosquitto__free(packet); return rc; } } /* FIXME - disable support until available */ - rc = mosquitto_property_add_byte(&properties, MQTT_PROP_SHARED_SUB_AVAILABLE, 0); + rc = mosquitto_property_add_byte(&connack_props, MQTT_PROP_SHARED_SUB_AVAILABLE, 0); if(rc){ mosquitto__free(packet); return rc; } - rc = mosquitto_property_add_byte(&properties, MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE, 0); + rc = mosquitto_property_add_byte(&connack_props, MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE, 0); if(rc){ mosquitto__free(packet); return rc; } - proplen = property__get_length_all(properties); + proplen = property__get_length_all(connack_props); varbytes = packet__varint_bytes(proplen); packet->remaining_length += proplen + varbytes; } @@ -75,9 +80,9 @@ int send__connack(struct mosquitto_db *db, struct mosquitto *context, int ack, i packet__write_byte(packet, ack); packet__write_byte(packet, reason_code); if(context->protocol == mosq_p_mqtt5){ - property__write_all(packet, properties); + property__write_all(packet, connack_props); } - mosquitto_property_free_all(&properties); + mosquitto_property_free_all(&connack_props); return packet__queue(context, packet); }