Bladeren bron

implemented Tor trick of pre-emptively approving SOCKS connect

cecylia 8 jaren geleden
bovenliggende
commit
b68313ff89
7 gewijzigde bestanden met toevoegingen van 315 en 151 verwijderingen
  1. 215 59
      client/socks5proxy.c
  2. 3 26
      server/crypto.c
  3. 1 1
      server/crypto.h
  4. 58 47
      server/flow.c
  5. 2 2
      server/flow.h
  6. 34 5
      server/relay.c
  7. 2 11
      server/slitheen-proxy.c

+ 215 - 59
client/socks5proxy.c

@@ -21,6 +21,8 @@
 #include <openssl/evp.h>
 #include<openssl/buffer.h>
 
+#define NEW
+
 int proxy_data(int sockfd, uint8_t stream_id, int32_t pipefd);
 void *demultiplex_data();
 
@@ -30,6 +32,8 @@ struct __attribute__ ((__packed__)) slitheen_hdr{
 	uint16_t garbage_len;
 };
 
+#define SLITHEEN_HEADER_LEN 5
+
 struct __attribute__ ((__packed__)) slitheen_up_hdr{
 	uint8_t stream_id;
 	uint16_t len;
@@ -54,7 +58,6 @@ int main(void){
 	struct sockaddr_in remote_addr;
 	socklen_t addr_size;
 
-	//mkfifo("OUS_in", 0666);
 	mkfifo("OUS_out", 0666);
 
 	/* Spawn process to listen for incoming data from OUS 
@@ -79,6 +82,12 @@ int main(void){
 	address.sin_addr.s_addr = INADDR_ANY;
 	address.sin_port = htons(1080);
 
+	int enable = 1;
+	if (setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable)) <0 ){
+		printf("Error setting sockopt\n");
+		return 1;
+	}
+
 	if(bind(listen_socket, (struct sockaddr *) &address, sizeof(address))){
 		printf("Error binding socket\n");
 		fflush(stdout);
@@ -91,7 +100,7 @@ int main(void){
 		close(listen_socket);
 		exit(1);
 	}
-	uint8_t last_id = 0;
+	uint8_t last_id = 1;
 
 	printf("Ready for listening\n");
 
@@ -127,11 +136,9 @@ int main(void){
 		} else {
 			connection *last = connections->first;
 			printf("New incoming connection\n");
-			printf("First connection was at %p\n", last);
 			fflush(stdout);
 			while(last->next != NULL){
 				last = last->next;
-				printf("Next connection was at %p\n", last);
 			}
 			last->next = new_conn;
 			printf("Added connection with id: %d at %p\n", new_conn->stream_id, last->next);
@@ -182,7 +189,8 @@ int proxy_data(int sockfd, uint8_t stream_id, int32_t ous_out){
 	}
 
 	printf("Received %d bytes (id %d):\n", bytes_read, stream_id);
-	for(int i=0; i< bytes_read; i++){
+	int i;
+	for(i=0; i< bytes_read; i++){
 		printf("%02x ", buffer[i]);
 	}
 	printf("\n");
@@ -199,7 +207,7 @@ int proxy_data(int sockfd, uint8_t stream_id, int32_t ous_out){
 
 	int responded = 0;
 	int bytes_sent;
-	for(int i=0; i< clnt_meth->num_methods; i++){
+	for(i=0; i< clnt_meth->num_methods; i++){
 		if(p[0] == 0x00){//send response with METH= 0x00
 			response[0] = 0x05;
 			response[1] = 0x00;
@@ -224,12 +232,38 @@ int proxy_data(int sockfd, uint8_t stream_id, int32_t ous_out){
 	}
 
 	printf("Received %d bytes (id %d):\n", bytes_read, stream_id);
-	for(int i=0; i< bytes_read; i++){
+	for(i=0; i< bytes_read; i++){
 		printf("%02x ", buffer[i]);
 	}
 	printf("\n");
 		fflush(stdout);
 
+	//Now respond
+	response[0] = 0x05;
+	response[1] = 0x00;
+	response[2] = 0x00;
+	response[3] = 0x01;
+
+	*((uint32_t *) (response + 4)) = 0;
+	*((uint16_t *) (response + 8)) = 0;
+
+	send(sockfd, response, 10, 0);
+
+	//wait for first upstream bytes
+	bytes_read += recv(sockfd, buffer+bytes_read, BUFSIZ-bytes_read-3, 0);
+	if (bytes_read < 0){
+		printf("Error reading from socket\n");
+		fflush(stdout);
+		goto err;
+	}
+
+	printf("Received %d bytes (id %d):\n", bytes_read, stream_id);
+	for(i=0; i< bytes_read; i++){
+		printf("%02x ", buffer[i]);
+	}
+	printf("\n");
+	fflush(stdout);
+
 	//pre-pend stream_id and length
 	memmove(buffer+3, buffer, bytes_read+1);
 
@@ -255,7 +289,27 @@ int proxy_data(int sockfd, uint8_t stream_id, int32_t ous_out){
 	BIO_free_all(bio);
 	encoded_bytes = (*buffer_ptr).data;
 
+#ifdef NEW
+	struct sockaddr_in ous_addr;
+	ous_addr.sin_family = AF_INET;
+	inet_pton(AF_INET, "127.0.0.1", &(ous_addr.sin_addr));
+	ous_addr.sin_port = htons(8888);
+
+	int32_t ous_in = socket(AF_INET, SOCK_STREAM, 0);
+	if(ous_in < 0){
+		printf("Failed to make ous_in socket\n");
+		return 1;
+	}
+
+	int32_t error = connect(ous_in, (struct sockaddr *) &ous_addr, sizeof (struct sockaddr));
+	if(error < 0){
+		printf("Error connecting\n");
+		return 1;
+	}
+#endif
+
 	//send connect request to OUS
+#ifdef OLD
 	int ous_in = open("OUS_in", O_CREAT | O_WRONLY, 0666);
 	if(ous_in < 0){
 		printf("Error opening file OUS_in\n");
@@ -264,24 +318,29 @@ int proxy_data(int sockfd, uint8_t stream_id, int32_t ous_out){
 	}
 
 	lseek(ous_in, 0, SEEK_END);
+#endif
+
+#ifdef NEW
+	uint8_t *message = calloc(1, BUFSIZ);
+	sprintf(message, "POST / HTTP/1.1\r\nContent-Length: %d\r\n\r\n%s ", strlen(encoded_bytes)+1, encoded_bytes);
+	bytes_sent = send(ous_in, message, strlen(message), 0);
+	printf("Wrote %d bytes to OUS_in: %s\n", bytes_sent, message);
+#endif
+
+#ifdef OLD
 	bytes_sent = write(ous_in, encoded_bytes, strlen(encoded_bytes));
-	bytes_sent += write(ous_in, " ", 1);//space delimiter
-	close(ous_in);
+	bytes_sent += write(ous_in, " ", 1);
+#endif
 	if(bytes_sent < 0){
-		printf("Error writing to named pipe\n");
+		printf("Error writing to websocket\n");
 		fflush(stdout);
 		goto err;
 	} else {
-		printf("Wrote %d bytes to OUS_in:\n", bytes_sent);
-		for(int i=0; i< bytes_read; i++){
-			printf("%02x ",encoded_bytes[i]);
-		}
-		printf("\n");
-		fflush(stdout);
+		close(ous_in);
 	}
 
 	p = buffer+sizeof(struct slitheen_up_hdr);
-	for(int i=0; i< bytes_read; i++){
+	for(i=0; i< bytes_read; i++){
 		printf("%02x ", p[i]);
 	}
 	printf("\n");
@@ -333,14 +392,56 @@ int proxy_data(int sockfd, uint8_t stream_id, int32_t ous_out){
 		fflush(stdout);
 				goto err;
 			}
+			if(bytes_read == 0){
+				//socket is closed
+				printf("Closing connection for stream %d sockfd.\n", stream_id);
+				fflush(stdout);
+
+				//Send close message to slitheen proxy
+				up_hdr = (struct slitheen_up_hdr *) buffer;
+				up_hdr->stream_id = stream_id;
+				up_hdr->len = 0;
+				bio = BIO_new(BIO_s_mem());
+				b64 = BIO_new(BIO_f_base64());
+				bio = BIO_push(b64, bio);
+
+				BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
+				BIO_write(bio, buffer, 20);
+				BIO_flush(bio);
+				BIO_get_mem_ptr(bio, &buffer_ptr);
+				BIO_set_close(bio, BIO_NOCLOSE);
+				BIO_free_all(bio);
+				encoded_bytes = (*buffer_ptr).data;
+				ous_in = socket(AF_INET, SOCK_STREAM, 0);
+				if(ous_in < 0){
+					printf("Failed to make ous_in socket\n");
+				fflush(stdout);
+					goto err;
+				}
+
+				error = connect(ous_in, (struct sockaddr *) &ous_addr, sizeof (struct sockaddr));
+				if(error < 0){
+					printf("Error connecting\n");
+				fflush(stdout);
+					goto err;
+				}
+
+				sprintf(message, "POST / HTTP/1.1\r\nContent-Length: %d\r\n\r\n%s ", strlen(encoded_bytes)+1, encoded_bytes);
+				bytes_sent = send(ous_in, message, strlen(message), 0);
+				close(ous_in);
+
+				goto err;
+				
+			}
 
 			if(bytes_read > 0){
 
 				printf("Received %d data bytes from sockfd (id %d):\n", bytes_read, stream_id);
-				for(int i=0; i< bytes_read; i++){
+				for(i=0; i< bytes_read; i++){
 					printf("%02x ", buffer[i]);
 				}
 				printf("\n");
+				printf("%s\n", buffer);
 		fflush(stdout);
 				memmove(buffer+sizeof(struct slitheen_up_hdr), buffer, bytes_read);
 
@@ -363,27 +464,49 @@ int proxy_data(int sockfd, uint8_t stream_id, int32_t ous_out){
 				BIO_set_close(bio, BIO_NOCLOSE);
 				BIO_free_all(bio);
 				encoded_bytes = (*buffer_ptr).data;
-
+				
+#ifdef OLD
 				int ous_in = open("OUS_in", O_CREAT | O_WRONLY, 0666);
 				if(ous_in < 0){
 					printf("Error opening file OUS_in\n");
-		fflush(stdout);
+					fflush(stdout);
 					goto err;
 				}
 
 				lseek(ous_in, 0, SEEK_END);
-				bytes_sent = write(ous_in, encoded_bytes, strlen(encoded_bytes));
-				bytes_sent += write(ous_in, " ", 1);//space delimiter
+#endif
+
+#ifdef NEW
+				ous_in = socket(AF_INET, SOCK_STREAM, 0);
+				if(ous_in < 0){
+					printf("Failed to make ous_in socket\n");
+					return 1;
+				}
 
+				error = connect(ous_in, (struct sockaddr *) &ous_addr, sizeof (struct sockaddr));
+				if(error < 0){
+					printf("Error connecting\n");
+					return 1;
+				}
+
+				sprintf(message, "POST / HTTP/1.1\r\nContent-Length: %d\r\n\r\n%s ", strlen(encoded_bytes)+1, encoded_bytes);
+				bytes_sent = send(ous_in, message, strlen(message), 0);
+				printf("Sent to OUS (%d bytes):%s\n",bytes_sent, message);
 				close(ous_in);
-				printf("Sent to OUS (%d bytes):%s\n",bytes_sent, encoded_bytes );
-		fflush(stdout);
 
+#endif
+
+#ifdef OLD
+				bytes_sent = write(ous_in, encoded_bytes, strlen(encoded_bytes));
+				bytes_sent += write(ous_in, " ", 1);
+				printf("Sent to OUS (%d bytes):%s\n",bytes_sent, encoded_bytes);
+				close(ous_in);
+#endif
 			}
 		} else if(FD_ISSET(ous_out, &readfds) && FD_ISSET(sockfd, &writefds)){
 
 			bytes_read = read(ous_out, buffer, BUFSIZ-1);
-			if (bytes_read < 0){
+			if (bytes_read <= 0){
 				printf("Error reading from ous_out (in for loop)\n");
 		fflush(stdout);
 				goto err;
@@ -392,15 +515,20 @@ int proxy_data(int sockfd, uint8_t stream_id, int32_t ous_out){
 			if(bytes_read > 0){
 
 				printf("Stream id %d received %d bytes from ous_out:\n", stream_id, bytes_read);
-				for(int i=0; i< bytes_read; i++){
+				for(i=0; i< bytes_read; i++){
 					printf("%02x ", buffer[i]);
 				}
 				printf("\n");
+				printf("%s\n", buffer);
 		fflush(stdout);
 
 				bytes_sent = send(sockfd, buffer, bytes_read, 0);
-				printf("Sent to browser (%d bytes):\n", bytes_sent);
-				for(int i=0; i< bytes_sent; i++){
+				if(bytes_sent <= 0){
+					printf("Error sending bytes to browser for stream id %d\n", stream_id);
+				}
+				
+				printf("Sent to browser (%d bytes from stream id %d):\n", bytes_sent, stream_id);
+				for(i=0; i< bytes_sent; i++){
 					printf("%02x ", buffer[i]);
 				}
 				printf("\n");
@@ -412,6 +540,7 @@ int proxy_data(int sockfd, uint8_t stream_id, int32_t ous_out){
 
 
 err:
+		//should also remove stream from table
 	close(sockfd);
 	free(buffer);
 	free(response);
@@ -438,6 +567,7 @@ void *demultiplex_data(){
 
 			if(overflow_len > 0){
 				//process first part of slitheen info
+				printf("Completeing previously read header\n");
 				memmove(buffer+overflow_len, buffer, bytes_read);
 				memcpy(buffer, overflow, overflow_len);
 				bytes_remaining += overflow_len;
@@ -447,8 +577,62 @@ void *demultiplex_data(){
 
 			p = buffer;
 			while(bytes_remaining > 0){
+				if(bytes_remaining < SLITHEEN_HEADER_LEN){
+					printf("Partial header: ");
+					int i;
+					for(i = 0; i< bytes_remaining; i++){
+						printf("%02x ", p[i]);
+					}
+					printf("\n");
+				}
 
 				struct slitheen_hdr *sl_hdr = (struct slitheen_hdr *) p;
+				//first see if sl_hdr corresponds to a valid stream. If not, ignore rest of read bytes
+#ifdef DEBUG
+				printf("Slitheen header:\n");
+				int i;
+				for(i = 0; i< SLITHEEN_HEADER_LEN; i++){
+					printf("%02x ", p[i]);
+				}
+				printf("\n");
+#endif
+
+				p += sizeof(struct slitheen_hdr);
+
+				if(sl_hdr->stream_id == 0){
+#ifdef DEBUG
+					printf("Garbage bytes\n");
+#endif
+					p += ntohs(sl_hdr->len);
+					bytes_remaining -= sizeof(struct slitheen_hdr) + ntohs(sl_hdr->len);
+					continue;
+				}
+
+				int32_t pipe_fd =-1;
+				if(connections->first == NULL){
+					printf("There are no connections\n");
+				} else {
+					connection *last = connections->first;
+					if (last->stream_id == sl_hdr->stream_id){
+						printf("Found stream id %d!\n", sl_hdr->stream_id);
+						pipe_fd = last->pipe_fd;
+						printf("Pipe fd: %d\n", pipe_fd);
+					}
+					while(last->next != NULL){
+						last = last->next;
+						if (last->stream_id == sl_hdr->stream_id){
+							printf("Found stream id %d!\n", sl_hdr->stream_id);
+							pipe_fd = last->pipe_fd;
+							printf("Pipe fd: %d\n", pipe_fd);
+						}
+					}
+				}
+				
+				if(pipe_fd == -1){
+					printf("No stream id exists. Possibly invalid header\n");
+					break;
+				}
+				
 				if(ntohs(sl_hdr->len)+ sizeof(struct slitheen_hdr) > bytes_remaining){
 					overflow = calloc(1, bytes_remaining);
 					memcpy(overflow, p, bytes_remaining);
@@ -456,41 +640,13 @@ void *demultiplex_data(){
 					bytes_remaining = 0;
 					break;
 				}
-				p += sizeof(struct slitheen_hdr);
 
 				if(sl_hdr->garbage_len == 0){
 					printf("Received information for stream id: %d of length: %u\n", sl_hdr->stream_id, ntohs(sl_hdr->len));
 
-					int32_t pipe_fd =-1;
-
-					if(connections->first == NULL){
-						printf("There are no connections\n");
-					} else {
-						printf("First connection was at %p\n", connections->first);
-						connection *last = connections->first;
-						if (last->stream_id == sl_hdr->stream_id){
-							printf("Found stream id %d!\n", sl_hdr->stream_id);
-							pipe_fd = last->pipe_fd;
-							printf("Pipe fd: %d\n", pipe_fd);
-						}
-						while(last->next != NULL){
-							last = last->next;
-							printf("Next connection was at %p\n", last);
-							if (last->stream_id == sl_hdr->stream_id){
-								printf("Found stream id %d!\n", sl_hdr->stream_id);
-								pipe_fd = last->pipe_fd;
-								printf("Pipe fd: %d\n", pipe_fd);
-							}
-						}
-					}
-					
-					if(pipe_fd == -1){
-						printf("No stream id exists\n");
-					} else {
-						int32_t bytes_sent = write(pipe_fd, p, ntohs(sl_hdr->len));
-						if(bytes_sent < 0){
-							printf("Error reading to pipe for stream id %d\n", sl_hdr->stream_id);
-						}
+					int32_t bytes_sent = write(pipe_fd, p, ntohs(sl_hdr->len));
+					if(bytes_sent <= 0){
+						printf("Error reading to pipe for stream id %d\n", sl_hdr->stream_id);
 					}
 				}
 

+ 3 - 26
server/crypto.c

@@ -994,7 +994,7 @@ void update_context(flow *f, uint8_t *input, int32_t len, int32_t incoming, int3
  *  Output:
  *  	none
  */
-void check_handshake(struct packet_info *info, flow f){
+void check_handshake(struct packet_info *info){
 
 	FILE *fp;
 	int res, i, code;
@@ -1032,29 +1032,7 @@ void check_handshake(struct packet_info *info, flow f){
 		if (res) {
 			printf("Untagged\n");
 		} else {
-			fp = fopen("tags", "ab");
-			if (fp == NULL) {
-				perror("fopen");
-				exit(1);
-			}
-			//Write tag to file
-			for(i=0; i< 28; i++){
-				fprintf(fp, "%02x ", p[i]);
-			}
-			fprintf(fp, "\n");
-			fclose(fp);
-
-			//Write key to file
-			fp = fopen("sharedkey", "ab");
-			if (fp == NULL) {
-				perror("fopen");
-				exit(1);
-			}
-			for(i=0; i<16;i++){
-			    fprintf(fp, "%02x", key[i]);
-			}
-			fprintf(fp, "\n");
-			fclose(fp);
+
 			printf("Received tagged flow! (key =");
 			for(i=0; i<16;i++){
 			    printf(" %02x", key[i]);
@@ -1062,7 +1040,7 @@ void check_handshake(struct packet_info *info, flow f){
 			printf(")\n");
 
 			/* Save flow in table */
-			flow *flow_ptr = add_flow(f);
+			flow *flow_ptr = add_flow(info);
 			for(int i=0; i<16; i++){
 				flow_ptr->key[i] = key[i];
 			}
@@ -1077,5 +1055,4 @@ void check_handshake(struct packet_info *info, flow f){
 
 		}
 	}
-
 }

+ 1 - 1
server/crypto.h

@@ -25,7 +25,7 @@ int update_finish_hash(flow *f, uint8_t *hs);
 int verify_finish_hash(flow *f, uint8_t *p, int32_t incoming);
 int init_ciphers(flow *f);
 void update_context(flow *f, uint8_t *input, int32_t len, int32_t incoming, int32_t type, int32_t enc);
-void check_handshake(struct packet_info *info, flow f);
+void check_handshake(struct packet_info *info);
 
 #define PRE_MASTER_MAX_LEN BUFSIZ
 

+ 58 - 47
server/flow.c

@@ -38,52 +38,59 @@ int init_tables(void) {
 
 
 /* Add a new flow to the tagged flow table */
-flow *add_flow(flow newFlow) {
+flow *add_flow(struct packet_info *info) {
 	flow_entry *entry = calloc(1, sizeof(flow_entry));
-	flow *ptr = calloc(1, sizeof(flow));
-	entry->f = ptr;
+	flow *new_flow = calloc(1, sizeof(flow));
+	entry->f = new_flow;
 	entry->next = NULL;
 
 	printf("there are %d flows in the table\n", table->len);
 
-	sem_init(&(newFlow.flow_lock), 0, 1);
-	newFlow.state = TLS_CLNT_HELLO;
-	newFlow.in_encrypted = 0;
-	newFlow.out_encrypted = 0;
-	newFlow.application = 0;
-	newFlow.resume_session = 0;
-	newFlow.current_session = NULL;
-	newFlow.packet_chain = NULL;
-	sem_init(&(newFlow.packet_chain_lock), 0, 1);
-	newFlow.upstream_queue = NULL;
-	newFlow.upstream_remaining = 0;
-	sem_init(&(newFlow.upstream_queue_lock), 0, 1);
-	newFlow.outbox = NULL;
-	newFlow.outbox_len = 0;
-	newFlow.outbox_offset = 0;
-	newFlow.partial_record_header = NULL;
-	newFlow.partial_record_header_len = 0;
-	newFlow.remaining_record_len = 0;
-	newFlow.remaining_response_len = 0;
-	newFlow.httpstate = PARSE_HEADER;
-	newFlow.replace_response = 0;
-
-	newFlow.ecdh = NULL;
-
-
-	newFlow.finish_md_ctx = EVP_MD_CTX_create();
+	new_flow->src_ip = info->ip_hdr->src;
+	new_flow->dst_ip = info->ip_hdr->dst;
+	new_flow->src_port = info->tcp_hdr->src_port;
+	new_flow->dst_port = info->tcp_hdr->dst_port;
+
+	new_flow->upstream_seq_num = ntohl(info->tcp_hdr->sequence_num);
+	new_flow->downstream_seq_num = 0;
+
+	sem_init(&(new_flow->flow_lock), 0, 1);
+	new_flow->state = TLS_CLNT_HELLO;
+	new_flow->in_encrypted = 0;
+	new_flow->out_encrypted = 0;
+	new_flow->application = 0;
+	new_flow->resume_session = 0;
+	new_flow->current_session = NULL;
+	new_flow->packet_chain = NULL;
+	sem_init(&(new_flow->packet_chain_lock), 0, 1);
+	new_flow->upstream_queue = NULL;
+	new_flow->upstream_remaining = 0;
+	sem_init(&(new_flow->upstream_queue_lock), 0, 1);
+	new_flow->outbox = NULL;
+	new_flow->outbox_len = 0;
+	new_flow->outbox_offset = 0;
+	new_flow->partial_record_header = NULL;
+	new_flow->partial_record_header_len = 0;
+	new_flow->remaining_record_len = 0;
+	new_flow->remaining_response_len = 0;
+	new_flow->httpstate = PARSE_HEADER;
+	new_flow->replace_response = 0;
+
+	new_flow->ecdh = NULL;
+
+
+	new_flow->finish_md_ctx = EVP_MD_CTX_create();
 	const EVP_MD *md = EVP_sha384();
-	EVP_DigestInit_ex(newFlow.finish_md_ctx, md, NULL);
+	EVP_DigestInit_ex(new_flow->finish_md_ctx, md, NULL);
 
-	newFlow.clnt_read_ctx = NULL;
-	newFlow.clnt_write_ctx = NULL;
-	newFlow.srvr_read_ctx = NULL;
-	newFlow.srvr_write_ctx = NULL;
+	new_flow->clnt_read_ctx = NULL;
+	new_flow->clnt_write_ctx = NULL;
+	new_flow->srvr_read_ctx = NULL;
+	new_flow->srvr_write_ctx = NULL;
 
-	memset(newFlow.read_seq, 0, 8);
-	memset(newFlow.write_seq, 0, 8);
+	memset(new_flow->read_seq, 0, 8);
+	memset(new_flow->write_seq, 0, 8);
 
-	*ptr = newFlow;
 
 	sem_wait(&flow_table_lock);
 	flow_entry *last = table->first_entry;
@@ -98,7 +105,7 @@ flow *add_flow(flow newFlow) {
 	table->len ++;
 	sem_post(&flow_table_lock);
 
-	return ptr;
+	return new_flow;
 }
 
 /** Observes TLS handshake messages and updates the state of
@@ -480,8 +487,12 @@ int grow_table() {
  *
  *  Output:
  *  	index of flow in table or -1 if it doesn't exist
+	new_flow->src_ip = info->ip_hdr->src;
+	new_flow->dst_ip = info->ip_hdr->dst;
+	new_flow->src_port = info->tcp_hdr->src_port;
+	new_flow->dst_port = info->tcp_hdr->dst_port;
  */
-flow *check_flow(flow observed){
+flow *check_flow(struct packet_info *info){
 	/* Loop through flows in table and see if it exists */
 	int i;
 	flow_entry *entry = table->first_entry;
@@ -498,10 +509,10 @@ flow *check_flow(flow observed){
 			break;
 		}
 		candidate = entry->f;
-		if(candidate->src_ip.s_addr == observed.src_ip.s_addr){
-			if(candidate->dst_ip.s_addr == observed.dst_ip.s_addr){
-				if(candidate->src_port == observed.src_port){
-					if(candidate->dst_port == observed.dst_port){
+		if(candidate->src_ip.s_addr == info->ip_hdr->src.s_addr){
+			if(candidate->dst_ip.s_addr == info->ip_hdr->dst.s_addr){
+				if(candidate->src_port == info->tcp_hdr->src_port){
+					if(candidate->dst_port == info->tcp_hdr->dst_port){
 						found = candidate;
 					}
 				}
@@ -519,10 +530,10 @@ flow *check_flow(flow observed){
 			break;
 		}
 		candidate = entry->f;
-		if(candidate->src_ip.s_addr == observed.dst_ip.s_addr){
-			if(candidate->dst_ip.s_addr == observed.src_ip.s_addr){
-				if(candidate->src_port == observed.dst_port){
-					if(candidate->dst_port == observed.src_port){
+		if(candidate->src_ip.s_addr == info->ip_hdr->dst.s_addr){
+			if(candidate->dst_ip.s_addr == info->ip_hdr->src.s_addr){
+				if(candidate->src_port == info->tcp_hdr->dst_port){
+					if(candidate->dst_port == info->tcp_hdr->src_port){
 						found = candidate;
 					}
 				}

+ 2 - 2
server/flow.h

@@ -139,10 +139,10 @@ typedef struct flow_table_st {
 
 
 int init_tables(void);
-flow *add_flow(flow newFlow);
+flow *add_flow(struct packet_info *info);
 int update_flow(flow *f);
 int remove_flow(flow *f);
-flow *check_flow(flow observed);
+flow *check_flow(struct packet_info *info);
 flow *get_flow(int index);
 
 int init_session_cache (void);

+ 34 - 5
server/relay.c

@@ -18,6 +18,8 @@
 #include "flow.h"
 #include "crypto.h"
 
+#define DEBUG
+
 /** Called when a TLS application record is received for a
  *  tagged flow. Upstream packets will be checked for covert
  *  requests to censored sites, downstream packets will be
@@ -324,20 +326,19 @@ int read_header(flow *f, struct packet_info *info){
 					//remove from stream id table
 					if(last == streams->first){
 						streams->first = last->next;
-						printf("streams->first is now %p\n", streams->first);
 					} else {
 						prev->next = last->next;
-						printf("prev->next is now %p\n", prev->next);
 					}
-					printf("freeing %p\n", last);
 					free(last);
 					break;
 				}
+				printf("Found stream id %d\n", last->stream_id);
 				int32_t bytes_sent = write(stream_pipe, p, stream_len);
 
 			} else if(stream_len > 0){
 
 				/*Else, spawn a thread to handle the proxy to this site*/
+				printf("creating new thread for stream id %d\n", stream_id);
 				pthread_t proxy_thread;
 				int32_t pipefd[2];
 				if(pipe(pipefd) < 0){
@@ -377,6 +378,7 @@ int read_header(flow *f, struct packet_info *info){
 				}
 
 			} else{
+				printf("Error, stream len 0\n");
 				break;
 			}
 			output_len -= stream_len;
@@ -416,10 +418,14 @@ void *proxy_covert_site(void *data){
 		(struct proxy_thread_data *) data;
 
 	uint8_t *p = thread_data->initial_data;
+	uint16_t data_len = thread_data->initial_len;
 	uint8_t stream_id = thread_data->stream_id;
 
+	int32_t bytes_sent;
+
 	struct socks_req *clnt_req = (struct socks_req *) p;
 	p += 4;
+	data_len -= 4;
 
 	int32_t handle = -1;
 
@@ -437,12 +443,14 @@ void *proxy_covert_site(void *data){
 		//IPv4
 		dest.sin_addr.s_addr = *((uint32_t*) p);
 		p += 4;
+		data_len -= 4;
 		break;
 		
 	case 0x03:
 		//domain name
 		domain_len = p[0];
 		p++;
+		data_len --;
 		uint8_t *domain_name = calloc(1, domain_len+1);
 		memcpy(domain_name, p, domain_len);
 		domain_name[domain_len] = '\0';
@@ -451,6 +459,7 @@ void *proxy_covert_site(void *data){
 		dest.sin_addr = *((struct in_addr *) host->h_addr);
 
 		p += domain_len;
+		data_len -= domain_len;
 		free(domain_name);
 		break;
 	case 0x04:
@@ -461,6 +470,8 @@ void *proxy_covert_site(void *data){
 
 	//now set the port
 	dest.sin_port = *((uint16_t *) p);
+	p += 2;
+	data_len -= 2;
 
     handle = socket(AF_INET, SOCK_STREAM, 0);
     if(handle < 0){
@@ -497,6 +508,8 @@ void *proxy_covert_site(void *data){
 	fflush(stdout);
 #endif
 
+#ifdef OLD
+	//No longer need to send response
 	queue_block *new_block = calloc(1, sizeof(queue_block));
 	new_block->len = 10;
 	new_block->offset = 0;
@@ -512,6 +525,22 @@ void *proxy_covert_site(void *data){
 			last = last->next;
 		last->next = new_block;
 	}
+#endif
+
+	//see if there were extra upstream bytes
+	if(data_len > 0){
+		printf("Data len is %d\n", data_len);
+		printf("Upstream bytes: ");
+		for(int i=0; i< data_len; i++){
+			printf("%02x ", p[i]);
+		}
+		printf("\n");
+		bytes_sent = send(handle, p,
+				data_len, 0);
+		if( bytes_sent <= 0){
+			goto err;
+		}
+	}
 
 	uint8_t *buffer = calloc(1, BUFSIZ);
 	int32_t buffer_len = BUFSIZ;
@@ -549,7 +578,7 @@ void *proxy_covert_site(void *data){
 				printf("\n");
 				printf("%s\n", buffer);
 #endif
-				int32_t bytes_sent = send(handle, buffer,
+				bytes_sent = send(handle, buffer,
 						bytes_read, 0);
 				if( bytes_sent <= 0){
 					break;
@@ -580,7 +609,7 @@ void *proxy_covert_site(void *data){
 #endif
 
 				//make a new queue block
-				new_block = calloc(1, sizeof(queue_block));
+				queue_block *new_block = calloc(1, sizeof(queue_block));
 				new_block->len = bytes_read;
 				new_block->offset = 0;
 				new_block->data = new_data;

+ 2 - 11
server/slitheen-proxy.c

@@ -153,24 +153,15 @@ end:
  */
 void process_packet(struct packet_info *info){
 
-	flow newFlow;
-
-	newFlow.src_ip = info->ip_hdr->src;
-	newFlow.dst_ip = info->ip_hdr->dst;
-	newFlow.src_port = info->tcp_hdr->src_port;
-	newFlow.dst_port = info->tcp_hdr->dst_port;
-
-	newFlow.upstream_seq_num = ntohl(info->tcp_hdr->sequence_num);
-	newFlow.downstream_seq_num = 0;
 
 	/* Checks to see if this is a possibly tagged hello msg */
 	if ((info->record_hdr != NULL) && (info->record_hdr->type == HS)){ /* This is a TLS handshake */
-		check_handshake(info, newFlow);
+		check_handshake(info);
 	}
 
 	/* Now if flow is in table, update state */
 	flow *observed;
-	if((observed = check_flow(newFlow)) != NULL){
+	if((observed = check_flow(info)) != NULL){
 	
 		if(observed->application){
 			replace_packet(observed, info);