diff options
author | Tommi Virtanen <tommi.virtanen@dreamhost.com> | 2011-03-25 16:32:57 -0700 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2011-03-29 12:11:16 -0700 |
commit | 8323c3aa74cd92465350294567142d12ffdcc963 (patch) | |
tree | 052e7374393994eea8d534f98ee1bc7acea4c2d9 | |
parent | fbdb9190482fd83a3eb20cdeb0da454759f479d7 (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.c | 2 | ||||
-rw-r--r-- | include/linux/ceph/auth.h | 4 | ||||
-rw-r--r-- | include/linux/ceph/libceph.h | 2 | ||||
-rw-r--r-- | net/ceph/auth.c | 8 | ||||
-rw-r--r-- | net/ceph/auth_x.c | 8 | ||||
-rw-r--r-- | net/ceph/ceph_common.c | 43 | ||||
-rw-r--r-- | net/ceph/crypto.c | 11 | ||||
-rw-r--r-- | net/ceph/crypto.h | 2 | ||||
-rw-r--r-- | net/ceph/mon_client.c | 2 |
9 files changed, 63 insertions, 19 deletions
diff --git a/fs/ceph/super.c b/fs/ceph/super.c index a9e78b4a258..f2f77fd3c14 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) if (opt->name) seq_printf(m, ",name=%s", opt->name); - if (opt->secret) + if (opt->key) seq_puts(m, ",secret=<hidden>"); if (opt->mount_timeout != CEPH_MOUNT_TIMEOUT_DEFAULT) diff --git a/include/linux/ceph/auth.h b/include/linux/ceph/auth.h index 7fff521d7eb..aa13392a7ef 100644 --- a/include/linux/ceph/auth.h +++ b/include/linux/ceph/auth.h @@ -67,12 +67,12 @@ struct ceph_auth_client { bool negotiating; /* true if negotiating protocol */ const char *name; /* entity name */ u64 global_id; /* our unique id in system */ - const char *secret; /* our secret key */ + const struct ceph_crypto_key *key; /* our secret key */ unsigned want_keys; /* which services we want */ }; extern struct ceph_auth_client *ceph_auth_init(const char *name, - const char *secret); + const struct ceph_crypto_key *key); extern void ceph_auth_destroy(struct ceph_auth_client *ac); extern void ceph_auth_reset(struct ceph_auth_client *ac); diff --git a/include/linux/ceph/libceph.h b/include/linux/ceph/libceph.h index 0d2e0fffb47..6365f041745 100644 --- a/include/linux/ceph/libceph.h +++ b/include/linux/ceph/libceph.h @@ -61,7 +61,7 @@ struct ceph_options { pointer type of args */ int num_mon; char *name; - char *secret; + struct ceph_crypto_key *key; }; /* diff --git a/net/ceph/auth.c b/net/ceph/auth.c index 549c1f43e1d..b4bf4ac090f 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) /* * setup, teardown. */ -struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret) +struct ceph_auth_client *ceph_auth_init(const char *name, const struct ceph_crypto_key *key) { struct ceph_auth_client *ac; int ret; - dout("auth_init name '%s' secret '%s'\n", name, secret); + dout("auth_init name '%s'\n", name); ret = -ENOMEM; ac = kzalloc(sizeof(*ac), GFP_NOFS); @@ -52,8 +52,8 @@ struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret) ac->name = name; else ac->name = CEPH_AUTH_NAME_DEFAULT; - dout("auth_init name %s secret %s\n", ac->name, secret); - ac->secret = secret; + dout("auth_init name %s\n", ac->name); + ac->key = key; return ac; out: diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c index 7fd5dfcf6e1..1587dc6010c 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) goto out; ret = -EINVAL; - if (!ac->secret) { + if (!ac->key) { pr_err("no secret set (for auth_x protocol)\n"); goto out_nomem; } - ret = ceph_crypto_key_unarmor(&xi->secret, ac->secret); - if (ret) + ret = ceph_crypto_key_clone(&xi->secret, ac->key); + if (ret < 0) { + pr_err("cannot clone key: %d\n", ret); goto out_nomem; + } xi->starting = true; xi->ticket_handlers = RB_ROOT; diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index 9bbb356b12e..02e084f29d2 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c @@ -20,6 +20,7 @@ #include <linux/ceph/decode.h> #include <linux/ceph/mon_client.h> #include <linux/ceph/auth.h> +#include "crypto.h" @@ -117,9 +118,29 @@ int ceph_compare_options(struct ceph_options *new_opt, if (ret) return ret; - ret = strcmp_null(opt1->secret, opt2->secret); - if (ret) - return ret; + if (opt1->key && !opt2->key) + return -1; + if (!opt1->key && opt2->key) + return 1; + if (opt1->key && opt2->key) { + if (opt1->key->type != opt2->key->type) + return -1; + if (opt1->key->created.tv_sec != opt2->key->created.tv_sec) + return -1; + if (opt1->key->created.tv_nsec != opt2->key->created.tv_nsec) + return -1; + if (opt1->key->len != opt2->key->len) + return -1; + if (opt1->key->key && !opt2->key->key) + return -1; + if (!opt1->key->key && opt2->key->key) + return 1; + if (opt1->key->key && opt2->key->key) { + ret = memcmp(opt1->key->key, opt2->key->key, opt1->key->len); + if (ret) + return ret; + } + } /* any matching mon ip implies a match */ for (i = 0; i < opt1->num_mon; i++) { @@ -203,7 +224,10 @@ void ceph_destroy_options(struct ceph_options *opt) { dout("destroy_options %p\n", opt); kfree(opt->name); - kfree(opt->secret); + if (opt->key) { + ceph_crypto_key_destroy(opt->key); + kfree(opt->key); + } kfree(opt); } EXPORT_SYMBOL(ceph_destroy_options); @@ -295,9 +319,14 @@ int ceph_parse_options(struct ceph_options **popt, char *options, GFP_KERNEL); break; case Opt_secret: - opt->secret = kstrndup(argstr[0].from, - argstr[0].to-argstr[0].from, - GFP_KERNEL); + opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL); + if (!opt->key) { + err = -ENOMEM; + goto out; + } + err = ceph_crypto_key_unarmor(opt->key, argstr[0].from); + if (err < 0) + goto out; break; /* misc */ diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c index 7b505b0c983..75f0893fa11 100644 --- a/net/ceph/crypto.c +++ b/net/ceph/crypto.c @@ -9,6 +9,17 @@ #include <linux/ceph/decode.h> #include "crypto.h" +int ceph_crypto_key_clone(struct ceph_crypto_key *dst, + const struct ceph_crypto_key *src) +{ + memcpy(dst, src, sizeof(struct ceph_crypto_key)); + dst->key = kmalloc(src->len, GFP_NOFS); + if (!dst->key) + return -ENOMEM; + memcpy(dst->key, src->key, src->len); + return 0; +} + int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end) { if (*p + sizeof(u16) + sizeof(key->created) + diff --git a/net/ceph/crypto.h b/net/ceph/crypto.h index f9eccace592..6cf6edc91ec 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) kfree(key->key); } +extern int ceph_crypto_key_clone(struct ceph_crypto_key *dst, + const struct ceph_crypto_key *src); extern int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end); extern 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 8a079399174..cbe31fa4550 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) /* authentication */ monc->auth = ceph_auth_init(cl->options->name, - cl->options->secret); + cl->options->key); if (IS_ERR(monc->auth)) return PTR_ERR(monc->auth); monc->auth->want_keys = |