fs-crypt-common.c revision 4c78d9e646c4a1158d7167806937c02d86cdfc25
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi/* Copyright (c) 2015-2016 Dovecot authors, see the included COPYING file */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi/* defined outside this file */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomiint fs_crypt_load_keys(struct crypt_fs *fs, const char **error_r);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomifs_crypt_init(struct fs *_fs, const char *args, const
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const char *p, *arg, *value, *error, *parent_name, *parent_args;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const char *public_key_path = "", *private_key_path = "", *password = "";
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi /* [algo=<s>:][set_prefix=<n>:][public_key_path=<s>:]
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi [private_key_path=<s>:[password=<s>:]]<parent fs> */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (fs_init(parent_name, parent_args, set, &_fs->parent, &error) < 0) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi fs->public_key_path = i_strdup_empty(public_key_path);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi fs->private_key_path = i_strdup_empty(private_key_path);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic struct fs_file *
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomifs_crypt_file_init(struct fs *_fs, const char *path,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi /* avoid unnecessarily creating two seekable streams */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi file->file.parent = fs_file_init(_fs->parent, path, mode | flags);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi /* use async stream for super, so fs_read_stream() won't create
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi another seekable stream unneededly */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi file->super_read = fs_file_init(_fs->parent, path, mode | flags |
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic void fs_crypt_file_deinit(struct fs_file *_file)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct crypt_fs_file *file = (struct crypt_fs_file *)_file;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (file->super_read != _file->parent && file->super_read != NULL)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic void fs_crypt_file_close(struct fs_file *_file)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct crypt_fs_file *file = (struct crypt_fs_file *)_file;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic int fs_crypt_read_file(const char *set_name, const char *path,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi *error_r = t_strdup_printf("%s: read(%s) failed: %s",
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const unsigned char *data = i_stream_get_data(input, &size);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomifs_crypt_load_keys_from_path(struct crypt_fs *fs, const char **error_r)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (mail_crypt_load_global_public_key("crypt:public_key_path",
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (mail_crypt_load_global_private_key("crypt:private_key_path",
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomifs_crypt_istream_get_key(const char *pubkey_digest,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi *priv_key_r = mail_crypt_global_key_find(&file->fs->keys, pubkey_digest);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic struct istream *
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomifs_crypt_read_stream(struct fs_file *_file, size_t max_buffer_size)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct crypt_fs_file *file = (struct crypt_fs_file *)_file;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi input = fs_read_stream(file->super_read, max_buffer_size);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi file->input = i_stream_create_decrypt_callback(input,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic void fs_crypt_write_stream(struct fs_file *_file)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct crypt_fs_file *file = (struct crypt_fs_file *)_file;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const char *error;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi "NOT encrypting stream %s",
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi file->super_output = fs_write_stream(_file->parent);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi iostream_temp_create_named(_file->fs->temp_path_prefix,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi _file->output = o_stream_create_encrypt(file->temp_output,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic int fs_crypt_write_stream_finish(struct fs_file *_file, bool success)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct crypt_fs_file *file = (struct crypt_fs_file *)_file;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi /* no encryption */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi fs_write_stream_abort_error(_file->parent, &file->super_output,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi "write(%s) failed: %s",
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi /* no encrypt */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return fs_write_stream_finish(_file->parent, &file->super_output);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi /* finishing up */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return fs_write_stream_finish_async(_file->parent);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi /* finish writing the temporary file */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi input = iostream_temp_finish(&file->temp_output, IO_BLOCK_SIZE);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi file->super_output = fs_write_stream(_file->parent);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi o_stream_nsend_istream(file->super_output, input);