예제 #1
0
int do_unpack(void)
{
	struct file_header untrusted_hdr;
#ifdef HAVE_SYNCFS
	int cwd_fd;
	int saved_errno;
#endif

	total_bytes = total_files = 0;
	/* initialize checksum */
	crc32_sum = 0;
	while (read_all_with_crc(0, &untrusted_hdr, sizeof untrusted_hdr)) {
		/* check for end of transfer marker */
		if (untrusted_hdr.namelen == 0) {
			errno = 0;
			break;
		}
		total_files++;
		if (files_limit && total_files > files_limit)
			do_exit(EDQUOT, untrusted_namebuf);
		process_one_file(&untrusted_hdr);
	}

#ifdef HAVE_SYNCFS
	saved_errno = errno;
	cwd_fd = open(".", O_RDONLY);
	if (cwd_fd >= 0 && syncfs(cwd_fd) == 0 && close(cwd_fd) == 0)
		errno = saved_errno;
#endif

	send_status_and_crc(errno, untrusted_namebuf);
	return errno;
}
예제 #2
0
void process_one_file_link(struct file_header *untrusted_hdr,
			   const char *untrusted_name)
{
	char untrusted_content[MAX_PATH_LENGTH];
	unsigned int filelen;
	if (untrusted_hdr->filelen > MAX_PATH_LENGTH - 1)
		do_exit(ENAMETOOLONG, untrusted_name);
	filelen = untrusted_hdr->filelen;	/* sanitized above */
	total_bytes += filelen;
	if (bytes_limit && total_bytes > bytes_limit)
		do_exit(EDQUOT, untrusted_name);
	if (!read_all_with_crc(0, untrusted_content, filelen))
		do_exit(LEGAL_EOF, untrusted_name);	// hopefully remote has produced error message
	untrusted_content[filelen] = 0;
	if (symlink(untrusted_content, untrusted_name))	/* safe because of chroot */
		do_exit(errno, untrusted_name);

}
예제 #3
0
void process_one_file(struct file_header *untrusted_hdr)
{
	unsigned int namelen;
	if (untrusted_hdr->namelen > MAX_PATH_LENGTH - 1)
		do_exit(ENAMETOOLONG, NULL); /* filename too long so not received at all */
	namelen = untrusted_hdr->namelen;	/* sanitized above */
	if (!read_all_with_crc(0, untrusted_namebuf, namelen))
		do_exit(LEGAL_EOF, NULL);	// hopefully remote has produced error message
	untrusted_namebuf[namelen] = 0;
	if (S_ISREG(untrusted_hdr->mode))
		process_one_file_reg(untrusted_hdr, untrusted_namebuf);
	else if (S_ISLNK(untrusted_hdr->mode))
		process_one_file_link(untrusted_hdr, untrusted_namebuf);
	else if (S_ISDIR(untrusted_hdr->mode))
		process_one_file_dir(untrusted_hdr, untrusted_namebuf);
	else
		do_exit(EINVAL, untrusted_namebuf);
	if (verbose && !S_ISDIR(untrusted_hdr->mode))
		fprintf(stderr, "%s\n", untrusted_namebuf);
}
예제 #4
0
int do_unpack(void)
{
	struct file_header untrusted_hdr;
	total_bytes = total_files = 0;
	/* initialize checksum */
	crc32_sum = 0;
	while (read_all_with_crc(0, &untrusted_hdr, sizeof untrusted_hdr)) {
		/* check for end of transfer marker */
		if (untrusted_hdr.namelen == 0) {
			errno = 0;
			break;
		}
		total_files++;
		if (files_limit && total_files > files_limit)
			do_exit(EDQUOT, untrusted_namebuf);
		process_one_file(&untrusted_hdr);
	}
	send_status_and_crc(errno, untrusted_namebuf);
	return errno;
}