Selaa lähdekoodia

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 8 vuotta sitten
vanhempi
commit
f3066d02cf
5 muutettua tiedostoa jossa 63 lisäystä ja 39 poistoa
  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
 	if(CRYPTO_memcmp(p, output, fin_length) != 0){
-	//	printf("VERIFY FAILED\n");
+		printf("VERIFY FAILED\n");
 		free(output);
 		EVP_MD_CTX_cleanup(&ctx);
 		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);
 					break;
 				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);
 					update_finish_hash(f, p);
 					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;
 		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;
 		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));
@@ -328,6 +328,7 @@ int remove_flow(flow *f) {
 			tmp = f->ds_packet_chain->first_packet;
 		}
 	}
+	free(f->ds_packet_chain);
 
 	if(f->us_packet_chain != NULL){
 		packet *tmp = f->us_packet_chain->first_packet;
@@ -340,6 +341,7 @@ int remove_flow(flow *f) {
 			tmp = f->us_packet_chain->first_packet;
 		}
 	}
+	free(f->us_packet_chain);
 		
 	if(f->upstream_queue != NULL){
 		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));
-	printf("Allocated new packet %p\n", new_packet);
 	new_packet->seq_num = ntohl(info->tcp_hdr->sequence_num);
 	new_packet->len = info->app_data_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);
 
 	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){
 		//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);
 
@@ -797,7 +797,6 @@ int add_packet(flow *f, struct packet_info *info){
 
 		//place packet after current
 		if(previous == NULL){
-			printf("Packet goes to beginning of chain\n");
 			//goes at the beginning of chain
 			new_packet->next = chain->first_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;
 				chain->record_len = RECORD_LEN(record_hdr)+RECORD_HEADER_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 {
-			printf("Appended packet to chain\n");
 			new_packet->next = next;
 			previous->next = new_packet;
 		}
 
 		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;
 
 			//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(chain->remaining_record_len <= new_packet->len){
-					printf("Completed remaining record!\n");
 					chain->remaining_record_len = 0;
 					uint8_t *record = calloc(1, chain->record_len);
+					uint32_t record_len = chain->record_len;
 					uint32_t tmp_len = chain->record_len;
 					packet *next = chain->first_packet;
 					while(tmp_len > 0){
@@ -844,7 +836,6 @@ int add_packet(flow *f, struct packet_info *info){
 							free(next->data);
 							free(next);
 							next = chain->first_packet;
-							printf("used up packet\n");
 							available_data = 0;
 						} else {
 							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;
 							available_data -= tmp_len;
 							tmp_len = 0;
-							printf("There are %d bytes of packet remaining\n", next->len);
 							//this is going to be a new record
 							const struct record_header *record_hdr = (struct record_header *) next->data;
 							chain->record_len = RECORD_LEN(record_hdr)+RECORD_HEADER_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 {
 					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
 					new_packet = new_packet->next;
 					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
 			int32_t stream_pipe = -1;
 			stream *last = streams->first;
-			stream *prev = last;
 			if(streams->first != NULL){
 				if(last->stream_id == stream_id){
 					stream_pipe = last->pipefd;
 				} else {
 					while(last->next != NULL){
-						prev = last;
 						last = last->next;
 						if(last->stream_id == stream_id){
 							stream_pipe = last->pipefd;
@@ -392,19 +390,28 @@ int read_header(flow *f, struct packet_info *info){
 
 			if(stream_pipe != -1){
 				//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
-					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;
 				}
 				printf("Found stream id %d\n", last->stream_id);
 				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){
 
@@ -563,7 +570,9 @@ void *proxy_covert_site(void *data){
     }
 
 	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);
 	//now send the reply to the client
 	response[0] = 0x05;
@@ -573,17 +582,13 @@ void *proxy_covert_site(void *data){
 	*((uint32_t *) (response + 4)) = my_addr.sin_addr.s_addr;
 	*((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);
 	for(int i=0; i< 10; i++){
 		printf("%02x ", response[i]);
 	}
 	printf("\n");
 	fflush(stdout);
-#endif
 
-#ifdef OLD
 	//No longer need to send response
 	queue_block *new_block = calloc(1, sizeof(queue_block));
 	new_block->len = 10;
@@ -663,6 +668,7 @@ void *proxy_covert_site(void *data){
 					break;
 				}
 			} else {
+				printf("PROXY (id %d): read %d bytes from pipe\n", stream_id, bytes_read);
 				break;
 			}
 
@@ -700,12 +706,15 @@ void *proxy_covert_site(void *data){
 					last->next = new_block;
 				}
 			} else {
+				printf("PROXY (id %d): read %d bytes from censored site\n",stream_id, bytes_read);
 				
 				break;
 			}
 
 		}
 	}
+
+	printf("Closing connection for stream %d\n", stream_id);
 	//remove self from list 
 	stream *last = streams->first;
 	stream *prev = last;
@@ -733,6 +742,7 @@ void *proxy_covert_site(void *data){
 	free(thread_data);
 	free(buffer);
 	close(handle);
+	pthread_detach(pthread_self());
 	pthread_exit(NULL);
 	return 0;
 err:
@@ -762,6 +772,7 @@ err:
 	if(handle > 0){
 		close(handle);
 	}
+	pthread_detach(pthread_self());
 	pthread_exit(NULL);
 	return 0;
 }

+ 15 - 1
server/slitheen-proxy.c

@@ -177,7 +177,6 @@ void process_packet(struct packet_info *info){
 
 			/* Pass data to packet chain */
 			add_packet(observed, info);
-
 		}
 
 		/* Update TCP state */
@@ -247,3 +246,18 @@ void extract_packet_headers(uint8_t *packet, struct packet_info *info){
 	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 process_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_ */