Commit 8323c3aa74cd92465350294567142d12ffdcc963

Authored by Tommi Virtanen
Committed by Sage Weil
1 parent fbdb919048

ceph: Move secret key parsing earlier.

This makes the base64 logic be contained in mount option parsing,
and prepares us for replacing the homebew key management with the
kernel key retention service.

Signed-off-by: Tommi Virtanen <tommi.virtanen@dreamhost.com>
Signed-off-by: Sage Weil <sage@newdream.net>

Showing 9 changed files with 63 additions and 19 deletions Side-by-side Diff

... ... @@ -353,7 +353,7 @@
353 353  
354 354 if (opt->name)
355 355 seq_printf(m, ",name=%s", opt->name);
356   - if (opt->secret)
  356 + if (opt->key)
357 357 seq_puts(m, ",secret=<hidden>");
358 358  
359 359 if (opt->mount_timeout != CEPH_MOUNT_TIMEOUT_DEFAULT)
include/linux/ceph/auth.h
... ... @@ -67,12 +67,12 @@
67 67 bool negotiating; /* true if negotiating protocol */
68 68 const char *name; /* entity name */
69 69 u64 global_id; /* our unique id in system */
70   - const char *secret; /* our secret key */
  70 + const struct ceph_crypto_key *key; /* our secret key */
71 71 unsigned want_keys; /* which services we want */
72 72 };
73 73  
74 74 extern struct ceph_auth_client *ceph_auth_init(const char *name,
75   - const char *secret);
  75 + const struct ceph_crypto_key *key);
76 76 extern void ceph_auth_destroy(struct ceph_auth_client *ac);
77 77  
78 78 extern void ceph_auth_reset(struct ceph_auth_client *ac);
include/linux/ceph/libceph.h
... ... @@ -61,7 +61,7 @@
61 61 pointer type of args */
62 62 int num_mon;
63 63 char *name;
64   - char *secret;
  64 + struct ceph_crypto_key *key;
65 65 };
66 66  
67 67 /*
... ... @@ -35,12 +35,12 @@
35 35 /*
36 36 * setup, teardown.
37 37 */
38   -struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret)
  38 +struct ceph_auth_client *ceph_auth_init(const char *name, const struct ceph_crypto_key *key)
39 39 {
40 40 struct ceph_auth_client *ac;
41 41 int ret;
42 42  
43   - dout("auth_init name '%s' secret '%s'\n", name, secret);
  43 + dout("auth_init name '%s'\n", name);
44 44  
45 45 ret = -ENOMEM;
46 46 ac = kzalloc(sizeof(*ac), GFP_NOFS);
... ... @@ -52,8 +52,8 @@
52 52 ac->name = name;
53 53 else
54 54 ac->name = CEPH_AUTH_NAME_DEFAULT;
55   - dout("auth_init name %s secret %s\n", ac->name, secret);
56   - ac->secret = secret;
  55 + dout("auth_init name %s\n", ac->name);
  56 + ac->key = key;
57 57 return ac;
58 58  
59 59 out:
... ... @@ -662,14 +662,16 @@
662 662 goto out;
663 663  
664 664 ret = -EINVAL;
665   - if (!ac->secret) {
  665 + if (!ac->key) {
666 666 pr_err("no secret set (for auth_x protocol)\n");
667 667 goto out_nomem;
668 668 }
669 669  
670   - ret = ceph_crypto_key_unarmor(&xi->secret, ac->secret);
671   - if (ret)
  670 + ret = ceph_crypto_key_clone(&xi->secret, ac->key);
  671 + if (ret < 0) {
  672 + pr_err("cannot clone key: %d\n", ret);
672 673 goto out_nomem;
  674 + }
673 675  
674 676 xi->starting = true;
675 677 xi->ticket_handlers = RB_ROOT;
net/ceph/ceph_common.c
... ... @@ -20,6 +20,7 @@
20 20 #include <linux/ceph/decode.h>
21 21 #include <linux/ceph/mon_client.h>
22 22 #include <linux/ceph/auth.h>
  23 +#include "crypto.h"
23 24  
24 25  
25 26  
... ... @@ -117,9 +118,29 @@
117 118 if (ret)
118 119 return ret;
119 120  
120   - ret = strcmp_null(opt1->secret, opt2->secret);
121   - if (ret)
122   - return ret;
  121 + if (opt1->key && !opt2->key)
  122 + return -1;
  123 + if (!opt1->key && opt2->key)
  124 + return 1;
  125 + if (opt1->key && opt2->key) {
  126 + if (opt1->key->type != opt2->key->type)
  127 + return -1;
  128 + if (opt1->key->created.tv_sec != opt2->key->created.tv_sec)
  129 + return -1;
  130 + if (opt1->key->created.tv_nsec != opt2->key->created.tv_nsec)
  131 + return -1;
  132 + if (opt1->key->len != opt2->key->len)
  133 + return -1;
  134 + if (opt1->key->key && !opt2->key->key)
  135 + return -1;
  136 + if (!opt1->key->key && opt2->key->key)
  137 + return 1;
  138 + if (opt1->key->key && opt2->key->key) {
  139 + ret = memcmp(opt1->key->key, opt2->key->key, opt1->key->len);
  140 + if (ret)
  141 + return ret;
  142 + }
  143 + }
123 144  
124 145 /* any matching mon ip implies a match */
125 146 for (i = 0; i < opt1->num_mon; i++) {
... ... @@ -203,7 +224,10 @@
203 224 {
204 225 dout("destroy_options %p\n", opt);
205 226 kfree(opt->name);
206   - kfree(opt->secret);
  227 + if (opt->key) {
  228 + ceph_crypto_key_destroy(opt->key);
  229 + kfree(opt->key);
  230 + }
207 231 kfree(opt);
208 232 }
209 233 EXPORT_SYMBOL(ceph_destroy_options);
... ... @@ -295,9 +319,14 @@
295 319 GFP_KERNEL);
296 320 break;
297 321 case Opt_secret:
298   - opt->secret = kstrndup(argstr[0].from,
299   - argstr[0].to-argstr[0].from,
300   - GFP_KERNEL);
  322 + opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
  323 + if (!opt->key) {
  324 + err = -ENOMEM;
  325 + goto out;
  326 + }
  327 + err = ceph_crypto_key_unarmor(opt->key, argstr[0].from);
  328 + if (err < 0)
  329 + goto out;
301 330 break;
302 331  
303 332 /* misc */
... ... @@ -9,6 +9,17 @@
9 9 #include <linux/ceph/decode.h>
10 10 #include "crypto.h"
11 11  
  12 +int ceph_crypto_key_clone(struct ceph_crypto_key *dst,
  13 + const struct ceph_crypto_key *src)
  14 +{
  15 + memcpy(dst, src, sizeof(struct ceph_crypto_key));
  16 + dst->key = kmalloc(src->len, GFP_NOFS);
  17 + if (!dst->key)
  18 + return -ENOMEM;
  19 + memcpy(dst->key, src->key, src->len);
  20 + return 0;
  21 +}
  22 +
12 23 int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end)
13 24 {
14 25 if (*p + sizeof(u16) + sizeof(key->created) +
... ... @@ -19,6 +19,8 @@
19 19 kfree(key->key);
20 20 }
21 21  
  22 +extern int ceph_crypto_key_clone(struct ceph_crypto_key *dst,
  23 + const struct ceph_crypto_key *src);
22 24 extern int ceph_crypto_key_encode(struct ceph_crypto_key *key,
23 25 void **p, void *end);
24 26 extern int ceph_crypto_key_decode(struct ceph_crypto_key *key,
net/ceph/mon_client.c
... ... @@ -759,7 +759,7 @@
759 759  
760 760 /* authentication */
761 761 monc->auth = ceph_auth_init(cl->options->name,
762   - cl->options->secret);
  762 + cl->options->key);
763 763 if (IS_ERR(monc->auth))
764 764 return PTR_ERR(monc->auth);
765 765 monc->auth->want_keys =