Esempio n. 1
0
File: files.c Progetto: Schala/mhxd
void
rcv_file_hash (struct htlc_conn *htlc)
{
	u_int16_t fnlen = 0;
	char dir[MAXPATHLEN], filename[NAME_MAX], pathbuf[MAXPATHLEN];
	int err;
	int fd;
	u_int32_t data_len = 0, rsrc_len = 0;
	u_int16_t haval_len = 16, haval_passes = 3, hash_types = 0;
	u_int8_t md5[32], haval[64], sha1[40];
	u_int16_t md5len, sha1len;
#if defined(CONFIG_HFS)
	int rfd;
	off_t off = -1; /* keep gcc happy */
#endif

	dir[0] = 0;

	dh_start(htlc)
		switch (dh_type) {
			case HTLC_DATA_FILE_NAME:
				fnlen = dh_len > NAME_MAX ? NAME_MAX - 1 : dh_len;
				read_filename(filename, dh_data, fnlen);
				break;
			case HTLC_DATA_DIR:
				if ((err = hldir_to_path(dh, ROOTDIR, dir, dir))) {
					snd_strerror(htlc, err);
					return;
				}
				break;
			case HTLC_DATA_RFLT:
				if (dh_len >= 50)
					L32NTOH(data_len, &dh_data[46]);
				if (dh_len >= 66)
					L32NTOH(rsrc_len, &dh_data[62]);
				break;
			case HTLC_DATA_HASH_MD5:
				hash_types |= 0x01;
				break;
			case HTLC_DATA_HASH_HAVAL:
				hash_types |= 0x02;
				if (dh_len == 2) {
					haval_len = dh_data[0];
					haval_passes = dh_data[1];
				}
				if (haval_len > 32)
					haval_len = 32;
				if (haval_passes < 3)
					haval_passes = 3;
				if (haval_passes > 5)
					haval_passes = 5;
				break;
			case HTLC_DATA_HASH_SHA1:
				hash_types |= 0x04;
				break;
		}
	dh_end()

	if (!fnlen && !dir[0]) {
		hlwrite(htlc, HTLS_HDR_TASK, 1, 1, HTLS_DATA_TASKERROR, 6, "huh?!?");
		return;
	}
	if (dir[0]) {
		if (fnlen)
			snprintf(pathbuf, sizeof(pathbuf), "%s/%s", dir, filename);
		else
			strcpy(pathbuf, dir);
	} else {
		snprintf(pathbuf, sizeof(pathbuf), "%s/%s", ROOTDIR, filename);
	}
	if (check_dropbox(htlc, pathbuf)) {
		snd_strerror(htlc, EPERM);
		return;
	}

	if (log_hash)
		hxd_log("%s:%s:%u - hash %s", htlc->name, htlc->login, htlc->uid, pathbuf);

	fd = SYS_open(pathbuf, O_RDONLY, 0);
	if (fd < 0) {
		snd_strerror(htlc, errno);
		return;
	}
#if defined(CONFIG_HFS)
	if (hxd_cfg.operation.hfs) {
		rfd = resource_open(pathbuf, O_RDONLY, 0);
		if (rfd >= 0) {
			off = lseek(rfd, 0, SEEK_CUR);
			if (off == (off_t)-1) {
				close(rfd);
				rfd = -1;
			}
		}
	} else {
		rfd = -1;
	}
#endif
	if (hash_types & 0x01) {
		memset(md5, 0, 32);
		md5_fd(fd, data_len, &md5[0]);
#if defined(CONFIG_HFS)
		if (rfd >= 0)
			md5_fd(rfd, rsrc_len, &md5[16]);
#endif
	}
	if (hash_types & 0x02) {
		memset(haval, 0, haval_len * 2);
		lseek(fd, 0, SEEK_SET);
		haval_fd(fd, data_len, &haval[0], haval_len * 8, haval_passes);
#if defined(CONFIG_HFS)
		if (rfd >= 0) {
			lseek(rfd, off, SEEK_SET);
			haval_fd(rfd, rsrc_len, &haval[haval_len], haval_len * 8, haval_passes);
		}
#endif
	}
	if (hash_types & 0x04) {
		memset(sha1, 0, 40);
		lseek(fd, 0, SEEK_SET);
		sha_fd(fd, data_len, &sha1[0]);
#if defined(CONFIG_HFS)
		if (rfd >= 0) {
			lseek(rfd, off, SEEK_SET);
			sha_fd(rfd, rsrc_len, &sha1[20]);
		}
#endif
	}
#if defined(CONFIG_HFS)
	if (rfd >= 0)
		close(rfd);
#endif
	close(fd);

	md5len = 16;
	sha1len = 20;
#if defined(CONFIG_HFS)
	if (hxd_cfg.operation.hfs) {
		md5len = 32;
		haval_len *= 2;
		sha1len = 40;
	}
#endif
	hlwrite(htlc, HTLS_HDR_TASK, 0, 3,
		HTLS_DATA_HASH_MD5, md5len, md5,
		HTLS_DATA_HASH_HAVAL, haval_len, haval,
		HTLS_DATA_HASH_SHA1, sha1len, sha1);
}
Esempio n. 2
0
char *md5_file(int dirfd, char *filename)
{
    _cleanup_close_ int fd = openat(dirfd, filename, O_RDONLY);
    return md5_fd(fd);
}