aboutsummaryrefslogtreecommitdiffstats
path: root/net/ceph/ceph_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ceph/ceph_common.c')
-rw-r--r--net/ceph/ceph_common.c112
1 files changed, 102 insertions, 10 deletions
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c
index 95f96ab94bba..132963abc266 100644
--- a/net/ceph/ceph_common.c
+++ b/net/ceph/ceph_common.c
@@ -5,6 +5,8 @@
5#include <linux/fs.h> 5#include <linux/fs.h>
6#include <linux/inet.h> 6#include <linux/inet.h>
7#include <linux/in6.h> 7#include <linux/in6.h>
8#include <linux/key.h>
9#include <keys/ceph-type.h>
8#include <linux/module.h> 10#include <linux/module.h>
9#include <linux/mount.h> 11#include <linux/mount.h>
10#include <linux/parser.h> 12#include <linux/parser.h>
@@ -20,6 +22,7 @@
20#include <linux/ceph/decode.h> 22#include <linux/ceph/decode.h>
21#include <linux/ceph/mon_client.h> 23#include <linux/ceph/mon_client.h>
22#include <linux/ceph/auth.h> 24#include <linux/ceph/auth.h>
25#include "crypto.h"
23 26
24 27
25 28
@@ -117,9 +120,29 @@ int ceph_compare_options(struct ceph_options *new_opt,
117 if (ret) 120 if (ret)
118 return ret; 121 return ret;
119 122
120 ret = strcmp_null(opt1->secret, opt2->secret); 123 if (opt1->key && !opt2->key)
121 if (ret) 124 return -1;
122 return ret; 125 if (!opt1->key && opt2->key)
126 return 1;
127 if (opt1->key && opt2->key) {
128 if (opt1->key->type != opt2->key->type)
129 return -1;
130 if (opt1->key->created.tv_sec != opt2->key->created.tv_sec)
131 return -1;
132 if (opt1->key->created.tv_nsec != opt2->key->created.tv_nsec)
133 return -1;
134 if (opt1->key->len != opt2->key->len)
135 return -1;
136 if (opt1->key->key && !opt2->key->key)
137 return -1;
138 if (!opt1->key->key && opt2->key->key)
139 return 1;
140 if (opt1->key->key && opt2->key->key) {
141 ret = memcmp(opt1->key->key, opt2->key->key, opt1->key->len);
142 if (ret)
143 return ret;
144 }
145 }
123 146
124 /* any matching mon ip implies a match */ 147 /* any matching mon ip implies a match */
125 for (i = 0; i < opt1->num_mon; i++) { 148 for (i = 0; i < opt1->num_mon; i++) {
@@ -176,6 +199,7 @@ enum {
176 Opt_fsid, 199 Opt_fsid,
177 Opt_name, 200 Opt_name,
178 Opt_secret, 201 Opt_secret,
202 Opt_key,
179 Opt_ip, 203 Opt_ip,
180 Opt_last_string, 204 Opt_last_string,
181 /* string args above */ 205 /* string args above */
@@ -192,6 +216,7 @@ static match_table_t opt_tokens = {
192 {Opt_fsid, "fsid=%s"}, 216 {Opt_fsid, "fsid=%s"},
193 {Opt_name, "name=%s"}, 217 {Opt_name, "name=%s"},
194 {Opt_secret, "secret=%s"}, 218 {Opt_secret, "secret=%s"},
219 {Opt_key, "key=%s"},
195 {Opt_ip, "ip=%s"}, 220 {Opt_ip, "ip=%s"},
196 /* string args above */ 221 /* string args above */
197 {Opt_noshare, "noshare"}, 222 {Opt_noshare, "noshare"},
@@ -203,11 +228,56 @@ void ceph_destroy_options(struct ceph_options *opt)
203{ 228{
204 dout("destroy_options %p\n", opt); 229 dout("destroy_options %p\n", opt);
205 kfree(opt->name); 230 kfree(opt->name);
206 kfree(opt->secret); 231 if (opt->key) {
232 ceph_crypto_key_destroy(opt->key);
233 kfree(opt->key);
234 }
207 kfree(opt); 235 kfree(opt);
208} 236}
209EXPORT_SYMBOL(ceph_destroy_options); 237EXPORT_SYMBOL(ceph_destroy_options);
210 238
239/* get secret from key store */
240static int get_secret(struct ceph_crypto_key *dst, const char *name) {
241 struct key *ukey;
242 int key_err;
243 int err = 0;
244 struct ceph_crypto_key *ckey;
245
246 ukey = request_key(&key_type_ceph, name, NULL);
247 if (!ukey || IS_ERR(ukey)) {
248 /* request_key errors don't map nicely to mount(2)
249 errors; don't even try, but still printk */
250 key_err = PTR_ERR(ukey);
251 switch (key_err) {
252 case -ENOKEY:
253 pr_warning("ceph: Mount failed due to key not found: %s\n", name);
254 break;
255 case -EKEYEXPIRED:
256 pr_warning("ceph: Mount failed due to expired key: %s\n", name);
257 break;
258 case -EKEYREVOKED:
259 pr_warning("ceph: Mount failed due to revoked key: %s\n", name);
260 break;
261 default:
262 pr_warning("ceph: Mount failed due to unknown key error"
263 " %d: %s\n", key_err, name);
264 }
265 err = -EPERM;
266 goto out;
267 }
268
269 ckey = ukey->payload.data;
270 err = ceph_crypto_key_clone(dst, ckey);
271 if (err)
272 goto out_key;
273 /* pass through, err is 0 */
274
275out_key:
276 key_put(ukey);
277out:
278 return err;
279}
280
211int ceph_parse_options(struct ceph_options **popt, char *options, 281int ceph_parse_options(struct ceph_options **popt, char *options,
212 const char *dev_name, const char *dev_name_end, 282 const char *dev_name, const char *dev_name_end,
213 int (*parse_extra_token)(char *c, void *private), 283 int (*parse_extra_token)(char *c, void *private),
@@ -295,9 +365,24 @@ int ceph_parse_options(struct ceph_options **popt, char *options,
295 GFP_KERNEL); 365 GFP_KERNEL);
296 break; 366 break;
297 case Opt_secret: 367 case Opt_secret:
298 opt->secret = kstrndup(argstr[0].from, 368 opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
299 argstr[0].to-argstr[0].from, 369 if (!opt->key) {
300 GFP_KERNEL); 370 err = -ENOMEM;
371 goto out;
372 }
373 err = ceph_crypto_key_unarmor(opt->key, argstr[0].from);
374 if (err < 0)
375 goto out;
376 break;
377 case Opt_key:
378 opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
379 if (!opt->key) {
380 err = -ENOMEM;
381 goto out;
382 }
383 err = get_secret(opt->key, argstr[0].from);
384 if (err < 0)
385 goto out;
301 break; 386 break;
302 387
303 /* misc */ 388 /* misc */
@@ -394,8 +479,8 @@ void ceph_destroy_client(struct ceph_client *client)
394 ceph_osdc_stop(&client->osdc); 479 ceph_osdc_stop(&client->osdc);
395 480
396 /* 481 /*
397 * make sure mds and osd connections close out before destroying 482 * make sure osd connections close out before destroying the
398 * the auth module, which is needed to free those connections' 483 * auth module, which is needed to free those connections'
399 * ceph_authorizers. 484 * ceph_authorizers.
400 */ 485 */
401 ceph_msgr_flush(); 486 ceph_msgr_flush();
@@ -496,10 +581,14 @@ static int __init init_ceph_lib(void)
496 if (ret < 0) 581 if (ret < 0)
497 goto out; 582 goto out;
498 583
499 ret = ceph_msgr_init(); 584 ret = ceph_crypto_init();
500 if (ret < 0) 585 if (ret < 0)
501 goto out_debugfs; 586 goto out_debugfs;
502 587
588 ret = ceph_msgr_init();
589 if (ret < 0)
590 goto out_crypto;
591
503 pr_info("loaded (mon/osd proto %d/%d, osdmap %d/%d %d/%d)\n", 592 pr_info("loaded (mon/osd proto %d/%d, osdmap %d/%d %d/%d)\n",
504 CEPH_MONC_PROTOCOL, CEPH_OSDC_PROTOCOL, 593 CEPH_MONC_PROTOCOL, CEPH_OSDC_PROTOCOL,
505 CEPH_OSDMAP_VERSION, CEPH_OSDMAP_VERSION_EXT, 594 CEPH_OSDMAP_VERSION, CEPH_OSDMAP_VERSION_EXT,
@@ -507,6 +596,8 @@ static int __init init_ceph_lib(void)
507 596
508 return 0; 597 return 0;
509 598
599out_crypto:
600 ceph_crypto_shutdown();
510out_debugfs: 601out_debugfs:
511 ceph_debugfs_cleanup(); 602 ceph_debugfs_cleanup();
512out: 603out:
@@ -517,6 +608,7 @@ static void __exit exit_ceph_lib(void)
517{ 608{
518 dout("exit_ceph_lib\n"); 609 dout("exit_ceph_lib\n");
519 ceph_msgr_exit(); 610 ceph_msgr_exit();
611 ceph_crypto_shutdown();
520 ceph_debugfs_cleanup(); 612 ceph_debugfs_cleanup();
521} 613}
522 614