1 /* Copyright (c) 2015-2018 Dovecot authors, see the included COPYING file */
2 #include "lib.h"
3 #include "str.h"
4 #include "array.h"
5 #include "settings-parser.h"
6 #include "master-service.h"
7 #include "master-service-settings.h"
8 #include "mail-crypt-common.h"
9 #include "mail-crypt-key.h"
10 #include "fs-crypt-settings.h"
11
12 static const struct fs_crypt_settings *
fs_crypt_load_settings(void)13 fs_crypt_load_settings(void)
14 {
15 static const struct setting_parser_info *set_roots[] = {
16 &fs_crypt_setting_parser_info,
17 NULL
18 };
19 struct master_service_settings_input input;
20 struct master_service_settings_output output;
21 const char *error;
22
23 i_zero(&input);
24 input.roots = set_roots;
25 input.module = "fs-crypt";
26 input.service = "fs-crypt";
27 if (master_service_settings_read(master_service, &input,
28 &output, &error) < 0)
29 i_fatal("Error reading configuration: %s", error);
30
31 return master_service_settings_get_others(master_service)[0];
32 }
33
34 static
mail_crypt_plugin_getenv(const struct fs_crypt_settings * set,const char * name)35 const char *mail_crypt_plugin_getenv(const struct fs_crypt_settings *set,
36 const char *name)
37 {
38 const char *const *envs;
39 unsigned int i, count;
40
41 if (set == NULL)
42 return NULL;
43
44 if (!array_is_created(&set->plugin_envs))
45 return NULL;
46
47 envs = array_get(&set->plugin_envs, &count);
48 for (i = 0; i < count; i += 2) {
49 if (strcmp(envs[i], name) == 0)
50 return envs[i+1];
51 }
52 return NULL;
53 }
54
55 static int
mail_crypt_load_global_private_keys(const struct fs_crypt_settings * set,const char * set_prefix,struct mail_crypt_global_keys * global_keys,const char ** error_r)56 mail_crypt_load_global_private_keys(const struct fs_crypt_settings *set,
57 const char *set_prefix,
58 struct mail_crypt_global_keys *global_keys,
59 const char **error_r)
60 {
61 string_t *set_key = t_str_new(64);
62 str_append(set_key, set_prefix);
63 str_append(set_key, "_private_key");
64 size_t prefix_len = str_len(set_key);
65
66 unsigned int i = 1;
67 const char *key_data;
68 while ((key_data = mail_crypt_plugin_getenv(set, str_c(set_key))) != NULL) {
69 const char *set_pw = t_strconcat(str_c(set_key), "_password", NULL);
70 const char *password = mail_crypt_plugin_getenv(set, set_pw);
71 if (mail_crypt_load_global_private_key(str_c(set_key), key_data,
72 set_pw, password,
73 global_keys, error_r) < 0)
74 return -1;
75 str_truncate(set_key, prefix_len);
76 str_printfa(set_key, "%u", ++i);
77 }
78 return 0;
79 }
80
mail_crypt_global_keys_load_pluginenv(const char * set_prefix,struct mail_crypt_global_keys * global_keys_r,const char ** error_r)81 int mail_crypt_global_keys_load_pluginenv(const char *set_prefix,
82 struct mail_crypt_global_keys *global_keys_r,
83 const char **error_r)
84 {
85 const struct fs_crypt_settings *set = fs_crypt_load_settings();
86
87 const char *set_key = t_strconcat(set_prefix, "_public_key", NULL);
88 const char *key_data = mail_crypt_plugin_getenv(set, set_key);
89 int ret = 0;
90
91 mail_crypt_global_keys_init(global_keys_r);
92 if (key_data != NULL) {
93 if (mail_crypt_load_global_public_key(set_key, key_data,
94 global_keys_r, error_r) < 0)
95 ret = -1;
96 }
97
98 if (ret == 0 &&
99 mail_crypt_load_global_private_keys(set, set_prefix, global_keys_r,
100 error_r) < 0)
101 ret = -1;
102
103 if (ret != 0)
104 mail_crypt_global_keys_free(global_keys_r);
105 return ret;
106 }
107