This source file includes following definitions.
- is_magic_value
- check_md5_hash
- read_local_file
- replace_secret_params
- do_replace_secret_params
- add_secret_params
1
2
3
4
5
6
7
8
9 #include <crm_internal.h>
10
11 #include <unistd.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <ctype.h>
16 #include <errno.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <time.h>
20
21 #include <glib.h>
22
23 #include <crm/common/util.h>
24 #include <crm/common/cib_secrets.h>
25
26 static int do_replace_secret_params(char *rsc_id, GHashTable *params, gboolean from_legacy_dir);
27 static int is_magic_value(char *p);
28 static int check_md5_hash(char *hash, char *value);
29 static void add_secret_params(gpointer key, gpointer value, gpointer user_data);
30 static char *read_local_file(char *local_file);
31
32 #define MAX_VALUE_LEN 255
33 #define MAGIC "lrm://"
34
35 static int
36 is_magic_value(char *p)
37 {
38 return !strcmp(p, MAGIC);
39 }
40
41 static int
42 check_md5_hash(char *hash, char *value)
43 {
44 int rc = FALSE;
45 char *hash2 = NULL;
46
47 hash2 = crm_md5sum(value);
48 crm_debug("hash: %s, calculated hash: %s", hash, hash2);
49 if (safe_str_eq(hash, hash2)) {
50 rc = TRUE;
51 }
52
53 free(hash2);
54 return rc;
55 }
56
57 static char *
58 read_local_file(char *local_file)
59 {
60 FILE *fp = fopen(local_file, "r");
61 char buf[MAX_VALUE_LEN+1];
62 char *p;
63
64 if (!fp) {
65 if (errno != ENOENT) {
66 crm_perror(LOG_ERR, "cannot open %s" , local_file);
67 }
68 return NULL;
69 }
70
71 if (!fgets(buf, MAX_VALUE_LEN, fp)) {
72 crm_perror(LOG_ERR, "cannot read %s", local_file);
73 return NULL;
74 }
75
76
77 for (p = buf+strlen(buf)-1; p >= buf && isspace(*p); p--)
78 ;
79 *(p+1) = '\0';
80 return strdup(buf);
81 }
82
83
84
85
86
87
88 int
89 replace_secret_params(char *rsc_id, GHashTable *params)
90 {
91 if (do_replace_secret_params(rsc_id, params, FALSE) < 0
92 && do_replace_secret_params(rsc_id, params, TRUE) < 0) {
93 return -1;
94 }
95
96 return 0;
97 }
98
99 static int
100 do_replace_secret_params(char *rsc_id, GHashTable *params, gboolean from_legacy_dir)
101 {
102 char local_file[FILENAME_MAX+1], *start_pname;
103 char hash_file[FILENAME_MAX+1], *hash;
104 GList *secret_params = NULL, *l;
105 char *key, *pvalue, *secret_value;
106 int rc = 0;
107 const char *dir_prefix = NULL;
108
109 if (params == NULL) {
110 return 0;
111 }
112
113 if (from_legacy_dir) {
114 dir_prefix = LRM_LEGACY_CIBSECRETS_DIR;
115
116 } else {
117 dir_prefix = LRM_CIBSECRETS_DIR;
118 }
119
120
121
122
123
124 g_hash_table_foreach(params, add_secret_params, &secret_params);
125 if (!secret_params) {
126 return 0;
127 }
128
129 crm_debug("replace secret parameters for resource %s", rsc_id);
130
131 if (snprintf(local_file, FILENAME_MAX,
132 "%s/%s/", dir_prefix, rsc_id) > FILENAME_MAX) {
133 crm_err("filename size exceeded for resource %s", rsc_id);
134 return -1;
135 }
136 start_pname = local_file + strlen(local_file);
137
138 for (l = g_list_first(secret_params); l; l = g_list_next(l)) {
139 key = (char *)(l->data);
140 pvalue = g_hash_table_lookup(params, key);
141 if (!pvalue) {
142 crm_err("odd, no parameter %s for rsc %s found now", key, rsc_id);
143 continue;
144 }
145
146 if ((strlen(key) + strlen(local_file)) >= FILENAME_MAX-2) {
147 crm_err("%d: parameter name %s too big", key);
148 rc = -1;
149 continue;
150 }
151
152 strcpy(start_pname, key);
153 secret_value = read_local_file(local_file);
154 if (!secret_value) {
155 if (from_legacy_dir == FALSE) {
156 crm_debug("secret for rsc %s parameter %s not found in %s. "
157 "will try "LRM_LEGACY_CIBSECRETS_DIR, rsc_id, key, dir_prefix);
158
159 } else {
160 crm_err("secret for rsc %s parameter %s not found in %s",
161 rsc_id, key, dir_prefix);
162 }
163 rc = -1;
164 continue;
165 }
166
167 strcpy(hash_file, local_file);
168 if (strlen(hash_file) + 5 > FILENAME_MAX) {
169 crm_err("cannot build such a long name "
170 "for the sign file: %s.sign", hash_file);
171 free(secret_value);
172 rc = -1;
173 continue;
174
175 } else {
176 strncat(hash_file, ".sign", 5);
177 hash = read_local_file(hash_file);
178 if (hash == NULL) {
179 crm_err("md5 sum for rsc %s parameter %s "
180 "cannot be read from %s", rsc_id, key, hash_file);
181 free(secret_value);
182 rc = -1;
183 continue;
184
185 } else if (!check_md5_hash(hash, secret_value)) {
186 crm_err("md5 sum for rsc %s parameter %s "
187 "does not match", rsc_id, key);
188 free(secret_value);
189 free(hash);
190 rc = -1;
191 continue;
192 }
193 free(hash);
194 }
195 g_hash_table_replace(params, strdup(key), secret_value);
196 }
197 g_list_free(secret_params);
198 return rc;
199 }
200
201 static void
202 add_secret_params(gpointer key, gpointer value, gpointer user_data)
203 {
204 GList **lp = (GList **)user_data;
205
206 if (is_magic_value((char *)value)) {
207 *lp = g_list_append(*lp, (char *)key);
208 }
209 }