aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTommi Virtanen <tommi.virtanen@dreamhost.com>2011-03-25 19:32:57 -0400
committerSage Weil <sage@newdream.net>2011-03-29 15:11:16 -0400
commit8323c3aa74cd92465350294567142d12ffdcc963 (patch)
tree052e7374393994eea8d534f98ee1bc7acea4c2d9
parentfbdb9190482fd83a3eb20cdeb0da454759f479d7 (diff)
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>
-rw-r--r--fs/ceph/super.c2
-rw-r--r--include/linux/ceph/auth.h4
-rw-r--r--include/linux/ceph/libceph.h2
-rw-r--r--net/ceph/auth.c8
-rw-r--r--net/ceph/auth_x.c8
-rw-r--r--net/ceph/ceph_common.c43
-rw-r--r--net/ceph/crypto.c11
-rw-r--r--net/ceph/crypto.h2
-rw-r--r--net/ceph/mon_client.c2
9 files changed, 63 insertions, 19 deletions
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index a9e78b4a258c..f2f77fd3c14c 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -353,7 +353,7 @@ static int ceph_show_options(struct seq_file *m, struct vfsmount *mnt)
353 353
354 if (opt->name) 354 if (opt->name)
355 seq_printf(m, ",name=%s", opt->name); 355 seq_printf(m, ",name=%s", opt->name);
356 if (opt->secret) 356 if (opt->key)
357 seq_puts(m, ",secret=<hidden>"); 357 seq_puts(m, ",secret=<hidden>");
358 358
359 if (opt->mount_timeout != CEPH_MOUNT_TIMEOUT_DEFAULT) 359 if (opt->mount_timeout != CEPH_MOUNT_TIMEOUT_DEFAULT)
diff --git a/include/linux/ceph/auth.h b/include/linux/ceph/auth.h
index 7fff521d7eb5..aa13392a7efb 100644
--- a/include/linux/ceph/auth.h
+++ b/include/linux/ceph/auth.h
@@ -67,12 +67,12 @@ struct ceph_auth_client {
67 bool negotiating; /* true if negotiating protocol */ 67 bool negotiating; /* true if negotiating protocol */
68 const char *name; /* entity name */ 68 const char *name; /* entity name */
69 u64 global_id; /* our unique id in system */ 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 unsigned want_keys; /* which services we want */ 71 unsigned want_keys; /* which services we want */
72}; 72};
73 73
74extern struct ceph_auth_client *ceph_auth_init(const char *name, 74extern struct ceph_auth_client *ceph_auth_init(const char *name,
75 const char *secret); 75 const struct ceph_crypto_key *key);
76extern void ceph_auth_destroy(struct ceph_auth_client *ac); 76extern void ceph_auth_destroy(struct ceph_auth_client *ac);
77 77
78extern void ceph_auth_reset(struct ceph_auth_client *ac); 78extern void ceph_auth_reset(struct ceph_auth_client *ac);
diff --git a/include/linux/ceph/libceph.h b/include/linux/ceph/libceph.h
index 0d2e0fffb470..6365f041745b 100644
--- a/include/linux/ceph/libceph.h
+++ b/include/linux/ceph/libceph.h
@@ -61,7 +61,7 @@ struct ceph_options {
61 pointer type of args */ 61 pointer type of args */
62 int num_mon; 62 int num_mon;
63 char *name; 63 char *name;
64 char *secret; 64 struct ceph_crypto_key *key;
65}; 65};
66 66
67/* 67/*
diff --git a/net/ceph/auth.c b/net/ceph/auth.c
index 549c1f43e1d5..b4bf4ac090f1 100644
--- a/net/ceph/auth.c
+++ b/net/ceph/auth.c
@@ -35,12 +35,12 @@ static int ceph_auth_init_protocol(struct ceph_auth_client *ac, int protocol)
35/* 35/*
36 * setup, teardown. 36 * setup, teardown.
37 */ 37 */
38struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret) 38struct ceph_auth_client *ceph_auth_init(const char *name, const struct ceph_crypto_key *key)
39{ 39{
40 struct ceph_auth_client *ac; 40 struct ceph_auth_client *ac;
41 int ret; 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 ret = -ENOMEM; 45 ret = -ENOMEM;
46 ac = kzalloc(sizeof(*ac), GFP_NOFS); 46 ac = kzalloc(sizeof(*ac), GFP_NOFS);
@@ -52,8 +52,8 @@ struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret)
52 ac->name = name; 52 ac->name = name;
53 else 53 else
54 ac->name = CEPH_AUTH_NAME_DEFAULT; 54 ac->name = CEPH_AUTH_NAME_DEFAULT;
55 dout("auth_init name %s secret %s\n", ac->name, secret); 55 dout("auth_init name %s\n", ac->name);
56 ac->secret = secret; 56 ac->key = key;
57 return ac; 57 return ac;
58 58
59out: 59out:
diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c
index 7fd5dfcf6e18..1587dc6010c6 100644
--- a/net/ceph/auth_x.c
+++ b/net/ceph/auth_x.c
@@ -662,14 +662,16 @@ int ceph_x_init(struct ceph_auth_client *ac)
662 goto out; 662 goto out;
663 663
664 ret = -EINVAL; 664 ret = -EINVAL;
665 if (!ac->secret) { 665 if (!ac->key) {
666 pr_err("no secret set (for auth_x protocol)\n"); 666 pr_err("no secret set (for auth_x protocol)\n");
667 goto out_nomem; 667 goto out_nomem;
668 } 668 }
669 669
670 ret = ceph_crypto_key_unarmor(&xi->secret, ac->secret); 670 ret = ceph_crypto_key_clone(&xi->secret, ac->key);
671 if (ret) 671 if (ret < 0) {
672 pr_err("cannot clone key: %d\n", ret);
672 goto out_nomem; 673 goto out_nomem;
674 }
673 675
674 xi->starting = true; 676 xi->starting = true;
675 xi->ticket_handlers = RB_ROOT; 677 xi->ticket_handlers = RB_ROOT;
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c
index 9bbb356b12e7..02e084f29d24 100644
--- a/net/ceph/ceph_common.c
+++ b/net/ceph/ceph_common.c
@@ -20,6 +20,7 @@
20#include <linux/ceph/decode.h> 20#include <linux/ceph/decode.h>
21#include <linux/ceph/mon_client.h> 21#include <linux/ceph/mon_client.h>
22#include <linux/ceph/auth.h> 22#include <linux/ceph/auth.h>
23#include "crypto.h"
23 24
24 25
25 26
@@ -117,9 +118,29 @@ int ceph_compare_options(struct ceph_options *new_opt,
117 if (ret) 118 if (ret)
118 return ret; 119 return ret;
119 120
120 ret = strcmp_null(opt1->secret, opt2->secret); 121 if (opt1->key && !opt2->key)
121 if (ret) 122 return -1;
122 return ret; 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 /* any matching mon ip implies a match */ 145 /* any matching mon ip implies a match */
125 for (i = 0; i < opt1->num_mon; i++) { 146 for (i = 0; i < opt1->num_mon; i++) {
@@ -203,7 +224,10 @@ void ceph_destroy_options(struct ceph_options *opt)
203{ 224{
204 dout("destroy_options %p\n", opt); 225 dout("destroy_options %p\n", opt);
205 kfree(opt->name); 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 kfree(opt); 231 kfree(opt);
208} 232}
209EXPORT_SYMBOL(ceph_destroy_options); 233EXPORT_SYMBOL(ceph_destroy_options);
@@ -295,9 +319,14 @@ int ceph_parse_options(struct ceph_options **popt, char *options,
295 GFP_KERNEL); 319 GFP_KERNEL);
296 break; 320 break;
297 case Opt_secret: 321 case Opt_secret:
298 opt->secret = kstrndup(argstr[0].from, 322 opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
299 argstr[0].to-argstr[0].from, 323 if (!opt->key) {
300 GFP_KERNEL); 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 break; 330 break;
302 331
303 /* misc */ 332 /* misc */
diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c
index 7b505b0c983f..75f0893fa11f 100644
--- a/net/ceph/crypto.c
+++ b/net/ceph/crypto.c
@@ -9,6 +9,17 @@
9#include <linux/ceph/decode.h> 9#include <linux/ceph/decode.h>
10#include "crypto.h" 10#include "crypto.h"
11 11
12int 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
12int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end) 23int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end)
13{ 24{
14 if (*p + sizeof(u16) + sizeof(key->created) + 25 if (*p + sizeof(u16) + sizeof(key->created) +
diff --git a/net/ceph/crypto.h b/net/ceph/crypto.h
index f9eccace592b..6cf6edc91ec4 100644
--- a/net/ceph/crypto.h
+++ b/net/ceph/crypto.h
@@ -19,6 +19,8 @@ static inline void ceph_crypto_key_destroy(struct ceph_crypto_key *key)
19 kfree(key->key); 19 kfree(key->key);
20} 20}
21 21
22extern int ceph_crypto_key_clone(struct ceph_crypto_key *dst,
23 const struct ceph_crypto_key *src);
22extern int ceph_crypto_key_encode(struct ceph_crypto_key *key, 24extern int ceph_crypto_key_encode(struct ceph_crypto_key *key,
23 void **p, void *end); 25 void **p, void *end);
24extern int ceph_crypto_key_decode(struct ceph_crypto_key *key, 26extern int ceph_crypto_key_decode(struct ceph_crypto_key *key,
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c
index 8a079399174a..cbe31fa45508 100644
--- a/net/ceph/mon_client.c
+++ b/net/ceph/mon_client.c
@@ -759,7 +759,7 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
759 759
760 /* authentication */ 760 /* authentication */
761 monc->auth = ceph_auth_init(cl->options->name, 761 monc->auth = ceph_auth_init(cl->options->name,
762 cl->options->secret); 762 cl->options->key);
763 if (IS_ERR(monc->auth)) 763 if (IS_ERR(monc->auth))
764 return PTR_ERR(monc->auth); 764 return PTR_ERR(monc->auth);
765 monc->auth->want_keys = 765 monc->auth->want_keys =