1*8617a60dSAndroid Build Coastguard Worker /* Copyright 2022 The ChromiumOS Authors
2*8617a60dSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
3*8617a60dSAndroid Build Coastguard Worker * found in the LICENSE file.
4*8617a60dSAndroid Build Coastguard Worker */
5*8617a60dSAndroid Build Coastguard Worker
6*8617a60dSAndroid Build Coastguard Worker #include "2common.h"
7*8617a60dSAndroid Build Coastguard Worker #include "2crypto.h"
8*8617a60dSAndroid Build Coastguard Worker #include "2return_codes.h"
9*8617a60dSAndroid Build Coastguard Worker #include "cbfstool.h"
10*8617a60dSAndroid Build Coastguard Worker #include "host_misc.h"
11*8617a60dSAndroid Build Coastguard Worker #include "subprocess.h"
12*8617a60dSAndroid Build Coastguard Worker #include "vboot_host.h"
13*8617a60dSAndroid Build Coastguard Worker
14*8617a60dSAndroid Build Coastguard Worker #define ARGV_END(region) region ? "-r" : NULL, region, NULL,
15*8617a60dSAndroid Build Coastguard Worker
get_cbfstool_path(void)16*8617a60dSAndroid Build Coastguard Worker static const char *get_cbfstool_path(void)
17*8617a60dSAndroid Build Coastguard Worker {
18*8617a60dSAndroid Build Coastguard Worker static const char *cbfstool = NULL;
19*8617a60dSAndroid Build Coastguard Worker
20*8617a60dSAndroid Build Coastguard Worker if (cbfstool)
21*8617a60dSAndroid Build Coastguard Worker return cbfstool;
22*8617a60dSAndroid Build Coastguard Worker
23*8617a60dSAndroid Build Coastguard Worker const char *env_cbfstool = getenv(ENV_CBFSTOOL);
24*8617a60dSAndroid Build Coastguard Worker if (env_cbfstool && env_cbfstool[0] != '\0') {
25*8617a60dSAndroid Build Coastguard Worker cbfstool = strdup(env_cbfstool);
26*8617a60dSAndroid Build Coastguard Worker return cbfstool;
27*8617a60dSAndroid Build Coastguard Worker }
28*8617a60dSAndroid Build Coastguard Worker
29*8617a60dSAndroid Build Coastguard Worker cbfstool = DEFAULT_CBFSTOOL;
30*8617a60dSAndroid Build Coastguard Worker return cbfstool;
31*8617a60dSAndroid Build Coastguard Worker }
32*8617a60dSAndroid Build Coastguard Worker
find_cbfs_file(const char * buf,const char * name)33*8617a60dSAndroid Build Coastguard Worker static bool find_cbfs_file(const char *buf, const char *name)
34*8617a60dSAndroid Build Coastguard Worker {
35*8617a60dSAndroid Build Coastguard Worker char *to_find = NULL;
36*8617a60dSAndroid Build Coastguard Worker if (asprintf(&to_find, "\n%s\t", name) < 0) {
37*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Out of Memory\n");
38*8617a60dSAndroid Build Coastguard Worker exit(1);
39*8617a60dSAndroid Build Coastguard Worker }
40*8617a60dSAndroid Build Coastguard Worker
41*8617a60dSAndroid Build Coastguard Worker const char *start = strstr(buf, to_find);
42*8617a60dSAndroid Build Coastguard Worker
43*8617a60dSAndroid Build Coastguard Worker free(to_find);
44*8617a60dSAndroid Build Coastguard Worker return !!start;
45*8617a60dSAndroid Build Coastguard Worker }
46*8617a60dSAndroid Build Coastguard Worker
cbfstool_file_exists(const char * image_file,const char * region,const char * name)47*8617a60dSAndroid Build Coastguard Worker bool cbfstool_file_exists(const char *image_file, const char *region,
48*8617a60dSAndroid Build Coastguard Worker const char *name)
49*8617a60dSAndroid Build Coastguard Worker {
50*8617a60dSAndroid Build Coastguard Worker int status;
51*8617a60dSAndroid Build Coastguard Worker char *buffer;
52*8617a60dSAndroid Build Coastguard Worker const size_t buffer_size = 1024 * 128;
53*8617a60dSAndroid Build Coastguard Worker const char *cbfstool = get_cbfstool_path();
54*8617a60dSAndroid Build Coastguard Worker bool res = false;
55*8617a60dSAndroid Build Coastguard Worker
56*8617a60dSAndroid Build Coastguard Worker buffer = malloc(buffer_size);
57*8617a60dSAndroid Build Coastguard Worker if (!buffer)
58*8617a60dSAndroid Build Coastguard Worker goto done;
59*8617a60dSAndroid Build Coastguard Worker
60*8617a60dSAndroid Build Coastguard Worker struct subprocess_target output = {
61*8617a60dSAndroid Build Coastguard Worker .type = TARGET_BUFFER_NULL_TERMINATED,
62*8617a60dSAndroid Build Coastguard Worker .buffer = {
63*8617a60dSAndroid Build Coastguard Worker .buf = buffer,
64*8617a60dSAndroid Build Coastguard Worker .size = buffer_size,
65*8617a60dSAndroid Build Coastguard Worker },
66*8617a60dSAndroid Build Coastguard Worker };
67*8617a60dSAndroid Build Coastguard Worker const char *const argv[] = {
68*8617a60dSAndroid Build Coastguard Worker cbfstool, image_file, "print", "-k", ARGV_END(region)
69*8617a60dSAndroid Build Coastguard Worker };
70*8617a60dSAndroid Build Coastguard Worker
71*8617a60dSAndroid Build Coastguard Worker status = subprocess_run(argv, &subprocess_null, &output,
72*8617a60dSAndroid Build Coastguard Worker &subprocess_null);
73*8617a60dSAndroid Build Coastguard Worker if (status < 0) {
74*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "%s(): cbfstool invocation failed: %m\n",
75*8617a60dSAndroid Build Coastguard Worker __func__);
76*8617a60dSAndroid Build Coastguard Worker exit(1);
77*8617a60dSAndroid Build Coastguard Worker }
78*8617a60dSAndroid Build Coastguard Worker if (status > 0)
79*8617a60dSAndroid Build Coastguard Worker goto done;
80*8617a60dSAndroid Build Coastguard Worker
81*8617a60dSAndroid Build Coastguard Worker res = find_cbfs_file(buffer, name);
82*8617a60dSAndroid Build Coastguard Worker
83*8617a60dSAndroid Build Coastguard Worker done:
84*8617a60dSAndroid Build Coastguard Worker free(buffer);
85*8617a60dSAndroid Build Coastguard Worker return res;
86*8617a60dSAndroid Build Coastguard Worker }
87*8617a60dSAndroid Build Coastguard Worker
cbfstool_extract(const char * image_file,const char * region,const char * name,const char * file)88*8617a60dSAndroid Build Coastguard Worker int cbfstool_extract(const char *image_file, const char *region,
89*8617a60dSAndroid Build Coastguard Worker const char *name, const char *file)
90*8617a60dSAndroid Build Coastguard Worker {
91*8617a60dSAndroid Build Coastguard Worker int status;
92*8617a60dSAndroid Build Coastguard Worker const char *cbfstool = get_cbfstool_path();
93*8617a60dSAndroid Build Coastguard Worker
94*8617a60dSAndroid Build Coastguard Worker const char *const argv[] = {
95*8617a60dSAndroid Build Coastguard Worker cbfstool, image_file, "extract", "-n", name, "-f", file,
96*8617a60dSAndroid Build Coastguard Worker ARGV_END(region)
97*8617a60dSAndroid Build Coastguard Worker };
98*8617a60dSAndroid Build Coastguard Worker
99*8617a60dSAndroid Build Coastguard Worker status = subprocess_run(argv, &subprocess_null, &subprocess_null,
100*8617a60dSAndroid Build Coastguard Worker &subprocess_null);
101*8617a60dSAndroid Build Coastguard Worker if (status < 0) {
102*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "%s(): cbfstool invocation failed: %m\n",
103*8617a60dSAndroid Build Coastguard Worker __func__);
104*8617a60dSAndroid Build Coastguard Worker exit(1);
105*8617a60dSAndroid Build Coastguard Worker }
106*8617a60dSAndroid Build Coastguard Worker
107*8617a60dSAndroid Build Coastguard Worker return status;
108*8617a60dSAndroid Build Coastguard Worker }
109*8617a60dSAndroid Build Coastguard Worker
cbfstool_truncate(const char * file,const char * region,size_t * new_size)110*8617a60dSAndroid Build Coastguard Worker vb2_error_t cbfstool_truncate(const char *file, const char *region,
111*8617a60dSAndroid Build Coastguard Worker size_t *new_size)
112*8617a60dSAndroid Build Coastguard Worker {
113*8617a60dSAndroid Build Coastguard Worker int status;
114*8617a60dSAndroid Build Coastguard Worker char output_buffer[128];
115*8617a60dSAndroid Build Coastguard Worker const char *cbfstool = get_cbfstool_path();
116*8617a60dSAndroid Build Coastguard Worker
117*8617a60dSAndroid Build Coastguard Worker struct subprocess_target output = {
118*8617a60dSAndroid Build Coastguard Worker .type = TARGET_BUFFER_NULL_TERMINATED,
119*8617a60dSAndroid Build Coastguard Worker .buffer = {
120*8617a60dSAndroid Build Coastguard Worker .buf = output_buffer,
121*8617a60dSAndroid Build Coastguard Worker .size = sizeof(output_buffer),
122*8617a60dSAndroid Build Coastguard Worker },
123*8617a60dSAndroid Build Coastguard Worker };
124*8617a60dSAndroid Build Coastguard Worker const char *const argv[] = {
125*8617a60dSAndroid Build Coastguard Worker cbfstool, file, "truncate", "-r", region, NULL,
126*8617a60dSAndroid Build Coastguard Worker };
127*8617a60dSAndroid Build Coastguard Worker
128*8617a60dSAndroid Build Coastguard Worker status = subprocess_run(argv, &subprocess_null, &output,
129*8617a60dSAndroid Build Coastguard Worker &subprocess_null);
130*8617a60dSAndroid Build Coastguard Worker
131*8617a60dSAndroid Build Coastguard Worker if (status < 0) {
132*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "%s(): cbfstool invocation failed: %m\n",
133*8617a60dSAndroid Build Coastguard Worker __func__);
134*8617a60dSAndroid Build Coastguard Worker exit(1);
135*8617a60dSAndroid Build Coastguard Worker }
136*8617a60dSAndroid Build Coastguard Worker
137*8617a60dSAndroid Build Coastguard Worker /* Positive exit code means something is wrong with image. Return zero
138*8617a60dSAndroid Build Coastguard Worker as new size, because it might be problem with missing CBFS.*/
139*8617a60dSAndroid Build Coastguard Worker if (status > 0) {
140*8617a60dSAndroid Build Coastguard Worker *new_size = 0;
141*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_CBFSTOOL;
142*8617a60dSAndroid Build Coastguard Worker }
143*8617a60dSAndroid Build Coastguard Worker
144*8617a60dSAndroid Build Coastguard Worker if (sscanf(output_buffer, "%zi", new_size) != 1) {
145*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Failed to parse command output. Unexpected "
146*8617a60dSAndroid Build Coastguard Worker "output.\n");
147*8617a60dSAndroid Build Coastguard Worker *new_size = 0;
148*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_CBFSTOOL;
149*8617a60dSAndroid Build Coastguard Worker }
150*8617a60dSAndroid Build Coastguard Worker
151*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
152*8617a60dSAndroid Build Coastguard Worker }
153*8617a60dSAndroid Build Coastguard Worker
154*8617a60dSAndroid Build Coastguard Worker /* Requires null-terminated buffer */
extract_metadata_hash(const char * buf,struct vb2_hash * hash)155*8617a60dSAndroid Build Coastguard Worker static vb2_error_t extract_metadata_hash(const char *buf, struct vb2_hash *hash)
156*8617a60dSAndroid Build Coastguard Worker {
157*8617a60dSAndroid Build Coastguard Worker enum vb2_hash_algorithm algo;
158*8617a60dSAndroid Build Coastguard Worker const char *to_find = "\n[METADATA HASH]";
159*8617a60dSAndroid Build Coastguard Worker char *algo_str = NULL;
160*8617a60dSAndroid Build Coastguard Worker char *hash_str = NULL;
161*8617a60dSAndroid Build Coastguard Worker vb2_error_t rv = VB2_ERROR_CBFSTOOL;
162*8617a60dSAndroid Build Coastguard Worker
163*8617a60dSAndroid Build Coastguard Worker const char *start = strstr(buf, to_find);
164*8617a60dSAndroid Build Coastguard Worker if (start)
165*8617a60dSAndroid Build Coastguard Worker start += strlen(to_find);
166*8617a60dSAndroid Build Coastguard Worker
167*8617a60dSAndroid Build Coastguard Worker if (start) {
168*8617a60dSAndroid Build Coastguard Worker const int matches = sscanf(start, " %m[^:\n\t ]:%m[^:\n\t ]",
169*8617a60dSAndroid Build Coastguard Worker &algo_str, &hash_str);
170*8617a60dSAndroid Build Coastguard Worker
171*8617a60dSAndroid Build Coastguard Worker if (matches < 2)
172*8617a60dSAndroid Build Coastguard Worker goto done;
173*8617a60dSAndroid Build Coastguard Worker
174*8617a60dSAndroid Build Coastguard Worker if (!algo_str || !vb2_lookup_hash_alg(algo_str, &algo) ||
175*8617a60dSAndroid Build Coastguard Worker algo == VB2_HASH_INVALID)
176*8617a60dSAndroid Build Coastguard Worker goto done;
177*8617a60dSAndroid Build Coastguard Worker hash->algo = algo;
178*8617a60dSAndroid Build Coastguard Worker
179*8617a60dSAndroid Build Coastguard Worker if (!hash_str ||
180*8617a60dSAndroid Build Coastguard Worker strlen(hash_str) != (vb2_digest_size(algo) * 2) ||
181*8617a60dSAndroid Build Coastguard Worker !parse_hash(&hash->raw[0], vb2_digest_size(algo), hash_str))
182*8617a60dSAndroid Build Coastguard Worker goto done;
183*8617a60dSAndroid Build Coastguard Worker
184*8617a60dSAndroid Build Coastguard Worker if (!strstr(buf, "]\tfully valid"))
185*8617a60dSAndroid Build Coastguard Worker goto done;
186*8617a60dSAndroid Build Coastguard Worker
187*8617a60dSAndroid Build Coastguard Worker rv = VB2_SUCCESS;
188*8617a60dSAndroid Build Coastguard Worker }
189*8617a60dSAndroid Build Coastguard Worker
190*8617a60dSAndroid Build Coastguard Worker done:
191*8617a60dSAndroid Build Coastguard Worker if (rv != VB2_SUCCESS)
192*8617a60dSAndroid Build Coastguard Worker hash->algo = VB2_HASH_INVALID;
193*8617a60dSAndroid Build Coastguard Worker
194*8617a60dSAndroid Build Coastguard Worker free(algo_str);
195*8617a60dSAndroid Build Coastguard Worker free(hash_str);
196*8617a60dSAndroid Build Coastguard Worker
197*8617a60dSAndroid Build Coastguard Worker return rv;
198*8617a60dSAndroid Build Coastguard Worker }
199*8617a60dSAndroid Build Coastguard Worker
cbfstool_get_metadata_hash(const char * file,const char * region,struct vb2_hash * hash)200*8617a60dSAndroid Build Coastguard Worker vb2_error_t cbfstool_get_metadata_hash(const char *file, const char *region,
201*8617a60dSAndroid Build Coastguard Worker struct vb2_hash *hash)
202*8617a60dSAndroid Build Coastguard Worker {
203*8617a60dSAndroid Build Coastguard Worker int status;
204*8617a60dSAndroid Build Coastguard Worker const char *cbfstool = get_cbfstool_path();
205*8617a60dSAndroid Build Coastguard Worker const size_t data_buffer_sz = 1024 * 1024;
206*8617a60dSAndroid Build Coastguard Worker char *data_buffer = malloc(data_buffer_sz);
207*8617a60dSAndroid Build Coastguard Worker vb2_error_t rv = VB2_ERROR_CBFSTOOL;
208*8617a60dSAndroid Build Coastguard Worker
209*8617a60dSAndroid Build Coastguard Worker if (!data_buffer)
210*8617a60dSAndroid Build Coastguard Worker goto done;
211*8617a60dSAndroid Build Coastguard Worker
212*8617a60dSAndroid Build Coastguard Worker memset(hash, 0, sizeof(*hash));
213*8617a60dSAndroid Build Coastguard Worker hash->algo = VB2_HASH_INVALID;
214*8617a60dSAndroid Build Coastguard Worker
215*8617a60dSAndroid Build Coastguard Worker struct subprocess_target output = {
216*8617a60dSAndroid Build Coastguard Worker .type = TARGET_BUFFER_NULL_TERMINATED,
217*8617a60dSAndroid Build Coastguard Worker .buffer = {
218*8617a60dSAndroid Build Coastguard Worker .buf = data_buffer,
219*8617a60dSAndroid Build Coastguard Worker .size = data_buffer_sz,
220*8617a60dSAndroid Build Coastguard Worker },
221*8617a60dSAndroid Build Coastguard Worker };
222*8617a60dSAndroid Build Coastguard Worker const char *argv[] = {
223*8617a60dSAndroid Build Coastguard Worker cbfstool, file, "print", "-kv", ARGV_END(region)
224*8617a60dSAndroid Build Coastguard Worker };
225*8617a60dSAndroid Build Coastguard Worker
226*8617a60dSAndroid Build Coastguard Worker status = subprocess_run(argv, &subprocess_null, &output,
227*8617a60dSAndroid Build Coastguard Worker &subprocess_null);
228*8617a60dSAndroid Build Coastguard Worker
229*8617a60dSAndroid Build Coastguard Worker if (status < 0) {
230*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "%s(): cbfstool invocation failed: %m\n",
231*8617a60dSAndroid Build Coastguard Worker __func__);
232*8617a60dSAndroid Build Coastguard Worker exit(1);
233*8617a60dSAndroid Build Coastguard Worker }
234*8617a60dSAndroid Build Coastguard Worker
235*8617a60dSAndroid Build Coastguard Worker if (status > 0)
236*8617a60dSAndroid Build Coastguard Worker goto done;
237*8617a60dSAndroid Build Coastguard Worker
238*8617a60dSAndroid Build Coastguard Worker rv = extract_metadata_hash(data_buffer, hash);
239*8617a60dSAndroid Build Coastguard Worker
240*8617a60dSAndroid Build Coastguard Worker done:
241*8617a60dSAndroid Build Coastguard Worker free(data_buffer);
242*8617a60dSAndroid Build Coastguard Worker return rv;
243*8617a60dSAndroid Build Coastguard Worker }
244*8617a60dSAndroid Build Coastguard Worker
245*8617a60dSAndroid Build Coastguard Worker /* Requires null-terminated buffer */
extract_config_value(const char * buf,const char * config_field)246*8617a60dSAndroid Build Coastguard Worker static char *extract_config_value(const char *buf, const char *config_field)
247*8617a60dSAndroid Build Coastguard Worker {
248*8617a60dSAndroid Build Coastguard Worker char *to_find = NULL;
249*8617a60dSAndroid Build Coastguard Worker
250*8617a60dSAndroid Build Coastguard Worker if (asprintf(&to_find, "\n%s=", config_field) == -1) {
251*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "Out of Memory\n");
252*8617a60dSAndroid Build Coastguard Worker VB2_DIE("Out of memory\n");
253*8617a60dSAndroid Build Coastguard Worker }
254*8617a60dSAndroid Build Coastguard Worker
255*8617a60dSAndroid Build Coastguard Worker const char *start = strstr(buf, to_find);
256*8617a60dSAndroid Build Coastguard Worker if (start)
257*8617a60dSAndroid Build Coastguard Worker start += strlen(to_find);
258*8617a60dSAndroid Build Coastguard Worker
259*8617a60dSAndroid Build Coastguard Worker free(to_find);
260*8617a60dSAndroid Build Coastguard Worker
261*8617a60dSAndroid Build Coastguard Worker if (start) {
262*8617a60dSAndroid Build Coastguard Worker char *end = strchr(start, '\n');
263*8617a60dSAndroid Build Coastguard Worker if (end)
264*8617a60dSAndroid Build Coastguard Worker return strndup(start, end - start);
265*8617a60dSAndroid Build Coastguard Worker }
266*8617a60dSAndroid Build Coastguard Worker
267*8617a60dSAndroid Build Coastguard Worker return NULL;
268*8617a60dSAndroid Build Coastguard Worker }
269*8617a60dSAndroid Build Coastguard Worker
get_config_value(const char * file,const char * region,const char * config_field,char ** value)270*8617a60dSAndroid Build Coastguard Worker static vb2_error_t get_config_value(const char *file, const char *region,
271*8617a60dSAndroid Build Coastguard Worker const char *config_field, char **value)
272*8617a60dSAndroid Build Coastguard Worker {
273*8617a60dSAndroid Build Coastguard Worker int status;
274*8617a60dSAndroid Build Coastguard Worker const char *cbfstool = get_cbfstool_path();
275*8617a60dSAndroid Build Coastguard Worker const size_t data_buffer_sz = 1024 * 1024;
276*8617a60dSAndroid Build Coastguard Worker char *data_buffer = malloc(data_buffer_sz);
277*8617a60dSAndroid Build Coastguard Worker vb2_error_t rv = VB2_ERROR_CBFSTOOL;
278*8617a60dSAndroid Build Coastguard Worker
279*8617a60dSAndroid Build Coastguard Worker *value = NULL;
280*8617a60dSAndroid Build Coastguard Worker
281*8617a60dSAndroid Build Coastguard Worker if (!data_buffer)
282*8617a60dSAndroid Build Coastguard Worker goto done;
283*8617a60dSAndroid Build Coastguard Worker
284*8617a60dSAndroid Build Coastguard Worker struct subprocess_target output = {
285*8617a60dSAndroid Build Coastguard Worker .type = TARGET_BUFFER_NULL_TERMINATED,
286*8617a60dSAndroid Build Coastguard Worker .buffer = {
287*8617a60dSAndroid Build Coastguard Worker .buf = data_buffer,
288*8617a60dSAndroid Build Coastguard Worker .size = data_buffer_sz,
289*8617a60dSAndroid Build Coastguard Worker },
290*8617a60dSAndroid Build Coastguard Worker };
291*8617a60dSAndroid Build Coastguard Worker const char *argv[] = {
292*8617a60dSAndroid Build Coastguard Worker cbfstool, file, "extract", "-n", "config", "-f", "/dev/stdout",
293*8617a60dSAndroid Build Coastguard Worker ARGV_END(region)
294*8617a60dSAndroid Build Coastguard Worker };
295*8617a60dSAndroid Build Coastguard Worker
296*8617a60dSAndroid Build Coastguard Worker status = subprocess_run(argv, &subprocess_null, &output,
297*8617a60dSAndroid Build Coastguard Worker &subprocess_null);
298*8617a60dSAndroid Build Coastguard Worker
299*8617a60dSAndroid Build Coastguard Worker if (status < 0) {
300*8617a60dSAndroid Build Coastguard Worker fprintf(stderr, "%s(): cbfstool invocation failed: %m\n",
301*8617a60dSAndroid Build Coastguard Worker __func__);
302*8617a60dSAndroid Build Coastguard Worker exit(1);
303*8617a60dSAndroid Build Coastguard Worker }
304*8617a60dSAndroid Build Coastguard Worker
305*8617a60dSAndroid Build Coastguard Worker if (status > 0)
306*8617a60dSAndroid Build Coastguard Worker goto done;
307*8617a60dSAndroid Build Coastguard Worker
308*8617a60dSAndroid Build Coastguard Worker *value = extract_config_value(data_buffer, config_field);
309*8617a60dSAndroid Build Coastguard Worker
310*8617a60dSAndroid Build Coastguard Worker rv = VB2_SUCCESS;
311*8617a60dSAndroid Build Coastguard Worker done:
312*8617a60dSAndroid Build Coastguard Worker free(data_buffer);
313*8617a60dSAndroid Build Coastguard Worker return rv;
314*8617a60dSAndroid Build Coastguard Worker }
315*8617a60dSAndroid Build Coastguard Worker
cbfstool_get_config_bool(const char * file,const char * region,const char * config_field,bool * value)316*8617a60dSAndroid Build Coastguard Worker vb2_error_t cbfstool_get_config_bool(const char *file, const char *region,
317*8617a60dSAndroid Build Coastguard Worker const char *config_field, bool *value)
318*8617a60dSAndroid Build Coastguard Worker {
319*8617a60dSAndroid Build Coastguard Worker vb2_error_t rv;
320*8617a60dSAndroid Build Coastguard Worker char *raw_value = NULL;
321*8617a60dSAndroid Build Coastguard Worker
322*8617a60dSAndroid Build Coastguard Worker *value = false;
323*8617a60dSAndroid Build Coastguard Worker
324*8617a60dSAndroid Build Coastguard Worker rv = get_config_value(file, region, config_field, &raw_value);
325*8617a60dSAndroid Build Coastguard Worker if (rv)
326*8617a60dSAndroid Build Coastguard Worker return rv;
327*8617a60dSAndroid Build Coastguard Worker
328*8617a60dSAndroid Build Coastguard Worker if (raw_value && strcmp(raw_value, "y") == 0)
329*8617a60dSAndroid Build Coastguard Worker *value = true;
330*8617a60dSAndroid Build Coastguard Worker
331*8617a60dSAndroid Build Coastguard Worker free(raw_value);
332*8617a60dSAndroid Build Coastguard Worker return VB2_SUCCESS;
333*8617a60dSAndroid Build Coastguard Worker }
334*8617a60dSAndroid Build Coastguard Worker
cbfstool_get_config_string(const char * file,const char * region,const char * config_field,char ** value)335*8617a60dSAndroid Build Coastguard Worker vb2_error_t cbfstool_get_config_string(const char *file, const char *region,
336*8617a60dSAndroid Build Coastguard Worker const char *config_field, char **value)
337*8617a60dSAndroid Build Coastguard Worker {
338*8617a60dSAndroid Build Coastguard Worker vb2_error_t rv;
339*8617a60dSAndroid Build Coastguard Worker char *raw_value = NULL;
340*8617a60dSAndroid Build Coastguard Worker
341*8617a60dSAndroid Build Coastguard Worker *value = NULL;
342*8617a60dSAndroid Build Coastguard Worker
343*8617a60dSAndroid Build Coastguard Worker rv = get_config_value(file, region, config_field, &raw_value);
344*8617a60dSAndroid Build Coastguard Worker if (rv)
345*8617a60dSAndroid Build Coastguard Worker return rv;
346*8617a60dSAndroid Build Coastguard Worker
347*8617a60dSAndroid Build Coastguard Worker /*
348*8617a60dSAndroid Build Coastguard Worker * With CL:4085654, all the valid configs of type 'str' should be
349*8617a60dSAndroid Build Coastguard Worker * present in the "config" CBFS file.
350*8617a60dSAndroid Build Coastguard Worker */
351*8617a60dSAndroid Build Coastguard Worker if (!raw_value) {
352*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("Config '%s' not found in %s.", config_field, file);
353*8617a60dSAndroid Build Coastguard Worker return VB2_ERROR_CBFSTOOL;
354*8617a60dSAndroid Build Coastguard Worker }
355*8617a60dSAndroid Build Coastguard Worker
356*8617a60dSAndroid Build Coastguard Worker size_t len = strlen(raw_value);
357*8617a60dSAndroid Build Coastguard Worker if (len < 2 || raw_value[0] != '"' || raw_value[len - 1] != '"') {
358*8617a60dSAndroid Build Coastguard Worker VB2_DEBUG("%s value '%s' is not enclosed with double quotes.",
359*8617a60dSAndroid Build Coastguard Worker config_field, raw_value);
360*8617a60dSAndroid Build Coastguard Worker rv = VB2_ERROR_CBFSTOOL;
361*8617a60dSAndroid Build Coastguard Worker goto done;
362*8617a60dSAndroid Build Coastguard Worker }
363*8617a60dSAndroid Build Coastguard Worker
364*8617a60dSAndroid Build Coastguard Worker *value = strndup(&raw_value[1], len - 2);
365*8617a60dSAndroid Build Coastguard Worker
366*8617a60dSAndroid Build Coastguard Worker done:
367*8617a60dSAndroid Build Coastguard Worker free(raw_value);
368*8617a60dSAndroid Build Coastguard Worker return rv;
369*8617a60dSAndroid Build Coastguard Worker }
370