From f62018451f7868544aee63ff67599ef92a0e8dda Mon Sep 17 00:00:00 2001 From: Deomid Ryabkov Date: Wed, 30 Aug 2017 09:42:24 +0100 Subject: [PATCH] Fix subscription parsing in MQTT broker Also, do not accept PUBLISH and SUBSCRIBE before a sucessful CONNECT. PUBLISHED_FROM=b5096cdc2ec5da1358244c428efbbb2e20be1a05 --- mongoose.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/mongoose.c b/mongoose.c index d83a2e47..2c81f5df 100644 --- a/mongoose.c +++ b/mongoose.c @@ -10234,15 +10234,16 @@ void mg_mqtt_subscribe(struct mg_connection *nc, int mg_mqtt_next_subscribe_topic(struct mg_mqtt_message *msg, struct mg_str *topic, uint8_t *qos, int pos) { unsigned char *buf = (unsigned char *) msg->payload.p + pos; + int new_pos; - if ((size_t) pos >= msg->payload.len) { - return -1; - } + if ((size_t) pos >= msg->payload.len) return -1; topic->len = buf[0] << 8 | buf[1]; topic->p = (char *) buf + 2; *qos = buf[2 + topic->len]; - return pos + 2 + topic->len + 1; + new_pos = pos + 2 + topic->len + 1; + if ((size_t) new_pos > msg->payload.len) return -1; + return new_pos; } void mg_mqtt_unsubscribe(struct mg_connection *nc, char **topics, @@ -10467,13 +10468,28 @@ void mg_mqtt_broker(struct mg_connection *nc, int ev, void *data) { nc->user_data = NULL; /* Clear up the inherited pointer to broker */ break; case MG_EV_MQTT_CONNECT: - mg_mqtt_broker_handle_connect(brk, nc); + if (nc->user_data == NULL) { + mg_mqtt_broker_handle_connect(brk, nc); + } else { + /* Repeated CONNECT */ + nc->flags |= MG_F_CLOSE_IMMEDIATELY; + } break; case MG_EV_MQTT_SUBSCRIBE: - mg_mqtt_broker_handle_subscribe(nc, msg); + if (nc->user_data != NULL) { + mg_mqtt_broker_handle_subscribe(nc, msg); + } else { + /* Subscribe before CONNECT */ + nc->flags |= MG_F_CLOSE_IMMEDIATELY; + } break; case MG_EV_MQTT_PUBLISH: - mg_mqtt_broker_handle_publish(brk, msg); + if (nc->user_data != NULL) { + mg_mqtt_broker_handle_publish(brk, msg); + } else { + /* Publish before CONNECT */ + nc->flags |= MG_F_CLOSE_IMMEDIATELY; + } break; case MG_EV_CLOSE: if (nc->listener && nc->user_data != NULL) {