bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2015-2018 Dovecot authors, see the included COPYING file */
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "lib.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "str.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "array.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "settings-parser.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "master-service.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "master-service-settings.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "mail-crypt-common.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "mail-crypt-key.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi#include "fs-crypt-settings.h"
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic const struct fs_crypt_settings *
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomifs_crypt_load_settings(void)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi{
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi static const struct setting_parser_info *set_roots[] = {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi &fs_crypt_setting_parser_info,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi NULL
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi };
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct master_service_settings_input input;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct master_service_settings_output output;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const char *error;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&input);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi input.roots = set_roots;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi input.module = "fs-crypt";
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi input.service = "fs-crypt";
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (master_service_settings_read(master_service, &input,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi &output, &error) < 0)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi i_fatal("Error reading configuration: %s", error);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return master_service_settings_get_others(master_service)[0];
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi}
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomiconst char *mail_crypt_plugin_getenv(const struct fs_crypt_settings *set,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const char *name)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi{
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const char *const *envs;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi unsigned int i, count;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (set == NULL)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return NULL;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (!array_is_created(&set->plugin_envs))
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return NULL;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi envs = array_get(&set->plugin_envs, &count);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi for (i = 0; i < count; i += 2) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (strcmp(envs[i], name) == 0)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return envs[i+1];
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return NULL;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi}
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomistatic int
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomimail_crypt_load_global_private_keys(const struct fs_crypt_settings *set,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const char *set_prefix,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mail_crypt_global_keys *global_keys,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const char **error_r)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi{
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi string_t *set_key = t_str_new(64);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi str_append(set_key, set_prefix);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi str_append(set_key, "_private_key");
2ac5f36aa7c2e7a07ba8815d43a6d7483f62e74cTimo Sirainen size_t prefix_len = str_len(set_key);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi unsigned int i = 1;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const char *key_data;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi while ((key_data = mail_crypt_plugin_getenv(set, str_c(set_key))) != NULL) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const char *set_pw = t_strconcat(str_c(set_key), "_password", NULL);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const char *password = mail_crypt_plugin_getenv(set, set_pw);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (mail_crypt_load_global_private_key(str_c(set_key), key_data,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi set_pw, password,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi global_keys, error_r) < 0)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return -1;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi str_truncate(set_key, prefix_len);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi str_printfa(set_key, "%u", ++i);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return 0;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi}
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomiint mail_crypt_global_keys_load_pluginenv(const char *set_prefix,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi struct mail_crypt_global_keys *global_keys_r,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const char **error_r)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi{
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const struct fs_crypt_settings *set = fs_crypt_load_settings();
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const char *set_key = t_strconcat(set_prefix, "_public_key", NULL);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi const char *key_data = mail_crypt_plugin_getenv(set, set_key);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi int ret = 0;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mail_crypt_global_keys_init(global_keys_r);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (key_data != NULL) {
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (mail_crypt_load_global_public_key(set_key, key_data,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi global_keys_r, error_r) < 0)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi ret = -1;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi }
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi if (ret == 0 &&
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi mail_crypt_load_global_private_keys(set, set_prefix, global_keys_r,
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi error_r) < 0)
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi ret = -1;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi
abd2ac9eb17f620557716af62434c4c751d7c819Aki Tuomi if (ret != 0)
abd2ac9eb17f620557716af62434c4c751d7c819Aki Tuomi mail_crypt_global_keys_free(global_keys_r);
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi return ret;
4c78d9e646c4a1158d7167806937c02d86cdfc25Aki Tuomi}