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 "spdk/keyring_module.h"
6 : : #include "spdk/module/keyring/file.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 struct spdk_keyring_module g_keyring_file;
16 : :
17 : : static int
18 : 3849 : keyring_file_check_path(const char *path, int *size)
19 : : {
20 : 0 : struct stat st;
21 : : int rc, errsv;
22 : :
23 [ + + # # : 3849 : if (path[0] != '/') {
# # ]
24 : 3 : SPDK_ERRLOG("Non-absolute paths are not allowed: %s\n", path);
25 : 3 : return -EPERM;
26 : : }
27 : :
28 [ - + # # ]: 3846 : rc = stat(path, &st);
29 [ + + ]: 3846 : if (rc != 0) {
30 [ # # ]: 3 : errsv = errno;
31 : 3 : SPDK_ERRLOG("Could not stat key file '%s': %s\n", path, spdk_strerror(errsv));
32 [ # # ]: 3 : return -errsv;
33 : : }
34 : :
35 [ + + - + : 3843 : if ((st.st_mode & 077) || st.st_uid != getuid()) {
# # # # ]
36 [ # # ]: 9 : SPDK_ERRLOG("Invalid permissions for key file '%s': 0%o\n", path, st.st_mode);
37 : 9 : return -EPERM;
38 : : }
39 : :
40 [ + + ]: 3834 : if (size != NULL) {
41 [ # # # # ]: 3621 : *size = st.st_size;
42 : 0 : }
43 : :
44 : 3834 : return 0;
45 : 0 : }
46 : :
47 : : static void
48 : 18 : keyring_file_write_key_config(void *ctx, struct spdk_key *key)
49 : : {
50 : 18 : struct spdk_json_write_ctx *w = ctx;
51 : : struct keyring_file_key *kkey;
52 : :
53 [ - + ]: 18 : if (spdk_key_get_module(key) != &g_keyring_file) {
54 : 0 : return;
55 : : }
56 : :
57 : 18 : kkey = spdk_key_get_ctx(key);
58 : :
59 : 18 : spdk_json_write_object_begin(w);
60 : 18 : spdk_json_write_named_string(w, "method", "keyring_file_add_key");
61 : 18 : spdk_json_write_named_object_begin(w, "params");
62 : 18 : spdk_json_write_named_string(w, "name", spdk_key_get_name(key));
63 [ # # # # ]: 18 : spdk_json_write_named_string(w, "path", kkey->path);
64 : 18 : spdk_json_write_object_end(w);
65 : 18 : spdk_json_write_object_end(w);
66 : 0 : }
67 : :
68 : : static void
69 : 128 : keyring_file_write_config(struct spdk_json_write_ctx *w)
70 : : {
71 : 128 : spdk_keyring_for_each_key(NULL, w, keyring_file_write_key_config, 0);
72 : 128 : }
73 : :
74 : : static void
75 : 84 : keyring_file_dump_info(struct spdk_key *key, struct spdk_json_write_ctx *w)
76 : : {
77 : 84 : struct keyring_file_key *kkey = spdk_key_get_ctx(key);
78 : :
79 [ # # # # ]: 84 : spdk_json_write_named_string(w, "path", kkey->path);
80 : 84 : }
81 : :
82 : : static size_t
83 : 225 : keyring_file_get_ctx_size(void)
84 : : {
85 : 225 : return sizeof(struct keyring_file_key);
86 : : }
87 : :
88 : : static int
89 : 3624 : keyring_file_get_key(struct spdk_key *key, void *buf, int len)
90 : : {
91 : 3624 : struct keyring_file_key *kkey = spdk_key_get_ctx(key);
92 : : FILE *file;
93 : 3624 : int rc, errsv, size = 0;
94 : :
95 [ # # # # ]: 3624 : rc = keyring_file_check_path(kkey->path, &size);
96 [ + + ]: 3624 : if (rc != 0) {
97 : 3 : return rc;
98 : : }
99 : :
100 [ - + ]: 3621 : if (size > len) {
101 : 0 : SPDK_ERRLOG("Invalid key '%s' size: %d > %d\n", spdk_key_get_name(key), size, len);
102 : 0 : return -ENOBUFS;
103 : : }
104 : :
105 [ # # # # ]: 3621 : file = fopen(kkey->path, "r");
106 [ - + ]: 3621 : if (!file) {
107 [ # # ]: 0 : errsv = errno;
108 : 0 : SPDK_ERRLOG("Could not open key '%s': %s\n", spdk_key_get_name(key),
109 : : spdk_strerror(errsv));
110 [ # # ]: 0 : return -errsv;
111 : : }
112 : :
113 [ # # ]: 3621 : rc = (int)fread(buf, 1, size, file);
114 [ - + ]: 3621 : if (rc != size) {
115 : 0 : SPDK_ERRLOG("Could not load key '%s'\n", spdk_key_get_name(key));
116 : 0 : rc = -EIO;
117 : 0 : }
118 : :
119 [ - + ]: 3621 : fclose(file);
120 : :
121 : 3621 : return rc;
122 : 0 : }
123 : :
124 : : static void
125 : 213 : keyring_file_remove_key(struct spdk_key *key)
126 : : {
127 : 213 : struct keyring_file_key *kkey = spdk_key_get_ctx(key);
128 : :
129 [ # # # # ]: 213 : free(kkey->path);
130 : 213 : }
131 : :
132 : : static int
133 : 225 : keyring_file_add_key(struct spdk_key *key, void *ctx)
134 : : {
135 : 225 : struct keyring_file_key *kkey = spdk_key_get_ctx(key);
136 : 225 : const char *path = ctx;
137 : : int rc;
138 : :
139 : 225 : rc = keyring_file_check_path(path, NULL);
140 [ + + ]: 225 : if (rc != 0) {
141 : 12 : return rc;
142 : : }
143 : :
144 [ - + # # : 213 : kkey->path = strdup(path);
# # ]
145 [ - + # # : 213 : if (kkey->path == NULL) {
# # ]
146 : 0 : return -ENOMEM;
147 : : }
148 : :
149 : 213 : return 0;
150 : 0 : }
151 : :
152 : : int
153 : 225 : spdk_keyring_file_add_key(const char *name, const char *path)
154 : : {
155 : 225 : struct spdk_key_opts opts = {};
156 : :
157 : 225 : opts.size = SPDK_SIZEOF(&opts, ctx);
158 [ # # ]: 225 : opts.name = name;
159 [ # # ]: 225 : opts.module = &g_keyring_file;
160 [ # # ]: 225 : opts.ctx = (void *)path;
161 : :
162 : 225 : return spdk_keyring_add_key(&opts);
163 : : }
164 : :
165 : : int
166 : 15 : spdk_keyring_file_remove_key(const char *name)
167 : : {
168 : 15 : return spdk_keyring_remove_key(name, &g_keyring_file);
169 : : }
170 : :
171 : : static struct spdk_keyring_module g_keyring_file = {
172 : : .name = "keyring_file",
173 : : .add_key = keyring_file_add_key,
174 : : .remove_key = keyring_file_remove_key,
175 : : .get_key = keyring_file_get_key,
176 : : .get_ctx_size = keyring_file_get_ctx_size,
177 : : .dump_info = keyring_file_dump_info,
178 : : .write_config = keyring_file_write_config,
179 : : };
180 : :
181 : 2238 : SPDK_KEYRING_REGISTER_MODULE(keyring_file, &g_keyring_file);
|