pacemaker 3.0.1-16e74fc4da
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
cib_secrets.c
Go to the documentation of this file.
1/*
2 * Copyright 2011-2025 the Pacemaker project contributors
3 *
4 * The version control history for this file may have further details.
5 *
6 * This source code is licensed under the GNU Lesser General Public License
7 * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8 */
9
10#include <crm_internal.h>
11
12#include <unistd.h>
13#include <stdlib.h>
14#include <stdio.h>
15#include <string.h>
16#include <ctype.h>
17#include <errno.h>
18#include <sys/types.h>
19#include <sys/stat.h>
20#include <time.h>
21
22#include <glib.h>
23
24#include <crm/common/util.h>
25
40static char *
41read_file_trimmed(const char *filename)
42{
43 char *p = NULL;
44 char *buf = NULL;
45 int rc = pcmk__file_contents(filename, &buf);
46
47 if (rc != pcmk_rc_ok) {
48 crm_err("Failed to read %s: %s", filename, pcmk_rc_str(rc));
49 free(buf);
50 return NULL;
51 }
52
53 if (buf == NULL) {
54 crm_err("File %s is empty", filename);
55 return NULL;
56 }
57
58 // Strip trailing white space
59 for (p = buf + strlen(buf) - 1; (p >= buf) && isspace(*p); p--);
60 *(p + 1) = '\0';
61
62 return buf;
63}
64
76static int
77validate_hash(const char *filename, const char *secret_value,
78 const char *rsc_id, const char *param)
79{
80 char *stored = NULL;
81 char *calculated = NULL;
82 int rc = pcmk_rc_ok;
83
84 stored = read_file_trimmed(filename);
85 if (stored == NULL) {
86 crm_err("Could not read md5 sum for resource %s parameter '%s' from "
87 "file '%s'",
88 rsc_id, param, filename);
89 rc = ENOENT;
90 goto done;
91 }
92
93 calculated = crm_md5sum(secret_value);
94 if (calculated == NULL) {
95 // Should be impossible
96 rc = EINVAL;
97 goto done;
98 }
99
100 crm_trace("Stored hash: %s, calculated hash: %s", stored, calculated);
101
102 if (!pcmk__str_eq(stored, calculated, pcmk__str_casei)) {
103 crm_err("Calculated md5 sum for resource %s parameter '%s' does not "
104 "match stored md5 sum",
105 rsc_id, param);
107 }
108
109done:
110 free(stored);
111 free(calculated);
112 return rc;
113}
114
128int
129pcmk__substitute_secrets(const char *rsc_id, GHashTable *params)
130{
131 GHashTableIter iter;
132 char *param = NULL;
133 char *value = NULL;
134 GString *filename = NULL;
135 gsize dir_len = 0;
136 int rc = pcmk_rc_ok;
137
138 if (params == NULL) {
139 return pcmk_rc_ok;
140 }
141
142 // Some params are sent with operations, so we cannot cache secret params
143 g_hash_table_iter_init(&iter, params);
144 while (g_hash_table_iter_next(&iter, (gpointer *) &param,
145 (gpointer *) &value)) {
146 char *secret_value = NULL;
147 int hash_rc = pcmk_rc_ok;
148
149 if (!pcmk__str_eq(value, "lrm://", pcmk__str_none)) {
150 // Not a secret parameter
151 continue;
152 }
153
154 if (filename == NULL) {
155 // First secret parameter. Fill in directory path for use with all.
156 crm_debug("Replacing secret parameters for resource %s", rsc_id);
157
158 filename = g_string_sized_new(128);
159 pcmk__g_strcat(filename, PCMK__CIB_SECRETS_DIR "/", rsc_id, "/",
160 NULL);
161 dir_len = filename->len;
162
163 } else {
164 // Reset filename to the resource's secrets directory path
165 g_string_truncate(filename, dir_len);
166 }
167
168 // Path to file containing secret value for this parameter
169 g_string_append(filename, param);
170 secret_value = read_file_trimmed(filename->str);
171 if (secret_value == NULL) {
172 crm_err("Secret value for resource %s parameter '%s' not found in "
173 PCMK__CIB_SECRETS_DIR,
174 rsc_id, param);
175 rc = ENOENT;
176 continue;
177 }
178
179 // Path to file containing md5 sum for this parameter
180 g_string_append(filename, ".sign");
181 hash_rc = validate_hash(filename->str, secret_value, rsc_id, param);
182 if (hash_rc != pcmk_rc_ok) {
183 rc = hash_rc;
184 free(secret_value);
185 continue;
186 }
187
188 g_hash_table_iter_replace(&iter, (gpointer) secret_value);
189 }
190
191 if (filename != NULL) {
192 g_string_free(filename, TRUE);
193 }
194 return rc;
195}
int pcmk__substitute_secrets(const char *rsc_id, GHashTable *params)
Utility functions.
char * crm_md5sum(const char *buffer)
Definition digest.c:251
int pcmk__file_contents(const char *filename, char **contents)
Definition io.c:426
#define crm_debug(fmt, args...)
Definition logging.h:368
#define crm_err(fmt, args...)
Definition logging.h:357
#define crm_trace(fmt, args...)
Definition logging.h:370
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code.
Definition results.c:617
@ pcmk_rc_ok
Definition results.h:159
@ pcmk_rc_cib_corrupt
Definition results.h:147
@ pcmk__str_none
@ pcmk__str_casei
void pcmk__g_strcat(GString *buffer,...) G_GNUC_NULL_TERMINATED
Definition strings.c:1299