Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (c) 2024 Intel Corporation. All rights reserved.
3 : : */
4 : :
5 : : #include "keyring_file.h"
6 : : #include "spdk/keyring_module.h"
7 : : #include "spdk/log.h"
8 : : #include "spdk/string.h"
9 : : #include "spdk/util.h"
10 : :
11 : : struct keyring_file_key {
12 : : char *path;
13 : : };
14 : :
15 : : static int
16 : 3385 : keyring_file_check_path(const char *path, int *size)
17 : : {
18 : 0 : struct stat st;
19 : : int rc, errsv;
20 : :
21 [ - + ]: 3385 : if (path[0] != '/') {
22 : 0 : SPDK_ERRLOG("Non-absolute paths are not allowed: %s\n", path);
23 : 0 : return -EPERM;
24 : : }
25 : :
26 [ - + ]: 3385 : rc = stat(path, &st);
27 [ + + ]: 3385 : if (rc != 0) {
28 : 3 : errsv = errno;
29 : 3 : SPDK_ERRLOG("Could not stat key file '%s': %s\n", path, spdk_strerror(errsv));
30 : 3 : return -errsv;
31 : : }
32 : :
33 [ + + - + ]: 3382 : if ((st.st_mode & 077) || st.st_uid != getuid()) {
34 : 3 : SPDK_ERRLOG("Invalid permissions for key file '%s': 0%o\n", path, st.st_mode);
35 : 3 : return -EPERM;
36 : : }
37 : :
38 [ + + ]: 3379 : if (size != NULL) {
39 : 3241 : *size = st.st_size;
40 : : }
41 : :
42 : 3379 : return 0;
43 : : }
44 : :
45 : : static void
46 : 12 : keyring_file_write_key_config(void *ctx, struct spdk_key *key)
47 : : {
48 : 12 : struct spdk_json_write_ctx *w = ctx;
49 : : struct keyring_file_key *kkey;
50 : :
51 [ - + ]: 12 : if (spdk_key_get_module(key) != &g_keyring_file) {
52 : 0 : return;
53 : : }
54 : :
55 : 12 : kkey = spdk_key_get_ctx(key);
56 : :
57 : 12 : spdk_json_write_object_begin(w);
58 : 12 : spdk_json_write_named_string(w, "method", "keyring_file_add_key");
59 : 12 : spdk_json_write_named_object_begin(w, "params");
60 : 12 : spdk_json_write_named_string(w, "name", spdk_key_get_name(key));
61 : 12 : spdk_json_write_named_string(w, "path", kkey->path);
62 : 12 : spdk_json_write_object_end(w);
63 : 12 : spdk_json_write_object_end(w);
64 : : }
65 : :
66 : : static void
67 : 108 : keyring_file_write_config(struct spdk_json_write_ctx *w)
68 : : {
69 : 108 : spdk_keyring_for_each_key(NULL, w, keyring_file_write_key_config, 0);
70 : 108 : }
71 : :
72 : : static void
73 : 84 : keyring_file_dump_info(struct spdk_key *key, struct spdk_json_write_ctx *w)
74 : : {
75 : 84 : struct keyring_file_key *kkey = spdk_key_get_ctx(key);
76 : :
77 : 84 : spdk_json_write_named_string(w, "path", kkey->path);
78 : 84 : }
79 : :
80 : : static size_t
81 : 141 : keyring_file_get_ctx_size(void)
82 : : {
83 : 141 : return sizeof(struct keyring_file_key);
84 : : }
85 : :
86 : : static int
87 : 3244 : keyring_file_get_key(struct spdk_key *key, void *buf, int len)
88 : : {
89 : 3244 : struct keyring_file_key *kkey = spdk_key_get_ctx(key);
90 : : FILE *file;
91 : 3244 : int rc, errsv, size = 0;
92 : :
93 : 3244 : rc = keyring_file_check_path(kkey->path, &size);
94 [ + + ]: 3244 : if (rc != 0) {
95 : 3 : return rc;
96 : : }
97 : :
98 [ - + ]: 3241 : if (size > len) {
99 : 0 : SPDK_ERRLOG("Invalid key '%s' size: %d > %d\n", spdk_key_get_name(key), size, len);
100 : 0 : return -ENOBUFS;
101 : : }
102 : :
103 : 3241 : file = fopen(kkey->path, "r");
104 [ - + ]: 3241 : if (!file) {
105 : 0 : errsv = errno;
106 : 0 : SPDK_ERRLOG("Could not open key '%s': %s\n", spdk_key_get_name(key),
107 : : spdk_strerror(errsv));
108 : 0 : return -errsv;
109 : : }
110 : :
111 : 3241 : rc = (int)fread(buf, 1, size, file);
112 [ - + ]: 3241 : if (rc != size) {
113 : 0 : SPDK_ERRLOG("Could not load key '%s'\n", spdk_key_get_name(key));
114 : 0 : rc = -EIO;
115 : : }
116 : :
117 : 3241 : fclose(file);
118 : :
119 : 3241 : return rc;
120 : : }
121 : :
122 : : static void
123 : 138 : keyring_file_remove_key(struct spdk_key *key)
124 : : {
125 : 138 : struct keyring_file_key *kkey = spdk_key_get_ctx(key);
126 : :
127 : 138 : free(kkey->path);
128 : 138 : }
129 : :
130 : : static int
131 : 141 : keyring_file_add_key(struct spdk_key *key, void *ctx)
132 : : {
133 : 141 : struct keyring_file_key_opts *opts = ctx;
134 : 141 : struct keyring_file_key *kkey = spdk_key_get_ctx(key);
135 : : int rc;
136 : :
137 : 141 : rc = keyring_file_check_path(opts->path, NULL);
138 [ + + ]: 141 : if (rc != 0) {
139 : 3 : return rc;
140 : : }
141 : :
142 [ - + ]: 138 : kkey->path = strdup(opts->path);
143 [ - + ]: 138 : if (kkey->path == NULL) {
144 : 0 : return -ENOMEM;
145 : : }
146 : :
147 : 138 : return 0;
148 : : }
149 : :
150 : : struct spdk_keyring_module g_keyring_file = {
151 : : .name = "keyring_file",
152 : : .add_key = keyring_file_add_key,
153 : : .remove_key = keyring_file_remove_key,
154 : : .get_key = keyring_file_get_key,
155 : : .get_ctx_size = keyring_file_get_ctx_size,
156 : : .dump_info = keyring_file_dump_info,
157 : : .write_config = keyring_file_write_config,
158 : : };
159 : :
160 : 2048 : SPDK_KEYRING_REGISTER_MODULE(keyring_file, &g_keyring_file);
|