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 0 : keyring_file_check_path(const char *path, int *size)
17 : {
18 0 : struct stat st;
19 : int rc, errsv;
20 :
21 0 : if (path[0] != '/') {
22 0 : SPDK_ERRLOG("Non-absolute paths are not allowed: %s\n", path);
23 0 : return -EPERM;
24 : }
25 :
26 0 : rc = stat(path, &st);
27 0 : if (rc != 0) {
28 0 : errsv = errno;
29 0 : SPDK_ERRLOG("Could not stat key file '%s': %s\n", path, spdk_strerror(errsv));
30 0 : return -errsv;
31 : }
32 :
33 0 : if ((st.st_mode & 077) || st.st_uid != getuid()) {
34 0 : SPDK_ERRLOG("Invalid permissions for key file '%s': 0%o\n", path, st.st_mode);
35 0 : return -EPERM;
36 : }
37 :
38 0 : if (size != NULL) {
39 0 : *size = st.st_size;
40 : }
41 :
42 0 : return 0;
43 : }
44 :
45 : static void
46 0 : keyring_file_write_key_config(void *ctx, struct spdk_key *key)
47 : {
48 0 : struct spdk_json_write_ctx *w = ctx;
49 : struct keyring_file_key *kkey;
50 :
51 0 : if (spdk_key_get_module(key) != &g_keyring_file) {
52 0 : return;
53 : }
54 :
55 0 : kkey = spdk_key_get_ctx(key);
56 :
57 0 : spdk_json_write_object_begin(w);
58 0 : spdk_json_write_named_string(w, "method", "keyring_file_add_key");
59 0 : spdk_json_write_named_object_begin(w, "params");
60 0 : spdk_json_write_named_string(w, "name", spdk_key_get_name(key));
61 0 : spdk_json_write_named_string(w, "path", kkey->path);
62 0 : spdk_json_write_object_end(w);
63 0 : spdk_json_write_object_end(w);
64 : }
65 :
66 : static void
67 0 : keyring_file_write_config(struct spdk_json_write_ctx *w)
68 : {
69 0 : spdk_keyring_for_each_key(NULL, w, keyring_file_write_key_config, 0);
70 0 : }
71 :
72 : static void
73 0 : keyring_file_dump_info(struct spdk_key *key, struct spdk_json_write_ctx *w)
74 : {
75 0 : struct keyring_file_key *kkey = spdk_key_get_ctx(key);
76 :
77 0 : spdk_json_write_named_string(w, "path", kkey->path);
78 0 : }
79 :
80 : static size_t
81 0 : keyring_file_get_ctx_size(void)
82 : {
83 0 : return sizeof(struct keyring_file_key);
84 : }
85 :
86 : static int
87 0 : keyring_file_get_key(struct spdk_key *key, void *buf, int len)
88 : {
89 0 : struct keyring_file_key *kkey = spdk_key_get_ctx(key);
90 : FILE *file;
91 0 : int rc, errsv, size = 0;
92 :
93 0 : rc = keyring_file_check_path(kkey->path, &size);
94 0 : if (rc != 0) {
95 0 : return rc;
96 : }
97 :
98 0 : 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 0 : file = fopen(kkey->path, "r");
104 0 : 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 0 : rc = (int)fread(buf, 1, size, file);
112 0 : 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 0 : fclose(file);
118 :
119 0 : return rc;
120 : }
121 :
122 : static void
123 0 : keyring_file_remove_key(struct spdk_key *key)
124 : {
125 0 : struct keyring_file_key *kkey = spdk_key_get_ctx(key);
126 :
127 0 : free(kkey->path);
128 0 : }
129 :
130 : static int
131 0 : keyring_file_add_key(struct spdk_key *key, void *ctx)
132 : {
133 0 : struct keyring_file_key_opts *opts = ctx;
134 0 : struct keyring_file_key *kkey = spdk_key_get_ctx(key);
135 : int rc;
136 :
137 0 : rc = keyring_file_check_path(opts->path, NULL);
138 0 : if (rc != 0) {
139 0 : return rc;
140 : }
141 :
142 0 : kkey->path = strdup(opts->path);
143 0 : if (kkey->path == NULL) {
144 0 : return -ENOMEM;
145 : }
146 :
147 0 : 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 0 : SPDK_KEYRING_REGISTER_MODULE(keyring_file, &g_keyring_file);
|