diff options
author | Tommi Virtanen <tommi.virtanen@dreamhost.com> | 2011-03-25 19:40:48 -0400 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2011-03-29 15:11:19 -0400 |
commit | e2c3d29b4295c3eec18294bc34f0c99a7b9ae413 (patch) | |
tree | 29fbffeeed7e2774a4f87883ae01798079d85ed2 /net | |
parent | 8323c3aa74cd92465350294567142d12ffdcc963 (diff) |
libceph: Get secret from the kernel keys api when mounting with key=NAME.
Signed-off-by: Tommi Virtanen <tommi.virtanen@dreamhost.com>
Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ceph/Kconfig | 1 | ||||
-rw-r--r-- | net/ceph/ceph_common.c | 58 |
2 files changed, 59 insertions, 0 deletions
diff --git a/net/ceph/Kconfig b/net/ceph/Kconfig index ad424049b0cf..be683f2d401f 100644 --- a/net/ceph/Kconfig +++ b/net/ceph/Kconfig | |||
@@ -4,6 +4,7 @@ config CEPH_LIB | |||
4 | select LIBCRC32C | 4 | select LIBCRC32C |
5 | select CRYPTO_AES | 5 | select CRYPTO_AES |
6 | select CRYPTO | 6 | select CRYPTO |
7 | select KEYS | ||
7 | default n | 8 | default n |
8 | help | 9 | help |
9 | Choose Y or M here to include cephlib, which provides the | 10 | Choose Y or M here to include cephlib, which provides the |
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index 02e084f29d24..c92bc8d50597 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/user-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> |
@@ -197,6 +199,7 @@ enum { | |||
197 | Opt_fsid, | 199 | Opt_fsid, |
198 | Opt_name, | 200 | Opt_name, |
199 | Opt_secret, | 201 | Opt_secret, |
202 | Opt_key, | ||
200 | Opt_ip, | 203 | Opt_ip, |
201 | Opt_last_string, | 204 | Opt_last_string, |
202 | /* string args above */ | 205 | /* string args above */ |
@@ -213,6 +216,7 @@ static match_table_t opt_tokens = { | |||
213 | {Opt_fsid, "fsid=%s"}, | 216 | {Opt_fsid, "fsid=%s"}, |
214 | {Opt_name, "name=%s"}, | 217 | {Opt_name, "name=%s"}, |
215 | {Opt_secret, "secret=%s"}, | 218 | {Opt_secret, "secret=%s"}, |
219 | {Opt_key, "key=%s"}, | ||
216 | {Opt_ip, "ip=%s"}, | 220 | {Opt_ip, "ip=%s"}, |
217 | /* string args above */ | 221 | /* string args above */ |
218 | {Opt_noshare, "noshare"}, | 222 | {Opt_noshare, "noshare"}, |
@@ -232,6 +236,50 @@ void ceph_destroy_options(struct ceph_options *opt) | |||
232 | } | 236 | } |
233 | EXPORT_SYMBOL(ceph_destroy_options); | 237 | EXPORT_SYMBOL(ceph_destroy_options); |
234 | 238 | ||
239 | /* get secret from key store */ | ||
240 | static 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 user_key_payload *payload; | ||
245 | void *p; | ||
246 | |||
247 | ukey = request_key(&key_type_user, name, NULL); | ||
248 | if (!ukey || IS_ERR(ukey)) { | ||
249 | /* request_key errors don't map nicely to mount(2) | ||
250 | errors; don't even try, but still printk */ | ||
251 | key_err = PTR_ERR(ukey); | ||
252 | switch (key_err) { | ||
253 | case -ENOKEY: | ||
254 | pr_warning("ceph: Mount failed due to key not found: %s\n", name); | ||
255 | break; | ||
256 | case -EKEYEXPIRED: | ||
257 | pr_warning("ceph: Mount failed due to expired key: %s\n", name); | ||
258 | break; | ||
259 | case -EKEYREVOKED: | ||
260 | pr_warning("ceph: Mount failed due to revoked key: %s\n", name); | ||
261 | break; | ||
262 | default: | ||
263 | pr_warning("ceph: Mount failed due to unknown key error" | ||
264 | " %d: %s\n", key_err, name); | ||
265 | } | ||
266 | err = -EPERM; | ||
267 | goto out; | ||
268 | } | ||
269 | |||
270 | payload = ukey->payload.data; | ||
271 | p = payload->data; | ||
272 | err = ceph_crypto_key_decode(dst, &p, p + payload->datalen); | ||
273 | if (err) | ||
274 | goto out_key; | ||
275 | /* pass through, err is 0 */ | ||
276 | |||
277 | out_key: | ||
278 | key_put(ukey); | ||
279 | out: | ||
280 | return err; | ||
281 | } | ||
282 | |||
235 | int ceph_parse_options(struct ceph_options **popt, char *options, | 283 | int ceph_parse_options(struct ceph_options **popt, char *options, |
236 | const char *dev_name, const char *dev_name_end, | 284 | const char *dev_name, const char *dev_name_end, |
237 | int (*parse_extra_token)(char *c, void *private), | 285 | int (*parse_extra_token)(char *c, void *private), |
@@ -328,6 +376,16 @@ int ceph_parse_options(struct ceph_options **popt, char *options, | |||
328 | if (err < 0) | 376 | if (err < 0) |
329 | goto out; | 377 | goto out; |
330 | break; | 378 | break; |
379 | case Opt_key: | ||
380 | opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL); | ||
381 | if (!opt->key) { | ||
382 | err = -ENOMEM; | ||
383 | goto out; | ||
384 | } | ||
385 | err = get_secret(opt->key, argstr[0].from); | ||
386 | if (err < 0) | ||
387 | goto out; | ||
388 | break; | ||
331 | 389 | ||
332 | /* misc */ | 390 | /* misc */ |
333 | case Opt_osdtimeout: | 391 | case Opt_osdtimeout: |