Browse Source

fixed memory leaks

cecylia 6 years ago
parent
commit
9a923cea12
6 changed files with 63 additions and 15 deletions
  1. 1 1
      client/Makefile
  2. 4 5
      client/crypto.c
  3. 1 1
      relay_station/Makefile
  4. 11 4
      relay_station/crypto.c
  5. 21 0
      relay_station/flow.c
  6. 25 4
      relay_station/relay.c

+ 1 - 1
client/Makefile

@@ -1,4 +1,4 @@
-CFLAGS=-g -Wall -ggdb
+CFLAGS=-g -Wall -ggdb -DDEBUG -DDEBUG_UPSTREAM
 
 TARGETS= socks
 

+ 4 - 5
client/crypto.c

@@ -227,7 +227,7 @@ int peek_header(uint8_t *data){
 	int retval = 1;
 
 	//decrypt header
-#ifdef DEBUG
+#ifdef DEBUG_PEEK
 	int i;
 	printf("Encrypted header:\n");
 	for(i=0; i< SLITHEEN_HEADER_LEN; i++){
@@ -241,7 +241,6 @@ int peek_header(uint8_t *data){
     EVP_CipherInit_ex(hdr_ctx, EVP_aes_256_ecb(), NULL, super->header_key, NULL, 0);
 
 	if(!EVP_CipherUpdate(hdr_ctx, p, &out_len, p, SLITHEEN_HEADER_LEN)){
-		printf("Decryption failed!\n");
 		retval =  0;
 		goto end;
 	}
@@ -320,14 +319,14 @@ int super_decrypt(uint8_t *data){
 	}
 
 
-//#ifdef DEBUG_PARSE
+#ifdef DEBUG
 	printf("Decrypted header (%d bytes):\n", SLITHEEN_HEADER_LEN);
 	for(i=0; i< SLITHEEN_HEADER_LEN; i++){
 		printf("%02x ", p[i]);
 	}
 	printf("\n");
 	fflush(stdout);
-//#endif
+#endif
 	
 	p += SLITHEEN_HEADER_LEN;
 
@@ -396,7 +395,7 @@ int super_decrypt(uint8_t *data){
 		goto end;
 	}
 
-#ifdef DEBUG_PARSE
+#ifdef DEBUG
 	printf("Decrypted data (%d bytes):\n", out_len);
 	for(i=0; i< out_len; i++){
 		printf("%02x ", p[i]);

+ 1 - 1
relay_station/Makefile

@@ -1,4 +1,4 @@
-CFLAGS=-g -ggdb -Wall -std=gnu99 -DDEBUG_DOWN -DDEBUG_PROXY -DRESOURCE_DEBUG
+CFLAGS=-g -ggdb -Wall -std=gnu99 #-DDEBUG_DOWN -DDEBUG_PROXY -DRESOURCE_DEBUG -DDEBUG_HS
 
 TARGETS=slitheen-proxy
 

+ 11 - 4
relay_station/crypto.c

@@ -645,6 +645,11 @@ int compute_master_secret(flow *f){
 		ctx = BN_CTX_new();
 
 		dh_srvr = f->dh;
+
+                if(dh_srvr == NULL){
+                    goto err;
+                }
+
 		dh_clnt = DHparams_dup(dh_srvr);
 
 #if OPENSSL_VERSION_NUMBER >= 0x1010000eL
@@ -705,7 +710,7 @@ int compute_master_secret(flow *f){
 
 #if OPENSSL_VERSION_NUMBER >= 0x1010000eL
                 if(!DH_set0_key(dh_clnt, pub_key, priv_key)){
-                    return 1;
+                    goto err;
                 }
                 const BIGNUM *srvr_pub, *srvr_priv;
                 DH_get0_key(dh_srvr, &srvr_pub, &srvr_priv);
@@ -769,14 +774,14 @@ int compute_master_secret(flow *f){
 #endif
 		tkey = f->ecdh;
 		if(tkey == NULL){
-			return 1;
+                    goto err;
 		}
 
 		srvr_group = EC_KEY_get0_group(tkey);
 		srvr_ecpoint = EC_KEY_get0_public_key(tkey);
 
 		if((srvr_group == NULL) || (srvr_ecpoint == NULL)) {
-			return 1;
+                    goto err;
 		}
 
 		if((clnt_ecdh = EC_KEY_new()) == NULL) {
@@ -1614,10 +1619,12 @@ void check_handshake(struct packet_info *info){
 		fclose(fp);
 
 		/* check tag*/ 
+                /*TODO: change back!
                 uint8_t context[4 + SSL3_RANDOM_SIZE - PTWIST_TAG_BYTES];
                 memcpy(context, &info->ip_hdr->dst.s_addr, 4);
                 memcpy(context + 4, hello_rand, SSL3_RANDOM_SIZE - PTWIST_TAG_BYTES);
-		res = check_tag(key, privkey, p, (const byte *)context, sizeof(context));
+		res = check_tag(key, privkey, p, (const byte *)context, sizeof(context));*/
+		res = check_tag(key, privkey, p, (const byte *)"context", 7);//TODO: delete
 		if (!res) {
 
 #ifdef DEBUG_HS

+ 21 - 0
relay_station/flow.c

@@ -135,6 +135,7 @@ flow *add_flow(struct packet_info *info) {
 	new_flow->partial_record_header = NULL;
 	new_flow->partial_record_header_len = 0;
 	new_flow->partial_record = NULL;
+	new_flow->partial_record_dec = NULL;
 	new_flow->partial_record_len = 0;
 	new_flow->partial_record_total_len = 0;
 	new_flow->remaining_record_len = 0;
@@ -576,6 +577,14 @@ int remove_flow(flow *f) {
         free(f->partial_record_header);
     }
 
+    if(f->partial_record_dec != NULL){
+        free(f->partial_record_dec);
+    }
+
+    if(f->partial_record != NULL){
+        free(f->partial_record);
+    }
+
 	//Clean up cipher ctxs
 #if OPENSSL_VERSION_NUMBER >= 0x1010000eL
 	EVP_MD_CTX_free(f->hs_md_ctx);
@@ -606,6 +615,18 @@ int remove_flow(flow *f) {
 		EC_KEY_free(f->ecdh);
 	}
 
+        if(f->gcm_ctx_out != NULL){
+           CRYPTO_gcm128_release(f->gcm_ctx_out);
+        }
+
+        if(f->gcm_ctx_iv != NULL){
+            free(f->gcm_ctx_iv);
+        }
+
+        if(f->gcm_ctx_key != NULL){
+            free(f->gcm_ctx_key);
+        }
+
     if(f->dh != NULL){
         DH_free(f->dh);
     }

+ 25 - 4
relay_station/relay.c

@@ -991,6 +991,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
 
                         f->partial_record_total_len = 0;
                         f->partial_record_len = 0;
+                        free(record_ptr);
                         return 0; //TODO: goto err or return correctly
                     }
 
@@ -1005,6 +1006,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
                             f->partial_record_header_len = 0;
                             free(f->partial_record_header);
                         }
+                        free(record_ptr);
                         return 0;//TODO: goto err to free record_ptr
                     }
 
@@ -1015,7 +1017,11 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
                 //now update pointer to past where we've already parsed
                 if(partial_offset){
                     p += partial_offset;
-                    remaining_record_len = n + EVP_GCM_TLS_EXPLICIT_IV_LEN - partial_offset;
+                    if(n + EVP_GCM_TLS_EXPLICIT_IV_LEN >= partial_offset){
+                        remaining_record_len = n + EVP_GCM_TLS_EXPLICIT_IV_LEN - partial_offset;
+                    } else {//only received last part of tag
+                        remaining_record_len = 0;
+                    }
                 } else {
                     p += EVP_GCM_TLS_EXPLICIT_IV_LEN;
                     remaining_record_len = n;
@@ -1032,6 +1038,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
                             f->partial_record_header_len = 0;
                             free(f->partial_record_header);
                         }
+                        free(record_ptr);
                         return 0;//TODO goto an err to free record_ptr
                     }
 
@@ -1062,6 +1069,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
 
 #ifdef RESOURCE_DEBUG
                 printf("Current state (flow %p): %x\n", f, f->httpstate);
+                printf("Remaining record len: %d\n", remaining_record_len);
 #endif
 
 			switch(f->httpstate){
@@ -1118,7 +1126,9 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
 
 					len_ptr = strstr((const char *) p, "Transfer-Encoding");
 					if(len_ptr != NULL){
+                                            printf("Transfer encoding\n");
 						if(!memcmp(len_ptr + 19, "chunked", 7)){
+                                            printf("Chunked\n");
 							//now find end of header
 							
 							len_ptr = strstr((const char *) p, "\r\n\r\n");
@@ -1126,8 +1136,13 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
 								f->httpstate = BEGIN_CHUNK;
 								remaining_record_len -= (((uint8_t *)len_ptr - p) + 4);
 								p = (uint8_t *) len_ptr + 4;
-							}
-						}
+							} else {
+                                                            printf("Couldn't find end of header\n");
+                                                            f->httpstate = FORFEIT_REST;
+                                                        }
+						} else {// other encodings not yet implemented
+                                                    f->httpstate = FORFEIT_REST;
+                                                }
 					} else {
 						len_ptr = strstr((const char *) p, "Content-Length");
 						if(len_ptr != NULL){
@@ -1321,11 +1336,14 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
                     //partially encrypting data
 
                     //first copy plaintext to flow struct
-                    memcpy(f->partial_record_dec + partial_offset, record_ptr+partial_offset, n + EVP_GCM_TLS_EXPLICIT_IV_LEN - partial_offset);
+                    if(n + EVP_GCM_TLS_EXPLICIT_IV_LEN >= partial_offset){
+                        memcpy(f->partial_record_dec + partial_offset, record_ptr+partial_offset, n + EVP_GCM_TLS_EXPLICIT_IV_LEN - partial_offset);
+                    } //otherwise, this packet contains only part of the tag
 
                     n = partial_aes_gcm_tls_cipher(f, record_ptr, record_ptr, n+ EVP_GCM_TLS_EXPLICIT_IV_LEN, 1);
                     if(n < 0){
                         printf("Partial decryption failed!\n");
+                        free(record_ptr);
                         return 0;
                     }
 #ifdef DEBUG_DOWN
@@ -1382,6 +1400,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
                                     f->partial_record_header_len = 0;
                                     free(f->partial_record_header);
                             }
+                            free(record_ptr);
                             return 0;
                     }
                     p = record_ptr;
@@ -1409,6 +1428,8 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
 			free(f->partial_record_header);
 		}
 
+                free(record_ptr);//free temporary record
+
 	}
 
 	if(changed){