Exemplo n.º 1
0
/**
 * ntfs_cat_decrypt - Decrypt the contents of an encrypted file to stdout.
 * @inode:	An encrypted file's inode structure, as obtained by
 * 		ntfs_inode_open().
 * @fek:	A file encryption key. As obtained by ntfs_inode_fek_get().
 */
static int ntfs_cat_decrypt(ntfs_inode *inode, ntfs_fek *fek)
{
    int bufsize = 512;
    unsigned char *buffer;
    ntfs_attr *attr;
    s64 bytes_read, written, offset, total;
    s64 old_data_size, old_initialized_size;
    int i;

    buffer = malloc(bufsize);
    if (!buffer)
        return 1;
    attr = ntfs_attr_open(inode, AT_DATA, NULL, 0);
    if (!attr) {
        ntfs_log_error("Cannot cat a directory.\n");
        free(buffer);
        return 1;
    }
    total = attr->data_size;

    // hack: make sure attr will not be commited to disk if you use this.
    // clear the encrypted bit, otherwise the library won't allow reading.
    NAttrClearEncrypted(attr);
    // extend the size, we may need to read past the end of the stream.
    old_data_size = attr->data_size;
    old_initialized_size = attr->initialized_size;
    attr->data_size = attr->initialized_size = attr->allocated_size;

    offset = 0;
    while (total > 0) {
        bytes_read = ntfs_attr_pread(attr, offset, 512, buffer);
        if (bytes_read == -1) {
            ntfs_log_perror("ERROR: Couldn't read file");
            break;
        }
        if (!bytes_read)
            break;
        if ((i = ntfs_fek_decrypt_sector(fek, buffer, offset)) <
                bytes_read) {
            ntfs_log_perror("ERROR: Couldn't decrypt all data!");
            ntfs_log_error("%u/%lld/%lld/%lld\n", i,
                           (long long)bytes_read, (long long)offset,
                           (long long)total);
            break;
        }
        if (bytes_read > total)
            bytes_read = total;
        written = fwrite(buffer, 1, bytes_read, stdout);
        if (written != bytes_read) {
            ntfs_log_perror("ERROR: Couldn't output all data!");
            break;
        }
        offset += bytes_read;
        total -= bytes_read;
    }
    attr->data_size = old_data_size;
    attr->initialized_size = old_initialized_size;
    NAttrSetEncrypted(attr);
    ntfs_attr_close(attr);
    free(buffer);
    return 0;
}
Exemplo n.º 2
0
/**
 * ntfs_feed_encrypt - Encrypt the contents of stdin to an encrypted file
 * @inode:	An encrypted file's inode structure, as obtained by
 * 		ntfs_inode_open().
 * @fek:	A file encryption key. As obtained by ntfs_inode_fek_get().
 */
static int ntfs_feed_encrypt(ntfs_inode *inode, ntfs_fek *fek)
{
	const int bufsize = 512;
	unsigned char *buffer;
	ntfs_attr *attr;
	s64 bytes_read, written, offset, total;
	unsigned char *b;
	long val;
	int count;
	int i;

	buffer = (unsigned char*)malloc(bufsize);
	if (!buffer)
		return 1;
	attr = ntfs_attr_open(inode, AT_DATA, NULL, 0);
	if (!attr) {
		ntfs_log_error("Cannot feed into a directory.\n");
		goto rejected;
	}
	total = 0;

	if (!(attr->data_flags & ATTR_IS_ENCRYPTED)) {
		ntfs_log_error("The data stream was not encrypted\n");
		goto rejected;
	}
	inode->vol->efs_raw = TRUE;

	if (ntfs_attr_truncate(attr, 0)) {
		ntfs_log_error("Failed to truncate the data stream\n");
		goto rejected;
	}
	offset = 0;
	do {
		bytes_read = fread(buffer, 1, bufsize, stdin);
		if (bytes_read <= 0) {
			if (bytes_read < 0)
				ntfs_log_perror("ERROR: Couldn't read data");
		} else {
			if (bytes_read < bufsize) {
				/* Fill with random data */
				srandom((unsigned int)(sle64_to_cpu(
					inode->last_data_change_time)
					/100000000));
				count = bufsize - bytes_read;
				b = &buffer[bytes_read];
				do {
					val = random();
					switch (count) {
						default :
							*b++ = val;
							val >>= 8;
						case 3 :
							*b++ = val;
							val >>= 8;
						case 2 :
							*b++ = val;
							val >>= 8;
						case 1 :
							*b++ = val;
							val >>= 8;
					}
					count -= 4;
				} while (count > 0);
			}
			if ((i = ntfs_fek_encrypt_sector(fek, buffer, offset))
					< bufsize) {
				ntfs_log_perror("ERROR: Couldn't encrypt all data!");
				ntfs_log_error("%u/%lld/%lld/%lld\n", i,
					(long long)bytes_read, (long long)offset,
					(long long)total);
				break;
			}
		written = ntfs_attr_pwrite(attr, offset, bufsize, buffer);
		if (written != bufsize) {
			ntfs_log_perror("ERROR: Couldn't output all data!");
			break;
		}
		offset += bufsize;
		total += bytes_read;
		}
	} while (bytes_read == bufsize);
	ntfs_attr_truncate(attr, total);
	inode->last_data_change_time = ntfs_current_time();
	NAttrSetEncrypted(attr);
	ntfs_attr_close(attr);
	free(buffer);
	return 0;
rejected :
	free(buffer);
	return (-1);
}