Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Tommi Virtanen and committed by
Sage Weil
e2c3d29b 8323c3aa

+59
+1
net/ceph/Kconfig
··· 4 4 select LIBCRC32C 5 5 select CRYPTO_AES 6 6 select CRYPTO 7 + select KEYS 7 8 default n 8 9 help 9 10 Choose Y or M here to include cephlib, which provides the
+58
net/ceph/ceph_common.c
··· 5 5 #include <linux/fs.h> 6 6 #include <linux/inet.h> 7 7 #include <linux/in6.h> 8 + #include <linux/key.h> 9 + #include <keys/user-type.h> 8 10 #include <linux/module.h> 9 11 #include <linux/mount.h> 10 12 #include <linux/parser.h> ··· 199 197 Opt_fsid, 200 198 Opt_name, 201 199 Opt_secret, 200 + Opt_key, 202 201 Opt_ip, 203 202 Opt_last_string, 204 203 /* string args above */ ··· 216 213 {Opt_fsid, "fsid=%s"}, 217 214 {Opt_name, "name=%s"}, 218 215 {Opt_secret, "secret=%s"}, 216 + {Opt_key, "key=%s"}, 219 217 {Opt_ip, "ip=%s"}, 220 218 /* string args above */ 221 219 {Opt_noshare, "noshare"}, ··· 235 231 kfree(opt); 236 232 } 237 233 EXPORT_SYMBOL(ceph_destroy_options); 234 + 235 + /* get secret from key store */ 236 + static int get_secret(struct ceph_crypto_key *dst, const char *name) { 237 + struct key *ukey; 238 + int key_err; 239 + int err = 0; 240 + struct user_key_payload *payload; 241 + void *p; 242 + 243 + ukey = request_key(&key_type_user, name, NULL); 244 + if (!ukey || IS_ERR(ukey)) { 245 + /* request_key errors don't map nicely to mount(2) 246 + errors; don't even try, but still printk */ 247 + key_err = PTR_ERR(ukey); 248 + switch (key_err) { 249 + case -ENOKEY: 250 + pr_warning("ceph: Mount failed due to key not found: %s\n", name); 251 + break; 252 + case -EKEYEXPIRED: 253 + pr_warning("ceph: Mount failed due to expired key: %s\n", name); 254 + break; 255 + case -EKEYREVOKED: 256 + pr_warning("ceph: Mount failed due to revoked key: %s\n", name); 257 + break; 258 + default: 259 + pr_warning("ceph: Mount failed due to unknown key error" 260 + " %d: %s\n", key_err, name); 261 + } 262 + err = -EPERM; 263 + goto out; 264 + } 265 + 266 + payload = ukey->payload.data; 267 + p = payload->data; 268 + err = ceph_crypto_key_decode(dst, &p, p + payload->datalen); 269 + if (err) 270 + goto out_key; 271 + /* pass through, err is 0 */ 272 + 273 + out_key: 274 + key_put(ukey); 275 + out: 276 + return err; 277 + } 238 278 239 279 int ceph_parse_options(struct ceph_options **popt, char *options, 240 280 const char *dev_name, const char *dev_name_end, ··· 373 325 goto out; 374 326 } 375 327 err = ceph_crypto_key_unarmor(opt->key, argstr[0].from); 328 + if (err < 0) 329 + goto out; 330 + break; 331 + case Opt_key: 332 + opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL); 333 + if (!opt->key) { 334 + err = -ENOMEM; 335 + goto out; 336 + } 337 + err = get_secret(opt->key, argstr[0].from); 376 338 if (err < 0) 377 339 goto out; 378 340 break;