diff options
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: |
