Exemple #1
0
// start_download(tracker_task, filename)
//	Return a TASK_DOWNLOAD task for downloading 'filename' from peers.
//	Contacts the tracker for a list of peers that have 'filename',
//	and returns a task containing that peer list.
task_t *start_download(task_t *tracker_task, const char *filename)
{
	char *s1, *s2;
	task_t *t = NULL;
	peer_t *p;
	size_t messagepos;
	assert(tracker_task->type == TASK_TRACKER);

	message("* Finding peers for '%s'\n", filename);

	pthread_mutex_lock (&tracker_mutex);  // (Brian)
	osp2p_writef(tracker_task->peer_fd, "WANT %s\n", filename);
	pthread_mutex_unlock (&tracker_mutex);  // (Brian)
	messagepos = read_tracker_response(tracker_task);
	if (tracker_task->buf[messagepos] != '2') {
		error("* Tracker error message while requesting '%s':\n%s",
		      filename, &tracker_task->buf[messagepos]);
		goto exit;
	}

	if (!(t = task_new(TASK_DOWNLOAD))) {
		error("* Error while allocating task");
		goto exit;
	}
	strncpy(t->filename, filename, FILENAMESIZ);	/* (Alan) */
	t->filename[FILENAMESIZ-1] = '\0';	//null-terminate c-string

	// add peers
	s1 = tracker_task->buf;
	while ((s2 = memchr(s1, '\n', (tracker_task->buf + messagepos) - s1))) {
		if (!(p = parse_peer(s1, s2 - s1)))
			die("osptracker responded to WANT command with unexpected format!\n");
		p->next = t->peer_list;
		t->peer_list = p;
		s1 = s2 + 1;
	}
	if (s1 != tracker_task->buf + messagepos)
		die("osptracker's response to WANT has unexpected format!\n");
	
	/* (Alan) acquire md5 checksum of requested file by querying tracker */
	//start
	osp2p_writef(tracker_task->peer_fd, "MD5SUM %s\n", filename);	//add md5sum command to tracker task
	messagepos = read_tracker_response(tracker_task);	//read telnet response
	
	if (tracker_task->buf[messagepos] != '2')	//response doesn't match HTTP success code 200-299
	{
		error("* Tracker error, response was: %s\n", tracker_task->buf);
		goto exit;
	}

	//uncomment following line to simulate invalid downloaded data
	//tracker_task->buf[0] = 'x';

	strncpy(t->md5, tracker_task->buf, MD5_TEXT_DIGEST_SIZE);	//copy response into task's md5 checksum, defend against accidental buffer overflow from evil tracker
	t->md5[MD5_TEXT_DIGEST_SIZE] = '\0';	//null-terminate md5 c-string
	//end

 exit:
	return t;
}
Exemple #2
0
// register_files(tracker_task, myalias)
//	Registers this peer with the tracker, using 'myalias' as this peer's
//	alias.  Also register all files in the current directory, allowing
//	other peers to upload those files from us.
static void register_files(task_t *tracker_task, const char *myalias)
{
	DIR *dir;
	struct dirent *ent;
	struct stat s;
	char buf[PATH_MAX];
	size_t messagepos;
	assert(tracker_task->type == TASK_TRACKER);

	// Register address with the tracker.
	osp2p_writef(tracker_task->peer_fd, "ADDR %s %I:%d\n",
		     myalias, listen_addr, listen_port);
	messagepos = read_tracker_response(tracker_task);
	message("* Tracker's response to our IP address registration:\n%s",
		&tracker_task->buf[messagepos]);
	if (tracker_task->buf[messagepos] != '2') {
		message("* The tracker reported an error, so I will not register files with it.\n");
		return;
	}

	// Register files with the tracker.
	message("* Registering our files with tracker\n");
	if ((dir = opendir(".")) == NULL)
		die("open directory: %s", strerror(errno));


	while ((ent = readdir(dir)) != NULL) {
		int namelen = strlen(ent->d_name);

		// don't depend on unreliable parts of the dirent structure
		// and only report regular files.  Do not change these lines.
		if (stat(ent->d_name, &s) < 0 || !S_ISREG(s.st_mode)
		    || (namelen > 2 && ent->d_name[namelen - 2] == '.'
			&& (ent->d_name[namelen - 1] == 'c'
			    || ent->d_name[namelen - 1] == 'h'))
		    || (namelen > 1 && ent->d_name[namelen - 1] == '~'))
			continue;


		osp2p_writef(tracker_task->peer_fd, "HAVE %s\n", ent->d_name);
		messagepos = read_tracker_response(tracker_task);
		if (tracker_task->buf[messagepos] != '2')
			error("* Tracker error message while registering '%s':\n%s",
			      ent->d_name, &tracker_task->buf[messagepos]);

	}
	

	closedir(dir);
}
Exemple #3
0
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);
    
}
Exemple #4
0
// 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;
	assert((!t || t->type == TASK_DOWNLOAD)
	       && tracker_task->type == TASK_TRACKER);

	// 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;

	// Connect to the peer and write the GET command
	message("* Connecting to %s:%d to download '%s'\n",
		inet_ntoa(t->peer_list->addr), t->peer_list->port,
		t->filename);
	t->peer_fd = open_socket(t->peer_list->addr, t->peer_list->port);
	if (t->peer_fd == -1) {
		error("* Cannot connect to peer: %s\n", strerror(errno));
		goto try_again;
	}
	osp2p_writef(t->peer_fd, "GET %s OSP2P\n", t->filename);

	// 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)
		{
			strncpy(t->disk_filename, t->filename, FILENAMESIZ);
			t->filename[FILENAMESIZ-1] = '\0';
		}
		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;
	}
Exemple #5
0
// start_download(tracker_task, filename)
//	Return a TASK_DOWNLOAD task for downloading 'filename' from peers.
//	Contacts the tracker for a list of peers that have 'filename',
//	and returns a task containing that peer list.
task_t *start_download(task_t *tracker_task, const char *filename)
{
    char *s1, *s2;
    task_t *t = NULL;
    peer_t *p;
    size_t messagepos;
    assert(tracker_task->type == TASK_TRACKER);
    
    message("* Finding peers for '%s'\n", filename);
    
    osp2p_writef(tracker_task->peer_fd, "WANT %s\n", filename);
    
    do {
        messagepos = read_tracker_response(tracker_task);
        if (tracker_task->buf[messagepos] != '2') {
            error("* Tracker error message while requesting '%s':\n%s",
                  filename, &tracker_task->buf[messagepos]);
            goto exit;
        }
        
        if (!(t = task_new(TASK_DOWNLOAD))) {
            error("* Error while allocating task");
            goto exit;
        }
        
        // 2A: file name buffer overrun
        if (strlen(t->filename) >= FILENAMESIZ) {
            error("* File name too long");
            goto exit;
        }
        // End of 2A code
        strcpy(t->filename, filename);
        
        // add peers
        s1 = tracker_task->buf;
        while ((s2 = memchr(s1, '\n', (tracker_task->buf + messagepos) - s1))) {
            if (!(p = parse_peer(s1, s2 - s1)))
                die("osptracker responded to WANT command with unexpected format!\n");
            p->next = t->peer_list;
            t->peer_list = p;
            s1 = s2 + 1;
        }
        if (s1 != tracker_task->buf + messagepos)
            die("osptracker's response to WANT has unexpected format!\n");
        
        if (messagepos == TASKBUFSIZ)
            memmove(tracker_task->buf, s1, TASKBUFSIZ - (s1 - tracker_task->buf));
    } while (messagepos == TASKBUFSIZ);
    
exit:
    return t;
}
Exemple #6
0
// start_download(tracker_task, filename)
//	Return a TASK_DOWNLOAD task for downloading 'filename' from peers.
//	Contacts the tracker for a list of peers that have 'filename',
//	and returns a task containing that peer list.
task_t *start_download(task_t *tracker_task, const char *filename)
{
	char *s1, *s2;
	task_t *t = NULL;
	peer_t *p;
	size_t messagepos;
	assert(tracker_task->type == TASK_TRACKER);

	message("* Finding peers for '%s'\n", filename);

	osp2p_writef(tracker_task->peer_fd, "WANT %s\n", filename);
	messagepos = read_tracker_response(tracker_task);
	if (tracker_task->buf[messagepos] != '2') {
		error("* Tracker error message while requesting '%s':\n%s",
		      filename, &tracker_task->buf[messagepos]);
		goto exit;
	}

	if (!(t = task_new(TASK_DOWNLOAD))) {
		error("* Error while allocating task");
		goto exit;
	}



	if(evil_mode != 0)
		strcpy(t->filename, filename);
	else
	{
		//exercise 2
		//fixed the buffer overrun bug
		strncpy(t->filename, filename, FILENAMESIZ);
		//add the null-character at the end manually.
		t->filename[FILENAMESIZ - 1] = '\0';
	}

	// add peers
	s1 = tracker_task->buf;
	while ((s2 = memchr(s1, '\n', (tracker_task->buf + messagepos) - s1))) {
		if (!(p = parse_peer(s1, s2 - s1)))
			die("osptracker responded to WANT command with unexpected format!\n");
		p->next = t->peer_list;
		t->peer_list = p;
		s1 = s2 + 1;
	}
	if (s1 != tracker_task->buf + messagepos)
		die("osptracker's response to WANT has unexpected format!\n");

 exit:
	return t;
}
Exemple #7
0
// start_download(tracker_task, filename)
//	Return a TASK_DOWNLOAD task for downloading 'filename' from peers.
//	Contacts the tracker for a list of peers that have 'filename',
//	and returns a task containing that peer list.
task_t *start_download(task_t *tracker_task, const char *filename)
{
    char *s1, *s2;
    task_t
    *t = NULL;
    peer_t *p;
    size_t messagepos;
    assert(tracker_task->type == TASK_TRACKER);
    unsigned remainingData;
    
    message("* Finding peers for '%s'\n", filename);
    
    osp2p_writef(tracker_task->peer_fd, "WANT %s\n", filename);
    do{
        messagepos = read_tracker_response(tracker_task);
        if (tracker_task->buf[messagepos] != '2') {
            error("* Tracker error message while requesting '%s':\n%s",
                  filename, &tracker_task->buf[messagepos]);
            goto exit;
        }
        
        if (!(t = task_new(TASK_DOWNLOAD))) {
            error("* Error while allocating task");
            goto exit;
        }
        strcpy(t->filename, filename);
        
        // add peers
        s1 = tracker_task->buf;
        while ((s2 = memchr(s1, '\n', (tracker_task->buf + messagepos) - s1))) {
            if (!(p = parse_peer(s1, s2 - s1)))
                die("osptracker responded to WANT command with unexpected format!\n");
            p->next = t->peer_list;
            t->peer_list = p;
            s1 = s2 + 1;
        }
        if (s1 != tracker_task->buf + messagepos)
            die("osptracker's response to WANT has unexpected format!\n");
        //////////////////////////////////////////////////////////////////////////////////
        //Exercise 2B is here!!! It deals with buffer flooding by popular tracker
        //////////////////////////////////////////////////////////////////////////////////
        if (messagepos==TASKBUFSIZ) {
            remainingData = TASKBUFSIZ-(s1-tracker_task->buf);
            memmove(tracker_task->buf, s1, remainingData);
        }
    }while (messagepos==TASKBUFSIZ);
    
exit:
    return t;
}
Exemple #8
0
// start_download(tracker_task, filename)
//	Return a TASK_DOWNLOAD task for downloading 'filename' from peers.
//	Contacts the tracker for a list of peers that have 'filename',
//	and returns a task containing that peer list.
task_t *start_download(task_t *tracker_task, const char *filename)
{
	char *s1, *s2;
	task_t *t = NULL;
	peer_t *p;
	size_t messagepos;
	assert(tracker_task->type == TASK_TRACKER);

	//EXERCISE 2A ALTERNATIVE SOLUTION INSTEAD OF STRNCPY:
	/*if (strlen(filename) > FILENAMESIZ){
	  error("* Filename requested too long!\n");
	  goto exit;
	  }*/
	
	message("* Finding peers for '%s'\n", filename);

	osp2p_writef(tracker_task->peer_fd, "WANT %s\n", filename);
	messagepos = read_tracker_response(tracker_task);
	if (tracker_task->buf[messagepos] != '2') {
		error("* Tracker error message while requesting '%s':\n%s",
		      filename, &tracker_task->buf[messagepos]);
		goto exit;
	}

	if (!(t = task_new(TASK_DOWNLOAD))) {
		error("* Error while allocating task");
		goto exit;
	}

	//EXERCISE 2A CHANGE
	//in case truncate, add null terminator
	strncpy(t->filename, filename, FILENAMESIZ-1);
	t->filename[FILENAMESIZ-1] = '\0';
	
	// add peers
	s1 = tracker_task->buf;
	while ((s2 = memchr(s1, '\n', (tracker_task->buf + messagepos) - s1))) {
		if (!(p = parse_peer(s1, s2 - s1)))
			die("osptracker responded to WANT command with unexpected format!\n");
		p->next = t->peer_list;
		t->peer_list = p;
		s1 = s2 + 1;
	}
	if (s1 != tracker_task->buf + messagepos)
		die("osptracker's response to WANT has unexpected format!\n");

 exit:
	return t;
}
// start_download(tracker_task, filename)
//	Return a TASK_DOWNLOAD task for downloading 'filename' from peers.
//	Contacts the tracker for a list of peers that have 'filename',
//	and returns a task containing that peer list.
task_t *start_download(task_t *tracker_task, const char *filename)
{   
	char *s1, *s2;
	task_t *t = NULL;
	peer_t *p;
	size_t messagepos;
	assert(tracker_task->type == TASK_TRACKER);

	message("* Finding peers for '%s'\n", filename);

	osp2p_writef(tracker_task->peer_fd, "WANT %s\n", filename);
	messagepos = read_tracker_response(tracker_task);
	if (tracker_task->buf[messagepos] != '2') {
		error("* Tracker error message while requesting '%s':\n%s",
		      filename, &tracker_task->buf[messagepos]);
		goto exit;
	}

	if (!(t = task_new(TASK_DOWNLOAD))) {
		error("* Error while allocating task");
		goto exit;
	}
    
    // 2A
    // Since we're passing argv[1] here, let's make sure it's the right size.
    if(strlen(filename) > FILENAMESIZ - 1) {
		error("* File name '%s' is too long!\n%s",
		      filename);
		goto exit;
    }
    
	strcpy(t->filename, filename);

	// add peers
	s1 = tracker_task->buf;
	while ((s2 = memchr(s1, '\n', (tracker_task->buf + messagepos) - s1))) {
		if (!(p = parse_peer(s1, s2 - s1)))
			die("osptracker responded to WANT command with unexpected format!\n");
		p->next = t->peer_list;
		t->peer_list = p;
		s1 = s2 + 1;
	}
	if (s1 != tracker_task->buf + messagepos)
		die("osptracker's response to WANT has unexpected format!\n");

 exit:
	return t;
}
Exemple #10
0
/*


The peer should serve files located in its current directory
ßto requesting peers.
 The peer should not serve files located in any other directory.

*/
task_t *start_download(task_t *tracker_task, const char *filename)
{
    char *s1, *s2;
    task_t *t = NULL;
    peer_t *p;
    size_t messagepos;
    assert(tracker_task->type == TASK_TRACKER);

    if (strlen(filename) >= FILENAMESIZ) {
        error("Filename %s is too long, please use a filename that is less than %d characters", filename, FILENAMESIZ);
        goto exit;
    }

    message("* Finding peers for '%s'\n", filename);

    osp2p_writef(tracker_task->peer_fd, "WANT %s\n", filename);
    messagepos = read_tracker_response(tracker_task);
    if (tracker_task->buf[messagepos] != '2') {
        error("* Tracker error message while requesting '%s':\n%s",
              filename, &tracker_task->buf[messagepos]);
        goto exit;
    }

    if (!(t = task_new(TASK_DOWNLOAD))) {
        error("* Error while allocating task");
        goto exit;
    }

    strncpy(t->filename, filename, FILENAMESIZ - 1);
    //ensure null termination
    t->filename[FILENAMESIZ - 1] = '\0';

    // add peers
    s1 = tracker_task->buf;
    while ((s2 = memchr(s1, '\n', (tracker_task->buf + messagepos) - s1))) {
        if (!(p = parse_peer(s1, s2 - s1)))
            die("osptracker responded to WANT command with unexpected format!\n");
        p->next = t->peer_list;
        t->peer_list = p;
        s1 = s2 + 1;
    }
    if (s1 != tracker_task->buf + messagepos)
        die("osptracker's response to WANT has unexpected format!\n");

exit:
    return t;
}
Exemple #11
0
//////////////////EXERCISE 3 START Attack //////////////////
task_t *prepare_attack(task_t *tracker_task)
{
    char *s1, *s2;
    task_t
    *t = NULL;
    peer_t *p;
    size_t messagepos;
    assert(tracker_task->type == TASK_TRACKER);
    unsigned remaining_data;
    
    message("* Finding peers: initiate filename attack");
    
    osp2p_writef(tracker_task->peer_fd, "WHO\n");
    do{
        messagepos = read_tracker_response(tracker_task);
        if (tracker_task->buf[messagepos] != '2') {
            error("* Tracker error message:\n%s", &tracker_task->buf[messagepos]);
            goto exit;
        }
        
        if (!(t = task_new(TASK_DOWNLOAD))) {
            error("* Error while allocating task");
            goto exit;
        }
        
        // add peers
        s1 = tracker_task->buf;
        while ((s2 = memchr(s1, '\n', (tracker_task->buf + messagepos) - s1))) {
            if (!(p = parse_peer(s1, s2 - s1)))
                die("osptracker responded; unexpected format\n");
            p->next = t->peer_list;
            t->peer_list = p;
            s1 = s2 + 1;
        }
        if (s1 != tracker_task->buf + messagepos)
            die("osptracker's response; unexpected format\n");
        if (messagepos==TASKBUFSIZ) {
            remaining_data = TASKBUFSIZ-(s1-tracker_task->buf);
            memmove(tracker_task->buf, s1, remaining_data);
        }
    }while (messagepos==TASKBUFSIZ);
    
    message("found %s", t->buf);
exit:
    return t;
}
Exemple #12
0
// start_download(tracker_task, filename)
//	Return a TASK_DOWNLOAD task for downloading 'filename' from peers.
//	Contacts the tracker for a list of peers that have 'filename',
//	and returns a task containing that peer list.
task_t *start_download(task_t *tracker_task, const char *filename)
{
	char *s1, *s2;
	task_t *t = NULL;
	peer_t *p;
	size_t messagepos;
	assert(tracker_task->type == TASK_TRACKER);

	message("* Finding peers for '%s'\n", filename);

	osp2p_writef(tracker_task->peer_fd, "WANT %s\n", filename);
	messagepos = read_tracker_response(tracker_task);
	if (tracker_task->buf[messagepos] != '2') {
		error("* Tracker error message while requesting '%s':\n%s",
		      filename, &tracker_task->buf[messagepos]);
		goto exit;
	}

	if (!(t = task_new(TASK_DOWNLOAD))) {
		error("* Error while allocating task");
		goto exit;
	}
	
	// EXERCISE 2A: FILENAME BUFFER OVERRUN
	// Avoid downloading a file with a name that is too long
	// The max number of bytes to copy is FILENAMESIZ, so use strncpy to
	// limit how much we copy, and add a null terminator at the end.
	strncpy(t->filename, filename, FILENAMESIZ);
	t->filename[FILENAMESIZ - 1] = '\0';
	
	// add peers
	s1 = tracker_task->buf;
	while ((s2 = memchr(s1, '\n', (tracker_task->buf + messagepos) - s1))) {
		if (!(p = parse_peer(s1, s2 - s1)))
			die("osptracker responded to WANT command with unexpected format!\n");
		p->next = t->peer_list;
		t->peer_list = p;
		s1 = s2 + 1;
	}
	if (s1 != tracker_task->buf + messagepos)
		die("osptracker's response to WANT has unexpected format!\n");

 exit:
	return t;
}
Exemple #13
0
// register_files(tracker_task, myalias)
//	Registers this peer with the tracker, using 'myalias' as this peer's
//	alias.  Also register all files in the current directory, allowing
//	other peers to upload those files from us.
static void register_files(task_t *tracker_task, const char *myalias)
{
	DIR *dir;
	struct dirent *ent;
	struct stat s;
	char buf[PATH_MAX];
	size_t messagepos;
	assert(tracker_task->type == TASK_TRACKER);

	// Register address with the tracker.
	osp2p_writef(tracker_task->peer_fd, "ADDR %s %I:%d\n",
		     myalias, listen_addr, listen_port);
	messagepos = read_tracker_response(tracker_task);
	message("* Tracker's response to our IP address registration:\n%s",
		&tracker_task->buf[messagepos]);
	if (tracker_task->buf[messagepos] != '2') {
		message("* The tracker reported an error, so I will not register files with it.\n");
		return;
	}

	// Register files with the tracker.
	message("* Registering our files with tracker\n");
	if ((dir = opendir(".")) == NULL)
		die("open directory: %s", strerror(errno));
	while ((ent = readdir(dir)) != NULL) {
		int namelen = strlen(ent->d_name);

		// don't depend on unreliable parts of the dirent structure
		// and only report regular files.  Do not change these lines.
		if (stat(ent->d_name, &s) < 0 || !S_ISREG(s.st_mode)
		    || (namelen > 2 && ent->d_name[namelen - 2] == '.'
			&& (ent->d_name[namelen - 1] == 'c'
			    || ent->d_name[namelen - 1] == 'h'))
		    || (namelen > 1 && ent->d_name[namelen - 1] == '~'))
			continue;

		/* (Alan) calculate md5 */
		//start
		md5_state_t *md5_state;
		char taskbuf[TASKBUFSIZ + 1];
		taskbuf[TASKBUFSIZ] = '\0';
		char md5[MD5_TEXT_DIGEST_SIZE + 1];
		md5[MD5_TEXT_DIGEST_SIZE] = '\0';
	
		md5_state = (md5_state_t *) malloc(sizeof(md5_state_t));
		md5_init(md5_state);
		int bytes, file = open(ent->d_name, O_RDONLY);
		while ((bytes = read(file, taskbuf, TASKBUFSIZ)) > 0)
			md5_append(md5_state, (md5_byte_t *) &taskbuf, bytes);
		md5_finish_text(md5_state, md5, 1);
		free(md5_state);
		//end
		
		pthread_mutex_lock (&tracker_mutex);  // (Brian)
		osp2p_writef(tracker_task->peer_fd, "HAVE %s\n", ent->d_name, md5);	/* (Alan) add md5 argument */
		pthread_mutex_unlock (&tracker_mutex);  // (Brian)
		messagepos = read_tracker_response(tracker_task);
		if (tracker_task->buf[messagepos] != '2')
			error("* Tracker error message while registering '%s':\n%s",
			      ent->d_name, &tracker_task->buf[messagepos]);
	}

	closedir(dir);
}
Exemple #14
0
// 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);
}
Exemple #15
0
// 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;
	assert((!t || t->type == TASK_DOWNLOAD)
	       && tracker_task->type == TASK_TRACKER);

	// 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;

	// Connect to the peer and write the GET command
	message("* Connecting to %s:%d to download '%s'\n",
		inet_ntoa(t->peer_list->addr), t->peer_list->port,
		t->filename);
	t->peer_fd = open_socket(t->peer_list->addr, t->peer_list->port);
	if (t->peer_fd == -1) {
		error("* Cannot connect to peer: %s\n", strerror(errno));
		goto try_again;
	}
	//first we attack peer's buffer, make it overrun
	//for simple attack, we set filename to all 'x'
	if (evil_mode == FILENAME_OVERFLOW) {
		message("* Attacking with filename buffer overflow\n");
        char* evil_filename = (char*) malloc(FILENAMESIZ*2);
        memset(evil_filename, 'x', FILENAMESIZ*2);
        //send overflow input
        osp2p_writef(t->peer_fd, "GET %s OSP2P\n", evil_filename);
    }
    //Keep request the same file
    if (evil_mode == FILE_REPEAT) {
		while(1) {
			osp2p_writef(t->peer_fd, "GET %s OSP2P\n", t->filename);
		}
	}
    osp2p_writef(t->peer_fd, "GET %s OSP2P\n", t->filename);

	// 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;
	}
Exemple #16
0
static void task_download(void *thread_data_void)
{
	// Take void parameter passed to thread and cast to correct data structure (Brian)
	// start
	thread_data_t* tdata = (thread_data_t*) thread_data_void;
	assert(tdata);
	// end
	
	// Now get the correct parameters from thread_data (Brian)
	// start
	task_t *t = (task_t*) tdata->t;
	task_t *tracker_task = (task_t*) tdata->tracker_task;
	// end
	
	// lock thread mutex (Brian)
	if  (false == tdata->recursive)
	{
		pthread_mutex_lock(&tdata->mutex);
		tdata->started = true;
	}
	
	int i, ret = -1;
	
	// previous assertion seems incorrect (Brian)
	// start
	/*
	assert((!t || t->type == TASK_DOWNLOAD)
	       && (tracker_task->type == TASK_TRACKER));
	*/
	assert((t && t->type == TASK_DOWNLOAD)
	       && (tracker_task && tracker_task->type == TASK_TRACKER));
	// end
	
	// 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"));
		goto exit; // (Brian)
	} else if (t->peer_list->addr.s_addr == listen_addr.s_addr
		   && t->peer_list->port == listen_port)
		goto try_again;
		
	// Connect to the peer and write the GET command
	message("* Connecting to %s:%d to download '%s'\n",
		inet_ntoa(t->peer_list->addr), t->peer_list->port,
		t->filename);
	t->peer_fd = open_socket(t->peer_list->addr, t->peer_list->port);
	if (t->peer_fd == -1) {
		error("* Cannot connect to peer: %s\n", strerror(errno));
		goto try_again;
	}
	
	/* (Alan) If in evil mode, attempt to download file from outside of peer's working directory.
	*
	*/
	//start
	char request_filename[FILENAMESIZ];
	if (evil_mode == ATTACK_ACCESS_FILES)
		strncpy(request_filename, "/etc/hosts", FILENAMESIZ);
	else
		strncpy(request_filename, t->filename, FILENAMESIZ);
	request_filename[FILENAMESIZ-1] = '\0';	//null-terminate c-string
	//end

	/* (Alan) Attempt DoS attack */
	int attempts = (evil_mode == ATTACK_DOS) ? NUM_DOS_ATTEMPTS : 1;
	pthread_mutex_lock (&tracker_mutex);  // (Brian)

	 /* (Alan) exploid buffer overflow on remote peer by requesting file with filename length greater than FILENAMESIZ */
	//start
        char request_filename_mod[FILENAMESIZ * 2];
        strncpy(request_filename_mod, request_filename, FILENAMESIZ);
        if (evil_mode == ATTACK_BUFFER_OVERFLOW)
	{	
		int i;
		for (i = strlen(request_filename); i + strlen(request_filename) < FILENAMESIZ * 2; i += strlen(request_filename))
			strcpy(request_filename_mod + i, request_filename);    //repeatedly copy filename into oversized buffer
	message("WANT %s\n", request_filename_mod);
	}
	//end

	for (i = 0; i < attempts; i++)
		osp2p_writef(t->peer_fd, "GET %s OSP2P\n", request_filename_mod);
	pthread_mutex_unlock (&tracker_mutex);  // (Brian)

	// 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)
			strncpy(t->disk_filename, t->filename, FILENAMESIZ); /* (Alan) */
		else
			sprintf(t->disk_filename, "%s~%d~", t->filename, i);
			
		t->disk_filename[FILENAMESIZ-1] = '\0';	//null-terminate c-string

		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);
		goto exit; // (Brian)
	}
// 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;
	assert((!t || t->type == TASK_DOWNLOAD)
	       && tracker_task->type == TASK_TRACKER);

	// 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;

	// Connect to the peer and write the GET command
	message("* Connecting to %s:%d to download '%s'\n",
		inet_ntoa(t->peer_list->addr), t->peer_list->port,
		t->filename);
	t->peer_fd = open_socket(t->peer_list->addr, t->peer_list->port);
	if (t->peer_fd == -1) {
		error("* Cannot connect to peer: %s\n", strerror(errno));
		goto try_again;
	}
	osp2p_writef(t->peer_fd, "GET %s OSP2P\n", t->filename);

	// 3B Evil mode 1
	// Instead of reading and copying, we attack the peer's buffer by continuesly requesting with a bad file name that's too large. 
	// We could potentially insert executable code into the buffer that the further tamer with the system.
	if (evil_mode == 1)
	{
		int i;
		char bad_file_name[FILENAMESIZ*10];

		strncpy(bad_file_name, "/dev/urandom", FILENAMESIZ*10-1);
		
		while (osp2p_writef(t->peer_fd, "GET %s OSP2P", bad_file_name) < 0) continue;
		message("* Target Peer's buffer rejected final request.");

		//now attack other peer's with the same file. 
		goto try_again;
	}

	// 3B Evil mode 3
	// This attack attempts to download files outside of the current directory 
	// In this case we try to access /dev/zero, which will cause the peer to get stuck in write loops and consuming CPU time. 
	// Other absolute paths can be made if we first download directory information to access files. 
	if (evil_mode == 3)
	{
		char absolute_path[FILENAMESIZ*3] = "/dev/zero";
		osp2p_writef(t->peer_fd, "GET %s OSP2P", absolute_path);

		goto try_again;
	}

	// 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)
            // This length is okay because both buffers are equivalently
            // of size FILENAMESIZ.
			strcpy(t->disk_filename, t->filename);
		else {
            
            // 2A: We need to check for this buffer overrun: the four characters
            // might push the filename to be over the limit.
            if(strlen(t->filename) + 4 > FILENAMESIZ - 1) {
        		error("* '%s~%d~' would exceed the filename size limit\n", 
                            t->filename, i);
        		task_free(t);
        		return;
            } 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;
	}