Browse Source

Process status 304 resources (header only) so that it doesn't forfeit the flow.

cecylia 6 years ago
parent
commit
0277603e5d
3 changed files with 78 additions and 19 deletions
  1. 18 10
      relay_station/flow.c
  2. 57 8
      relay_station/relay.c
  3. 3 1
      relay_station/slitheen-proxy.c

+ 18 - 10
relay_station/flow.c

@@ -390,6 +390,11 @@ int update_flow(flow *f, uint8_t *record, uint8_t incoming) {
 #ifdef DEBUG_HS
 					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));
 #endif
+					if((f->in_encrypted == 2) && (f->out_encrypted == 2)){
+						f->application = 1;
+                                                printf("Handshake complete!\n");
+					}
+
 					if(!incoming) {
 					    // We only care about incoming
 					    // Finished messages
@@ -417,11 +422,6 @@ int update_flow(flow *f, uint8_t *record, uint8_t incoming) {
 								f->dst_ip.s_addr, ntohs(f->dst_port));
 					}
 
-					if((f->in_encrypted == 2) && (f->out_encrypted == 2)){
-						f->application = 1;
-                                                printf("Handshake complete!\n");
-					}
-
 					break;
 				default:
 					printf("Error: unrecognized hs message? (%x:%d -> %x:%d)...\n", f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port));
@@ -456,15 +456,23 @@ int update_flow(flow *f, uint8_t *record, uint8_t incoming) {
 			p += RECORD_HEADER_LEN;
 			if(((incoming) && (f->in_encrypted > 0)) || ((!incoming) && (f->out_encrypted > 0))){
 				//decrypt alert
-				encrypt(f, p, p, record_len - RECORD_HEADER_LEN, incoming, 0x16, 0, 0);
+				int32_t n = encrypt(f, p, p, record_len - RECORD_HEADER_LEN, incoming, 0x15, 0, 0);
+                                if(n <= 0){
+                                    printf("Error decrypting Alert\n");
+                                }
+				printf("Decrypted alert:\n");
+				for(int i=0; i< n; i++){
+					printf("%02x ", p[i]);
+				}
+				printf("\n");
 				p += EVP_GCM_TLS_EXPLICIT_IV_LEN;
 			}
-			printf("Alert (%x:%d -> %x:%d) %02x %02x \n", f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port), p[0], p[1]);
+			printf("Alert (%x:%d -> %x:%d) (%s) %02x %02x \n", f->src_ip.s_addr, ntohs(f->src_port), f->dst_ip.s_addr, ntohs(f->dst_port), (incoming) ? "incoming" : "outgoing", p[0], p[1]);
 			fflush(stdout);
 			
 			//re-encrypt alert
 			if(((incoming) && (f->in_encrypted > 0)) || ((!incoming) && (f->out_encrypted > 0))){
-				int32_t n =  encrypt(f, record+RECORD_HEADER_LEN, record+RECORD_HEADER_LEN, record_len - (RECORD_HEADER_LEN+16), incoming, 0x16, 1, 1);
+				int32_t n =  encrypt(f, record+RECORD_HEADER_LEN, record+RECORD_HEADER_LEN, record_len - (RECORD_HEADER_LEN+16), incoming, 0x15, 1, 1);
 				if(n <= 0){
 					printf("Error re-encrypting alert\n");
 				}
@@ -789,7 +797,7 @@ int verify_session_id(flow *f, uint8_t *hs){
 		session *last = sessions->first_session;
 		int found = 0;
 		for(int i=0; ((i<sessions->length) && (!found)); i++){
-#ifdef DEBUG_HS
+#ifdef DEBUG_HS_EXTRA
 			printf("Checking saved session id: ");
 			for (int j=0; j< last->session_id_len; j++){
 				printf("%02x ", last->session_id[j]);
@@ -1279,7 +1287,7 @@ int add_packet(flow *f, struct packet_info *info){
                     return 1;//error occurred and flow was removed
                 }
 
-                if(f->in_encrypted ==2){
+                if(f->in_encrypted ==2 && incoming){
                     //if server finished message was received, copy changes back to packet
 
 #ifdef DEBUG

+ 57 - 8
relay_station/relay.c

@@ -933,7 +933,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
 
 			if(f->httpstate == PARSE_HEADER || f->httpstate == BEGIN_CHUNK || f->httpstate == END_CHUNK){
 #ifdef RESOURCE_DEBUG
-                            printf("record exceeds packet length, FORFEIT\n");
+                            printf("record exceeds packet length, state %x -> FORFEIT (%p)\n", f->httpstate, f);
 #endif
 				f->httpstate = FORFEIT_REST;
 			} else if( f->httpstate == MID_CONTENT || f->httpstate == MID_CHUNK){
@@ -972,13 +972,14 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
 					if(f->httpstate == MID_CHUNK)
 						f->httpstate = END_CHUNK;
 					else {
+                                            printf("Change state %x --> PARSE_HEADER (%p)\n", f->httpstate, f);
 						f->httpstate = PARSE_HEADER;
 					}
 				}
 				if(f->remaining_response_len < 0){
 					f->remaining_response_len = 0;
 #ifdef RESOURCE_DEBUG
-                            printf("Resource is mid-content and super long record exceeds remaining resource len, FORFEIT\n");
+                            printf("Resource is mid-content and super long record exceeds remaining resource len, FORFEIT (%p)\n", f);
 #endif
 					f->httpstate = FORFEIT_REST;
 				}
@@ -997,6 +998,14 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
 			break;
 		}
 
+#ifdef DEBUG_DOWN
+		printf("Received record\n");
+		printf("Bytes:\n");
+		for(int i=0; i< record_len; i++){
+			printf("%02x ", record_ptr[i]);
+		}
+		printf("\n");
+#endif
 
 		//now decrypt the record
 		int32_t n = encrypt(f, record_ptr, record_ptr, record_len, 1,
@@ -1032,7 +1041,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
 		while(remaining_record_len > 0){
 
 #ifdef RESOURCE_DEBUG
-                    printf("Current state: %d\n", f->httpstate);
+                    printf("Current state (flow %p): %x\n", f, f->httpstate);
 #endif
 
 			switch(f->httpstate){
@@ -1056,6 +1065,31 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
 						f->replace_response = 0;
 					}
 
+                                        //TODO: more cases for more status codes
+                                        //TODO: better way of finding terminating string
+                                        len_ptr = strstr((const char *) p, "304 Not Modified");
+                                        if(len_ptr != NULL){
+                                            //no message body, look for terminating string
+                                            len_ptr = strstr((const char *) p, "\r\n\r\n");
+                                            if(len_ptr != NULL){
+                                                    f->httpstate = PARSE_HEADER;
+                                                    remaining_record_len -= (((uint8_t *)len_ptr - p) + 4);
+                                                    p = (uint8_t *) len_ptr + 4;
+#ifdef RESOURCE_DEBUG
+                                                    printf("Found a 304 not modified, waiting for next header\n");
+                                                    printf("Remaining record len: %d\n", remaining_record_len);
+#endif
+                                            } else {
+#ifdef RESOURCE_DEBUG
+                                                    printf("Missing end of header. Sending to FORFEIT_REST (%p)\n", f);
+#endif
+                                                    f->httpstate = FORFEIT_REST;
+                                            }
+
+
+                                            break;
+                                        }
+
 					//check for 200 OK message
 					len_ptr = strstr((const char *) p, "200 OK");
 					if(len_ptr == NULL){
@@ -1093,13 +1127,13 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
 							} else {
 								remaining_record_len = 0;
 #ifdef RESOURCE_DEBUG
-								printf("Missing end of header. Sending to FORFEIT_REST\n");
+								printf("Missing end of header. Sending to FORFEIT_REST (%p)\n", f);
 #endif
 								f->httpstate = FORFEIT_REST;
 							}
 						} else {
 #ifdef RESOURCE_DEBUG
-							printf("No content length of transfer encoding field, sending to FORFEIT_REST\n");
+							printf("No content length of transfer encoding field, sending to FORFEIT_REST (%p)\n", f);
 #endif
 							f->httpstate = FORFEIT_REST;
 							remaining_record_len = 0;
@@ -1141,6 +1175,8 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
 						}
 						remaining_record_len -= f->remaining_response_len;
 						p += f->remaining_response_len;
+
+                                                printf("Change state %x --> PARSE_HEADER (%p)\n", f->httpstate, f);
 						f->httpstate = PARSE_HEADER;
 						f->remaining_response_len = 0;
 					}
@@ -1162,7 +1198,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
 					} else {
 						remaining_record_len = 0;
 #ifdef RESOURCE_DEBUG
-                            printf("Error parsing in BEGIN_CHUNK, FORFEIT\n");
+                            printf("Error parsing in BEGIN_CHUNK, FORFEIT (%p)\n", f);
 #endif
 						f->httpstate = FORFEIT_REST;
 					}
@@ -1213,7 +1249,7 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
 						remaining_record_len -= 2;
 					} else {
 						remaining_record_len = 0;
-						printf("Couldn't find end of chunk, sending to FORFEIT_REST\n");
+						printf("Couldn't find end of chunk, sending to FORFEIT_REST (%p)\n", f);
 						f->httpstate = FORFEIT_REST;
 					}
 					break;
@@ -1221,12 +1257,13 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
 				case END_BODY:
 					needle = strstr((const char *) p, "\r\n");
 					if(needle != NULL){
+                                                printf("Change state %x --> PARSE_HEADER (%p)\n", f->httpstate, f);
 						f->httpstate = PARSE_HEADER;
 						p += 2;
 						remaining_record_len -= 2;
 					} else {
 						remaining_record_len = 0;
-						printf("Couldn't find end of body, sending to FORFEIT_REST\n");
+						printf("Couldn't find end of body, sending to FORFEIT_REST (%p)\n", f);
 						f->httpstate = FORFEIT_REST;
 					}
 					break;
@@ -1267,6 +1304,18 @@ int process_downstream(flow *f, int32_t offset, struct packet_info *info){
 			return 0;
 		}
 
+#ifdef DEBUG_DOWN
+		fprintf(stdout,"Flow: %x > %x (%s)\n", info->ip_hdr->src.s_addr, info->ip_hdr->dst.s_addr, (info->ip_hdr->src.s_addr != f->src_ip.s_addr)? "incoming":"outgoing");
+		fprintf(stdout,"ID number: %u\n", htonl(info->ip_hdr->id));
+		fprintf(stdout,"Sequence number: %u\n", htonl(info->tcp_hdr->sequence_num));
+		fprintf(stdout,"Acknowledgement number: %u\n", htonl(info->tcp_hdr->ack_num));
+                printf("New ciphertext bytes:\n");
+                for(int i=0; i< n; i++){
+                        printf("%02x ", record_ptr[i]);
+                }
+                printf("\n");
+#endif
+
 		p = record_ptr + record_len;
 		remaining_packet_len -= record_len;
 		if(f->partial_record_header_len > 0){

+ 3 - 1
relay_station/slitheen-proxy.c

@@ -174,7 +174,7 @@ void inject_packet(struct inject_args *iargs, const struct pcap_pkthdr *header,
         printf("Length: %d\n", header->len);
     }
 
-#ifdef DEBUG
+#ifdef DEBUG_EXTRA
     fprintf(stderr, "injected the following packet:\n");
     for(int i=0; i< header->len; i++){
         fprintf(stderr, "%02x ", packet[i]);
@@ -367,6 +367,8 @@ void process_packet(struct inject_args *iargs, const struct pcap_pkthdr *header,
         observed->ref_ctr--;
     }
 
+    //TODO: figure out how to not need this
+    tcp_checksum(info);//update checksum
 err:
     free(info);//Note: don't free this while a thread is using it