From 733c700492b3dca19be90b7374309188ec49cff1 Mon Sep 17 00:00:00 2001 From: nis Date: Sun, 3 May 2020 00:19:54 +0200 Subject: [PATCH] struct padding error fix --- src/hash.c | 13 +++-- src/node.c | 168 +++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 145 insertions(+), 36 deletions(-) diff --git a/src/hash.c b/src/hash.c index a3665a0..7414934 100644 --- a/src/hash.c +++ b/src/hash.c @@ -10,7 +10,11 @@ void hash_data(pub_data *data, unsigned char *buf) { // The resulting buf is hashed and put into a buffer unsigned char hash[SHA256_DIGEST_LENGTH]; - SHA256(concat, totlen, hash); + + SHA256_CTX sha256; + SHA256_Init(&sha256); + SHA256_Update(&sha256, concat, totlen); + SHA256_Final(hash, &sha256); // Put truncated hash into buf hash_trunc(hash, buf); @@ -35,9 +39,10 @@ void hash_network(list *data_list, unsigned char *buf) { } // Hash all of concat to obtain the network hash - if (SHA256(concat, totlen, hash) == NULL) { - print_debug(">> Doing the hash failed : function return NULL, should return a pointer."); - }; + SHA256_CTX sha256; + SHA256_Init(&sha256); + SHA256_Update(&sha256, concat, concat_len); + SHA256_Final(hash, &sha256); // Put truncated hash into buf hash_trunc(hash, buf); diff --git a/src/node.c b/src/node.c index beae120..c2fa4af 100644 --- a/src/node.c +++ b/src/node.c @@ -698,6 +698,51 @@ int validate_tlv(char *data, int pos, uint16_t packet_len){ return 7; case 8: if(tlv_len < MIN_LEN_NODE_STATE || tlv_len > MAX_LEN_NODE_STATE) return -1; + + /* + // Check if it has the right hash + uint16_t *seqno = (uint16_t*) (data + pos + 10); + uint64_t *id = (uint64_t*) (data + pos + 2); + + pub_data pdata = (pub_data) { + .length = tlv_len, + .id = *id, + .seqno = *seqno, + .data = (unsigned char*) malloc(tlv_len) + }; + + unsigned char *cur_hash = (unsigned char*) (data + pos + 12); + char *cur_message = data + pos + 28; + + unsigned char hash[16]; + + memcpy(pdata.data, cur_message, tlv_len); + + hash_data(&pdata, hash); + + if(memcmp(hash, cur_hash, 16) != 0) { + print_debug(">> Malformed hash."); + printf("\x1b[31m[DEBUG]\x1b[0m >> Received : "); + + for(int x = 0; x < 16; x++){ + printf("%02x", hash[x]); + fflush(0); + } + + printf("\n"); + printf("\x1b[31m[DEBUG]\x1b[0m >> Received : "); + + for(int x = 0; x < 16; x++){ + printf("%02x", cur_hash[x]); + fflush(0); + } + + printf("\n"); + + return -1; + + } + */ return 8; case 9: return 9; @@ -772,7 +817,7 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 * int nbr_of_tlvs = 0; int pos = 4; - unsigned char tlv_len, hash[16]; + unsigned char tlv_len, hash[16], hash2[16]; char warn[32]; // The TLV we are going to send back. @@ -798,6 +843,12 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 * int ifindex = 0; + // Temporary values + uint16_t *port, *seqno; + uint64_t *id; + unsigned char *cur_hash, *ip; + char *cur_message; + while(pos < total_packet_len) { // Making sure the current TLV we are looking at is valid. // TODO : I think we should reset all the structs here. @@ -850,13 +901,14 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 * print_debug(">> Received neighbour tlv, sending back network hash."); // We received a neighbour tlv so a tlv network hash is sent to that address - cur_tlv.neighbour = (neighbour*) (data + pos); + ip = (unsigned char*) (data + pos + 2); + port = (uint16_t*) (data + pos + 18); // Init dest socket memset(&new_neighbour, 0, sizeof(new_neighbour)); new_neighbour.sin6_family = AF_INET6; - memcpy(&new_neighbour.sin6_addr, &cur_tlv.neighbour->ip, 16); - new_neighbour.sin6_port = be16toh(cur_tlv.neighbour->port); + memcpy(&new_neighbour.sin6_addr, ip, 16); + new_neighbour.sin6_port = be16toh(*port); new_neighbour.sin6_scope_id = ifindex; // Build network hash @@ -874,7 +926,8 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 * print_debug(">> Received network_hash, comparing with our own.."); // We reveived a network hash tlv so we compare the hash with our own, // if they differ we send a network state request tlv - cur_tlv.network_hash = (network_hash*) (data + pos); + cur_hash = (unsigned char*) (data + pos + 2); + hash_network(data_list, hash); if (DEBUG_LEVEL > 1) { @@ -886,13 +939,13 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 * printf("\n"); printf("\x1b[31m[DEBUG]\x1b[0m >> Received : "); for(int x = 0; x < 16; x++){ - printf("%02x", cur_tlv.network_hash->network_hash[x]); + printf("%02x", cur_hash[x]); fflush(0); } printf("\n"); } - if(memcmp(hash, cur_tlv.network_hash->network_hash, 16) != 0) { + if(memcmp(hash, cur_hash, 16) != 0) { print_debug(">> Sending out our network hash."); build_network_state_req(&new_tlv); send_single_tlv(&new_tlv, sender, socket_num); @@ -931,16 +984,20 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 * // we send a node state request, //if the hashes are identical nothing has to be done print_debug(">> Received node hash, updating message entry..."); - cur_tlv.node_hash = (node_hash*) (data + pos); - pdata = get_data(be64toh(cur_tlv.node_hash->node_id)); + + id = (uint64_t*) (data + pos + 2); + cur_hash = (unsigned char*) (data + pos + 12); + + pdata = get_data(be64toh(*id)); // If data is found for this id then we check that both hashes are the same if(pdata != NULL) { + print_debug(">> Comparing hashes..."); // We hash the data stored in the data list hash_data(pdata, hash); // If both hashes are the same then nothing has to be done - if(memcmp(hash, cur_tlv.node_hash->node_hash, 16) == 0) { + if(memcmp(hash, cur_hash, 16) == 0) { // The position is updated tlv_len = data[pos+1]; pos += tlv_len + 2; @@ -950,9 +1007,9 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 * } - print_debug(">> No hash found, or hashs are differents, sending back node state request."); + print_debug(">> No hash found, or hashs are different, sending back node state request."); // If no pub_data was found or the hashes differ then we send a node state request - build_node_state_req(&new_tlv, be64toh(cur_tlv.node_hash->node_id)); + build_node_state_req(&new_tlv, be64toh(*id)); add_tlv(&pack, &new_tlv, sender, socket_num); // The position is updated @@ -966,8 +1023,10 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 * // so a node state tlv for this node id has to be sent, // if no pub_data exists for this id nothing is sent print_debug(">> Received node state request. Processing..."); - cur_tlv.node_state_req = (node_state_req*) (data + pos); - pdata = get_data(be64toh(cur_tlv.node_state_req->node_id)); + + id = (uint64_t*) (data + pos + 2); + + pdata = get_data(be64toh(*id)); if(pdata != NULL) { build_node_state(&new_tlv, pdata->id, pdata->seqno, pdata->data, pdata->length); @@ -986,46 +1045,90 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 * // we add it to the data list // or update the data stored print_debug(">> Received node state, updating..."); - cur_tlv.node_state = (node_state*) (data + pos); + + tlv_len = data[pos + 1]; + id = (uint64_t*) (data + pos + 2); + seqno = (uint16_t*) (data + pos + 10); + cur_hash = (unsigned char*) (data + pos + 12); + cur_message = data + pos + 28; print_debug(">> Received message ! "); - printf("Type : %d\n", cur_tlv.node_state->type ); - printf("Length : %d\n", cur_tlv.node_state->length ); - printf("Node ID : %lu\n", be64toh(cur_tlv.node_state->node_id) ); - printf("Seqno : %hu\n", be16toh(cur_tlv.node_state->seqno) ); + printf("Type : %d\n", data[pos] ); + printf("Length : %d\n", tlv_len ); + printf("Node ID : %lu\n", be64toh(*id) ); + printf("Seqno : %hu\n", be16toh(*seqno) ); printf("Hash :"); for(int x = 0; x < 16; x++){ - printf("%02x", cur_tlv.node_state->node_hash[x]); + printf("%02x", cur_hash[x]); fflush(0); } printf("\n"); - for(int x = 0; x < 192; x++){ - printf("%d", cur_tlv.node_state->data[x]); + for(int x = 0; x < tlv_len; x++){ + printf("%c", cur_message[x]); fflush(0); } + printf("\n"); + // Check if it has the right hash + pub_data pdata_check = (pub_data) { + .length = tlv_len, + .id = *id, + .seqno = *seqno, + .data = (unsigned char*) malloc(tlv_len) + }; + + memcpy(pdata_check.data, cur_message, tlv_len); + + hash_data(&pdata_check, hash2); + + if(memcmp(hash2, cur_hash, 16) != 0) { + print_debug(">> Malformed hash."); + printf("\x1b[31m[DEBUG]\x1b[0m >> Calculated : "); + + for(int x = 0; x < 16; x++){ + printf("%02x", hash2[x]); + fflush(0); + } + + printf("\n"); + printf("\x1b[31m[DEBUG]\x1b[0m >> Received : "); + + for(int x = 0; x < 16; x++){ + printf("%02x", cur_hash[x]); + fflush(0); + } + + printf("\n"); + + pos += tlv_len + 2; + break; + } + + + /* if (DEBUG_LEVEL > 0) { - if (cur_tlv.node_state->data == NULL) { + if (cur_message == NULL) { print_error("The data in the current node is NULL !"); return -1; } - printf("\x1b[31m[DEBUG]\x1b[0m >> “%ls\0”\n", (const wchar_t*) cur_tlv.node_state->data); + printf("\x1b[31m[DEBUG]\x1b[0m >> “%ls\0”\n", (const wchar_t*) cur_message); sleep(1); } + */ // Compare hashes - pdata = get_data(be64toh(cur_tlv.node_state->node_id)); + pdata = get_data(be64toh(*id)); // If data is found for this id then we check that both hashes are the same if(pdata != NULL) { + print_debug(">> Comparing hashes..."); // We hash the data stored in the data list memset(hash, 0, 16); hash_data(pdata, hash); // If both hashes are the same then nothing has to be done - if(memcmp(hash, cur_tlv.node_state->node_hash, 16) == 0) { + if(memcmp(hash, cur_hash, 16) == 0) { // The position is updated - tlv_len = data[pos+1]; pos += tlv_len + 2; break; @@ -1034,12 +1137,11 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 * } // Else, we update the data - int rc = add_data(cur_tlv.node_state->length - 26, be64toh(cur_tlv.node_state->node_id), be16toh(cur_tlv.node_state->seqno), cur_tlv.node_state->data, pdata); + int rc = add_data(tlv_len - 26, be64toh(*id), be16toh(*seqno), (unsigned char*) cur_message, pdata); if (rc < 0) { print_error("Error while adding node state !"); } // The position is updated - tlv_len = data[pos+1]; pos += tlv_len + 2; break; @@ -1048,12 +1150,14 @@ int work_with_tlvs(char * data, uint16_t total_packet_len, struct sockaddr_in6 * // We received a warning tlv so it's message is printed cur_tlv.warning = (warning*) (data + pos); + tlv_len = data[pos+1]; + cur_message = data + pos + 2; + // Print exactly new_tlv.length characters from new_tlv.message - sprintf(warn, ">> WARNING:\n%%.%ds", cur_tlv.warning->length + 1); - printf(warn, cur_tlv.warning->message); + sprintf(warn, ">> WARNING:\n%%.%ds", tlv_len + 1); + printf(warn, cur_message); // The position is updated - tlv_len = data[pos+1]; pos += tlv_len + 2; break;