Explorar el Código

fixed seg faults and missing data due to 1) not looking for GET requests in the same packet as the Client Finished message, and 2) freeing streams in two different places

cecylia hace 8 años
padre
commit
f3066d02cf
Se han modificado 5 ficheros con 63 adiciones y 39 borrados
  1. 1 1
      server/crypto.c
  2. 21 23
      server/flow.c
  3. 25 14
      server/relay.c
  4. 15 1
      server/slitheen-proxy.c
  5. 1 0
      server/slitheen.h

+ 1 - 1
server/crypto.c

@@ -396,7 +396,7 @@ int verify_finish_hash(flow *f, uint8_t *p, int32_t incoming){
 
 
 	//now compare
 	//now compare
 	if(CRYPTO_memcmp(p, output, fin_length) != 0){
 	if(CRYPTO_memcmp(p, output, fin_length) != 0){
-	//	printf("VERIFY FAILED\n");
+		printf("VERIFY FAILED\n");
 		free(output);
 		free(output);
 		EVP_MD_CTX_cleanup(&ctx);
 		EVP_MD_CTX_cleanup(&ctx);
 		return 1;
 		return 1;

+ 21 - 23
server/flow.c

@@ -221,7 +221,7 @@ int update_flow(flow *f, uint8_t *record, uint8_t incoming) {
 					update_finish_hash(f, p);
 					update_finish_hash(f, p);
 					break;
 					break;
 				case TLS_FINISHED:
 				case TLS_FINISHED:
-					printf("Received finished (%x:%d -> %x:%d)\n", f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
+					printf("Received finished (%d) (%x:%d -> %x:%d)\n", incoming, f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
 					verify_finish_hash(f,p, incoming);
 					verify_finish_hash(f,p, incoming);
 					update_finish_hash(f, p);
 					update_finish_hash(f, p);
 					if((f->in_encrypted == 2) && (f->out_encrypted == 2)){
 					if((f->in_encrypted == 2) && (f->out_encrypted == 2)){
@@ -235,7 +235,7 @@ int update_flow(flow *f, uint8_t *record, uint8_t incoming) {
 			}
 			}
 			break;
 			break;
 		case APP:
 		case APP:
-			printf("Application Data\n");
+			printf("Application Data (%x:%d -> %x:%d)...\n", f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
 			break;
 			break;
 		case CCS:
 		case CCS:
 			printf("CCS (%x:%d -> %x:%d) \n", f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
 			printf("CCS (%x:%d -> %x:%d) \n", f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
@@ -328,6 +328,7 @@ int remove_flow(flow *f) {
 			tmp = f->ds_packet_chain->first_packet;
 			tmp = f->ds_packet_chain->first_packet;
 		}
 		}
 	}
 	}
+	free(f->ds_packet_chain);
 
 
 	if(f->us_packet_chain != NULL){
 	if(f->us_packet_chain != NULL){
 		packet *tmp = f->us_packet_chain->first_packet;
 		packet *tmp = f->us_packet_chain->first_packet;
@@ -340,6 +341,7 @@ int remove_flow(flow *f) {
 			tmp = f->us_packet_chain->first_packet;
 			tmp = f->us_packet_chain->first_packet;
 		}
 		}
 	}
 	}
+	free(f->us_packet_chain);
 		
 		
 	if(f->upstream_queue != NULL){
 	if(f->upstream_queue != NULL){
 		queue_block *tmp = f->upstream_queue;
 		queue_block *tmp = f->upstream_queue;
@@ -765,12 +767,10 @@ int add_packet(flow *f, struct packet_info *info){
 	}
 	}
 
 
 	packet *new_packet = calloc(1, sizeof(packet));
 	packet *new_packet = calloc(1, sizeof(packet));
-	printf("Allocated new packet %p\n", new_packet);
 	new_packet->seq_num = ntohl(info->tcp_hdr->sequence_num);
 	new_packet->seq_num = ntohl(info->tcp_hdr->sequence_num);
 	new_packet->len = info->app_data_len;
 	new_packet->len = info->app_data_len;
 
 
 	uint8_t *packet_data = calloc(1, new_packet->len);
 	uint8_t *packet_data = calloc(1, new_packet->len);
-	printf("Allocated new packet data %p\n", packet_data);
 	memcpy(packet_data, info->app_data, new_packet->len);
 	memcpy(packet_data, info->app_data, new_packet->len);
 
 
 	new_packet->data = packet_data;
 	new_packet->data = packet_data;
@@ -781,7 +781,7 @@ int add_packet(flow *f, struct packet_info *info){
 
 
 	if(new_packet->seq_num < chain->expected_seq_num){
 	if(new_packet->seq_num < chain->expected_seq_num){
 		//see if this packet contains any data we are missing
 		//see if this packet contains any data we are missing
-		printf("Received repeat packet (expected %d, received %d\n", chain->expected_seq_num, new_packet->seq_num);
+		printf("Received replayed packet O.o\n");
 		free(new_packet->data);
 		free(new_packet->data);
 		free(new_packet);
 		free(new_packet);
 
 
@@ -797,7 +797,6 @@ int add_packet(flow *f, struct packet_info *info){
 
 
 		//place packet after current
 		//place packet after current
 		if(previous == NULL){
 		if(previous == NULL){
-			printf("Packet goes to beginning of chain\n");
 			//goes at the beginning of chain
 			//goes at the beginning of chain
 			new_packet->next = chain->first_packet;
 			new_packet->next = chain->first_packet;
 			chain->first_packet = new_packet;
 			chain->first_packet = new_packet;
@@ -807,21 +806,14 @@ int add_packet(flow *f, struct packet_info *info){
 				const struct record_header *record_hdr = (struct record_header *) new_packet->data;
 				const struct record_header *record_hdr = (struct record_header *) new_packet->data;
 				chain->record_len = RECORD_LEN(record_hdr)+RECORD_HEADER_LEN;
 				chain->record_len = RECORD_LEN(record_hdr)+RECORD_HEADER_LEN;
 				chain->remaining_record_len = chain->record_len;
 				chain->remaining_record_len = chain->record_len;
-				fprintf(stdout, "New Record:\n");
-				for(int i=0; i< RECORD_HEADER_LEN; i++){
-					printf("%02x ", ((uint8_t *) record_hdr)[i]);
-				}
-				printf("\n");
 			}
 			}
 			
 			
 		} else {
 		} else {
-			printf("Appended packet to chain\n");
 			new_packet->next = next;
 			new_packet->next = next;
 			previous->next = new_packet;
 			previous->next = new_packet;
 		}
 		}
 
 
 		if(new_packet->seq_num == chain->expected_seq_num){
 		if(new_packet->seq_num == chain->expected_seq_num){
-			printf("Received expected packet (expected %u)\n", chain->expected_seq_num);
 			chain->expected_seq_num += new_packet->len;
 			chain->expected_seq_num += new_packet->len;
 
 
 			//while there is still data left:
 			//while there is still data left:
@@ -830,9 +822,9 @@ int add_packet(flow *f, struct packet_info *info){
 
 
 				//if full record, give to update_flow
 				//if full record, give to update_flow
 				if(chain->remaining_record_len <= new_packet->len){
 				if(chain->remaining_record_len <= new_packet->len){
-					printf("Completed remaining record!\n");
 					chain->remaining_record_len = 0;
 					chain->remaining_record_len = 0;
 					uint8_t *record = calloc(1, chain->record_len);
 					uint8_t *record = calloc(1, chain->record_len);
+					uint32_t record_len = chain->record_len;
 					uint32_t tmp_len = chain->record_len;
 					uint32_t tmp_len = chain->record_len;
 					packet *next = chain->first_packet;
 					packet *next = chain->first_packet;
 					while(tmp_len > 0){
 					while(tmp_len > 0){
@@ -844,7 +836,6 @@ int add_packet(flow *f, struct packet_info *info){
 							free(next->data);
 							free(next->data);
 							free(next);
 							free(next);
 							next = chain->first_packet;
 							next = chain->first_packet;
-							printf("used up packet\n");
 							available_data = 0;
 							available_data = 0;
 						} else {
 						} else {
 							memcpy(record+chain->record_len - tmp_len, next->data, tmp_len);
 							memcpy(record+chain->record_len - tmp_len, next->data, tmp_len);
@@ -852,23 +843,30 @@ int add_packet(flow *f, struct packet_info *info){
 							next->len -= tmp_len;
 							next->len -= tmp_len;
 							available_data -= tmp_len;
 							available_data -= tmp_len;
 							tmp_len = 0;
 							tmp_len = 0;
-							printf("There are %d bytes of packet remaining\n", next->len);
 							//this is going to be a new record
 							//this is going to be a new record
 							const struct record_header *record_hdr = (struct record_header *) next->data;
 							const struct record_header *record_hdr = (struct record_header *) next->data;
 							chain->record_len = RECORD_LEN(record_hdr)+RECORD_HEADER_LEN;
 							chain->record_len = RECORD_LEN(record_hdr)+RECORD_HEADER_LEN;
 							chain->remaining_record_len = chain->record_len;
 							chain->remaining_record_len = chain->record_len;
-							fprintf(stdout, "New Record:\n");
-							for(int i=0; i< RECORD_HEADER_LEN; i++){
-								printf("%02x ", ((uint8_t *) record_hdr)[i]);
-							}
-							printf("\n");
+							printf("Found record of type %d\n", record_hdr->type);
+							fflush(stdout);
 
 
 						}
 						}
 					}
 					}
-					update_flow(f, record, incoming);
+					//if handshake is complete, send to relay code
+					if(f->application == 1){
+						//update packet info and send to replace_packet
+						printf("Packet contains application data!\n");
+						struct packet_info *copy_info = copy_packet_info(info);
+						copy_info->app_data = record;
+						copy_info->app_data_len = record_len;
+						replace_packet(f, copy_info);
+						free(copy_info->app_data);
+						free(copy_info);
+					} else {
+						update_flow(f, record, incoming);
+					}
 				} else {
 				} else {
 					chain->remaining_record_len -= new_packet->len;
 					chain->remaining_record_len -= new_packet->len;
-					printf("Still have %d bytes remaining in record\n", chain->remaining_record_len);
 					//see if this packet filled a hole
 					//see if this packet filled a hole
 					new_packet = new_packet->next;
 					new_packet = new_packet->next;
 					if(new_packet != NULL &&
 					if(new_packet != NULL &&

+ 25 - 14
server/relay.c

@@ -374,13 +374,11 @@ int read_header(flow *f, struct packet_info *info){
 			//If a thread for this stream id exists, get the thread info and pipe data
 			//If a thread for this stream id exists, get the thread info and pipe data
 			int32_t stream_pipe = -1;
 			int32_t stream_pipe = -1;
 			stream *last = streams->first;
 			stream *last = streams->first;
-			stream *prev = last;
 			if(streams->first != NULL){
 			if(streams->first != NULL){
 				if(last->stream_id == stream_id){
 				if(last->stream_id == stream_id){
 					stream_pipe = last->pipefd;
 					stream_pipe = last->pipefd;
 				} else {
 				} else {
 					while(last->next != NULL){
 					while(last->next != NULL){
-						prev = last;
 						last = last->next;
 						last = last->next;
 						if(last->stream_id == stream_id){
 						if(last->stream_id == stream_id){
 							stream_pipe = last->pipefd;
 							stream_pipe = last->pipefd;
@@ -392,19 +390,28 @@ int read_header(flow *f, struct packet_info *info){
 
 
 			if(stream_pipe != -1){
 			if(stream_pipe != -1){
 				//check to see if this is a close message
 				//check to see if this is a close message
-				if(stream_len == 0){
-					close(stream_pipe);
+				//if(stream_len == 0){
+					//close(stream_pipe);
 					//remove from stream id table
 					//remove from stream id table
-					if(last == streams->first){
-						streams->first = last->next;
-					} else {
-						prev->next = last->next;
-					}
-					free(last);
+					//if(last == streams->first){
+					//	streams->first = last->next;
+					//} else {
+					//	prev->next = last->next;
+					//}
+					//printf("Freed (1) %p\n", last);
+					//fflush(stdout);
+					//free(last);
+					//break;
+				//}
+				if(stream_len ==0){
+					close(stream_pipe);
 					break;
 					break;
 				}
 				}
 				printf("Found stream id %d\n", last->stream_id);
 				printf("Found stream id %d\n", last->stream_id);
 				int32_t bytes_sent = write(stream_pipe, p, stream_len);
 				int32_t bytes_sent = write(stream_pipe, p, stream_len);
+				if(bytes_sent < 0){
+					printf("Error sending bytes to stream pipe\n");
+				}
 
 
 			} else if(stream_len > 0){
 			} else if(stream_len > 0){
 
 
@@ -563,7 +570,9 @@ void *proxy_covert_site(void *data){
     }
     }
 
 
 	getsockname(handle, (struct sockaddr *) &my_addr, &my_addr_len);
 	getsockname(handle, (struct sockaddr *) &my_addr, &my_addr_len);
+	printf("Bound to %x:%d\n", my_addr.sin_addr.s_addr, ntohs(my_addr.sin_port));
 
 
+#ifdef OLD
 	uint8_t *response = calloc(1, 11);
 	uint8_t *response = calloc(1, 11);
 	//now send the reply to the client
 	//now send the reply to the client
 	response[0] = 0x05;
 	response[0] = 0x05;
@@ -573,17 +582,13 @@ void *proxy_covert_site(void *data){
 	*((uint32_t *) (response + 4)) = my_addr.sin_addr.s_addr;
 	*((uint32_t *) (response + 4)) = my_addr.sin_addr.s_addr;
 	*((uint16_t *) (response + 8)) = my_addr.sin_port;
 	*((uint16_t *) (response + 8)) = my_addr.sin_port;
 
 
-#ifdef DEBUG
-	printf("Bound to %x:%d\n", my_addr.sin_addr.s_addr, ntohs(my_addr.sin_port));
 	printf("Downstream response (id %d):\n", stream_id);
 	printf("Downstream response (id %d):\n", stream_id);
 	for(int i=0; i< 10; i++){
 	for(int i=0; i< 10; i++){
 		printf("%02x ", response[i]);
 		printf("%02x ", response[i]);
 	}
 	}
 	printf("\n");
 	printf("\n");
 	fflush(stdout);
 	fflush(stdout);
-#endif
 
 
-#ifdef OLD
 	//No longer need to send response
 	//No longer need to send response
 	queue_block *new_block = calloc(1, sizeof(queue_block));
 	queue_block *new_block = calloc(1, sizeof(queue_block));
 	new_block->len = 10;
 	new_block->len = 10;
@@ -663,6 +668,7 @@ void *proxy_covert_site(void *data){
 					break;
 					break;
 				}
 				}
 			} else {
 			} else {
+				printf("PROXY (id %d): read %d bytes from pipe\n", stream_id, bytes_read);
 				break;
 				break;
 			}
 			}
 
 
@@ -700,12 +706,15 @@ void *proxy_covert_site(void *data){
 					last->next = new_block;
 					last->next = new_block;
 				}
 				}
 			} else {
 			} else {
+				printf("PROXY (id %d): read %d bytes from censored site\n",stream_id, bytes_read);
 				
 				
 				break;
 				break;
 			}
 			}
 
 
 		}
 		}
 	}
 	}
+
+	printf("Closing connection for stream %d\n", stream_id);
 	//remove self from list 
 	//remove self from list 
 	stream *last = streams->first;
 	stream *last = streams->first;
 	stream *prev = last;
 	stream *prev = last;
@@ -733,6 +742,7 @@ void *proxy_covert_site(void *data){
 	free(thread_data);
 	free(thread_data);
 	free(buffer);
 	free(buffer);
 	close(handle);
 	close(handle);
+	pthread_detach(pthread_self());
 	pthread_exit(NULL);
 	pthread_exit(NULL);
 	return 0;
 	return 0;
 err:
 err:
@@ -762,6 +772,7 @@ err:
 	if(handle > 0){
 	if(handle > 0){
 		close(handle);
 		close(handle);
 	}
 	}
+	pthread_detach(pthread_self());
 	pthread_exit(NULL);
 	pthread_exit(NULL);
 	return 0;
 	return 0;
 }
 }

+ 15 - 1
server/slitheen-proxy.c

@@ -177,7 +177,6 @@ void process_packet(struct packet_info *info){
 
 
 			/* Pass data to packet chain */
 			/* Pass data to packet chain */
 			add_packet(observed, info);
 			add_packet(observed, info);
-
 		}
 		}
 
 
 		/* Update TCP state */
 		/* Update TCP state */
@@ -247,3 +246,18 @@ void extract_packet_headers(uint8_t *packet, struct packet_info *info){
 	return;
 	return;
 
 
 }
 }
+
+struct packet_info *copy_packet_info(struct packet_info *src_info){
+	struct packet_info *dst_info = calloc(1, sizeof(struct packet_info));
+
+	dst_info->ip_hdr = src_info->ip_hdr;
+	dst_info->tcp_hdr = src_info->tcp_hdr;
+
+	dst_info->size_tcp_hdr = src_info->size_tcp_hdr;
+	dst_info->size_ip_hdr = src_info->size_ip_hdr;
+
+	dst_info->app_data = src_info->app_data;
+	dst_info->app_data_len = src_info->app_data_len;
+
+	return dst_info;
+}

+ 1 - 0
server/slitheen.h

@@ -108,5 +108,6 @@ void got_packet(uint8_t *args, const struct pcap_pkthdr *header, const uint8_t *
 void *sniff_packets(void *);
 void *sniff_packets(void *);
 void process_packet(struct packet_info *info);
 void process_packet(struct packet_info *info);
 void extract_packet_headers(uint8_t *packet, struct packet_info *info);
 void extract_packet_headers(uint8_t *packet, struct packet_info *info);
+struct packet_info *copy_packet_info(struct packet_info *src_info);
 
 
 #endif /* _SLITHEEN_H_ */
 #endif /* _SLITHEEN_H_ */