1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 #include "integrity-util.h"
3 
4 #include "extract-word.h"
5 #include "fileio.h"
6 #include "path-util.h"
7 #include "percent-util.h"
8 
9 
supported_integrity_algorithm(char * user_supplied)10 static int supported_integrity_algorithm(char *user_supplied) {
11         if (!STR_IN_SET(user_supplied, "crc32", "crc32c", "sha1", "sha256", "hmac-sha256"))
12                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unsupported integrity algorithm (%s)", user_supplied);
13         return 0;
14 }
15 
parse_integrity_options(const char * options,uint32_t * ret_activate_flags,int * ret_percent,usec_t * ret_commit_time,char ** ret_data_device,char ** ret_integrity_alg)16 int parse_integrity_options(
17                 const char *options,
18                 uint32_t *ret_activate_flags,
19                 int *ret_percent,
20                 usec_t *ret_commit_time,
21                 char **ret_data_device,
22                 char **ret_integrity_alg) {
23         int r;
24 
25         for (;;) {
26                 _cleanup_free_ char *word = NULL;
27                 char *val;
28 
29                 r = extract_first_word(&options, &word, ",", EXTRACT_DONT_COALESCE_SEPARATORS | EXTRACT_UNESCAPE_SEPARATORS);
30                 if (r < 0)
31                         return log_error_errno(r, "Failed to parse options: %m");
32                 if (r == 0)
33                         break;
34                 else if (streq(word, "allow-discards")) {
35                         if (ret_activate_flags)
36                                 *ret_activate_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
37                 } else if ((val = startswith(word, "journal-watermark="))) {
38                         r = parse_percent(val);
39                         if (r < 0)
40                                 return log_error_errno(r, "Failed to parse journal-watermark value or value out of range (%s)", val);
41                         if (ret_percent)
42                                 *ret_percent = r;
43                 } else if ((val = startswith(word, "journal-commit-time="))) {
44                         usec_t tmp_commit_time;
45                         r = parse_sec(val, &tmp_commit_time);
46                         if (r < 0)
47                                 return log_error_errno(r, "Failed to parse journal-commit-time value (%s)", val);
48                         if (ret_commit_time)
49                                 *ret_commit_time = tmp_commit_time;
50                 } else if ((val = startswith(word, "data-device="))) {
51                         if (ret_data_device) {
52                                 r = free_and_strdup(ret_data_device, val);
53                                 if (r < 0)
54                                         return log_oom();
55                         }
56                 } else if ((val = startswith(word, "integrity-algorithm="))) {
57                         r = supported_integrity_algorithm(val);
58                         if (r < 0)
59                                 return r;
60                         if (ret_integrity_alg) {
61                                 r = free_and_strdup(ret_integrity_alg, val);
62                                 if (r < 0)
63                                         return log_oom();
64                         }
65                 } else
66                         log_warning("Encountered unknown option '%s', ignoring.", word);
67         }
68 
69         return r;
70 }
71