From 3b6b6d5fa80fd811ffb7d3166cfe8cacada7dae0 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 26 Feb 2019 12:39:33 +0000 Subject: [PATCH] Test improvements And some related fixes. --- src/database.c | 1 + src/handle_publish.c | 3 +- src/persist.c | 6 +++ src/security_default.c | 86 +++++++++++++++++++++++++++++++----------- src/uhpa.h | 2 +- test/mosq_test.py | 28 +++++++++++++- 6 files changed, 102 insertions(+), 24 deletions(-) diff --git a/src/database.c b/src/database.c index 0755b174..193db02b 100644 --- a/src/database.c +++ b/src/database.c @@ -261,6 +261,7 @@ static void db__message_remove(struct mosquitto_db *db, struct mosquitto *contex context->last_inflight_msg = NULL; } } + mosquitto_property_free_all(&(*msg)->properties); mosquitto__free(*msg); if(last){ *msg = last->next; diff --git a/src/handle_publish.c b/src/handle_publish.c index 366c6521..7ec5aff3 100644 --- a/src/handle_publish.c +++ b/src/handle_publish.c @@ -254,11 +254,12 @@ int handle__publish(struct mosquitto_db *db, struct mosquitto *context) log__printf(NULL, MOSQ_LOG_DEBUG, "Dropped too large PUBLISH from %s (d%d, q%d, r%d, m%d, '%s', ... (%ld bytes))", context->id, dup, qos, retain, mid, topic, (long)payloadlen); goto process_bad_message; } - if(UHPA_ALLOC(payload, payloadlen+1) == 0){ + if(UHPA_ALLOC(payload, payloadlen) == 0){ mosquitto__free(topic); mosquitto_property_free_all(&msg_properties); return MOSQ_ERR_NOMEM; } + if(packet__read_bytes(&context->in_packet, UHPA_ACCESS(payload, payloadlen), payloadlen)){ mosquitto__free(topic); UHPA_FREE(payload, payloadlen); diff --git a/src/persist.c b/src/persist.c index f70f411f..ef487879 100644 --- a/src/persist.c +++ b/src/persist.c @@ -770,6 +770,7 @@ static int persist__msg_store_chunk_restore(struct mosquitto_db *db, FILE *db_fp mosquitto__free(load); fclose(db_fptr); mosquitto__free(source.id); + mosquitto__free(source.id); return rc; } @@ -784,6 +785,7 @@ static int persist__msg_store_chunk_restore(struct mosquitto_db *db, FILE *db_fp mosquitto__free(load); fclose(db_fptr); mosquitto__free(source.id); + mosquitto__free(source.username); mosquitto__free(topic); log__printf(NULL, MOSQ_LOG_ERR, "Error: Out of memory."); return MOSQ_ERR_NOMEM; @@ -793,6 +795,9 @@ static int persist__msg_store_chunk_restore(struct mosquitto_db *db, FILE *db_fp rc = db__message_store(db, &source, source_mid, topic, qos, payloadlen, &payload, retain, &stored, 0, NULL, store_id); mosquitto__free(source.id); + source.id = NULL; + mosquitto__free(source.username); + source.username = NULL; if(rc == MOSQ_ERR_SUCCESS){ load->db_id = stored->db_id; @@ -812,6 +817,7 @@ error: log__printf(NULL, MOSQ_LOG_ERR, "Error: %s.", err); fclose(db_fptr); mosquitto__free(source.id); + mosquitto__free(source.username); mosquitto__free(topic); UHPA_FREE(payload, payloadlen); return 1; diff --git a/src/security_default.c b/src/security_default.c index 58ee8b48..5edacb56 100644 --- a/src/security_default.c +++ b/src/security_default.c @@ -720,25 +720,28 @@ static int pwfile__parse(const char *file, struct mosquitto__unpwd **root) return MOSQ_ERR_SUCCESS; } -static int unpwd__file_parse(struct mosquitto__unpwd **unpwd, const char *password_file) -{ - int rc; + #ifdef WITH_TLS + +static void unpwd__free_item(struct mosquitto__unpwd **unpwd, struct mosquitto__unpwd *item) +{ + mosquitto__free(item->username); + mosquitto__free(item->password); + mosquitto__free(item->salt); + HASH_DEL(*unpwd, item); + mosquitto__free(item); +} + + +static int unpwd__decode_passwords(struct mosquitto__unpwd **unpwd) +{ struct mosquitto__unpwd *u, *tmp; char *token; unsigned char *salt; unsigned int salt_len; unsigned char *password; unsigned int password_len; -#endif - - if(!unpwd) return MOSQ_ERR_INVAL; - - if(!password_file) return MOSQ_ERR_SUCCESS; - - rc = pwfile__parse(password_file, unpwd); -#ifdef WITH_TLS - if(rc) return rc; + int rc; HASH_ITER(hh, *unpwd, u, tmp){ /* Need to decode password into hashed data + salt. */ @@ -760,30 +763,49 @@ static int unpwd__file_parse(struct mosquitto__unpwd **unpwd, const char *passwo u->password_len = password_len; }else{ log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to decode password for user %s, removing entry.", u->username); - HASH_DEL(*unpwd, u); + unpwd__free_item(unpwd, u); } }else{ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid password hash for user %s, removing entry.", u->username); - HASH_DEL(*unpwd, u); + unpwd__free_item(unpwd, u); } }else{ log__printf(NULL, MOSQ_LOG_ERR, "Error: Unable to decode password salt for user %s, removing entry.", u->username); - HASH_DEL(*unpwd, u); + unpwd__free_item(unpwd, u); } }else{ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid password hash for user %s, removing entry.", u->username); - HASH_DEL(*unpwd, u); + unpwd__free_item(unpwd, u); } }else{ log__printf(NULL, MOSQ_LOG_ERR, "Error: Invalid password hash for user %s, removing entry.", u->username); - HASH_DEL(*unpwd, u); + unpwd__free_item(unpwd, u); } }else{ log__printf(NULL, MOSQ_LOG_ERR, "Error: Missing password hash for user %s, removing entry.", u->username); - HASH_DEL(*unpwd, u); + unpwd__free_item(unpwd, u); } } + + return MOSQ_ERR_SUCCESS; +} #endif + + +static int unpwd__file_parse(struct mosquitto__unpwd **unpwd, const char *password_file) +{ + int rc; + if(!unpwd) return MOSQ_ERR_INVAL; + + if(!password_file) return MOSQ_ERR_SUCCESS; + + rc = pwfile__parse(password_file, unpwd); + +#ifdef WITH_TLS + if(rc) return rc; + rc = unpwd__decode_passwords(unpwd); +#endif + return rc; } @@ -1063,21 +1085,43 @@ int pw__digest(const char *password, const unsigned char *salt, unsigned int sal int base64__decode(char *in, unsigned char **decoded, unsigned int *decoded_len) { BIO *bmem, *b64; + int slen; + + slen = strlen(in); b64 = BIO_new(BIO_f_base64()); + if(!b64){ + return 1; + } BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + bmem = BIO_new(BIO_s_mem()); + if(!bmem){ + BIO_free_all(b64); + return 1; + } b64 = BIO_push(b64, bmem); - BIO_write(bmem, in, strlen(in)); + BIO_write(bmem, in, slen); if(BIO_flush(bmem) != 1){ BIO_free_all(b64); return 1; } - *decoded = mosquitto__calloc(strlen(in), 1); - *decoded_len = BIO_read(b64, *decoded, strlen(in)); + *decoded = mosquitto__calloc(slen, 1); + if(!(*decoded)){ + BIO_free_all(b64); + return 1; + } + *decoded_len = BIO_read(b64, *decoded, slen); BIO_free_all(b64); + if(*decoded_len <= 0){ + mosquitto__free(*decoded); + *decoded = NULL; + *decoded_len = 0; + return 1; + } + return 0; } diff --git a/src/uhpa.h b/src/uhpa.h index cd59dd9c..6ef9dc98 100644 --- a/src/uhpa.h +++ b/src/uhpa.h @@ -155,7 +155,7 @@ Contributors: # define UHPA_ALLOC(u, size) ((u).ptr = uhpa_malloc(size)) # define UHPA_ACCESS(u, size) (u).ptr # define UHPA_FREE(u, size) uhpa_free((u).ptr); (u).ptr = NULL; -# define UHPA_MOVE(dest, src, src_size) {(dest).ptr = (src).ptr; (src).ptr = NULL} +# define UHPA_MOVE(dest, src, src_size) {(dest).ptr = (src).ptr; (src).ptr = NULL;} #else # define UHPA_ALLOC(u, size) UHPA_ALLOC_CHK(u, size) # define UHPA_ACCESS(u, size) UHPA_ACCESS_CHK(u, size) diff --git a/test/mosq_test.py b/test/mosq_test.py index 6e9bb7b4..23428f53 100644 --- a/test/mosq_test.py +++ b/test/mosq_test.py @@ -8,7 +8,17 @@ import time import mqtt5_props +import __main__ + +import atexit +vg_index = 1 +vg_logfiles = [] + + def start_broker(filename, cmd=None, port=0, use_conf=False, expect_fail=False): + global vg_index + global vg_logfiles + delay = 0.1 if use_conf == True: @@ -26,7 +36,10 @@ def start_broker(filename, cmd=None, port=0, use_conf=False, expect_fail=False): port = 1888 if os.environ.get('MOSQ_USE_VALGRIND') is not None: - cmd = ['valgrind', '-q', '--trace-children=yes', '--leak-check=full', '--show-leak-kinds=all', '--log-file='+filename+'.vglog'] + cmd + logfile = filename+'.'+str(vg_index)+'.vglog' + cmd = ['valgrind', '-q', '--trace-children=yes', '--leak-check=full', '--show-leak-kinds=all', '--log-file='+logfile] + cmd + vg_logfiles.append(logfile) + vg_index += 1 delay = 1 #print(port) @@ -567,3 +580,16 @@ def get_lib_port(): return int(sys.argv[2]) else: return 1888 + + +@atexit.register +def test_cleanup(): + global vg_logfiles + + if os.environ.get('MOSQ_USE_VALGRIND') is not None: + for f in vg_logfiles: + try: + if os.stat(f).st_size == 0: + os.remove(f) + except OSError: + pass