aboutsummaryrefslogtreecommitdiffstats
path: root/net/ceph/ceph_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ceph/ceph_common.c')
-rw-r--r--net/ceph/ceph_common.c113
1 files changed, 103 insertions, 10 deletions
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c
index f3e4a13fea0..132963abc26 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/ceph-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>
@@ -20,6 +22,7 @@
20#include <linux/ceph/decode.h> 22#include <linux/ceph/decode.h>
21#include <linux/ceph/mon_client.h> 23#include <linux/ceph/mon_client.h>
22#include <linux/ceph/auth.h> 24#include <linux/ceph/auth.h>
25#include "crypto.h"
23 26
24 27
25 28
@@ -62,6 +65,7 @@ const char *ceph_msg_type_name(int type)
62 case CEPH_MSG_OSD_MAP: return "osd_map"; 65 case CEPH_MSG_OSD_MAP: return "osd_map";
63 case CEPH_MSG_OSD_OP: return "osd_op"; 66 case CEPH_MSG_OSD_OP: return "osd_op";
64 case CEPH_MSG_OSD_OPREPLY: return "osd_opreply"; 67 case CEPH_MSG_OSD_OPREPLY: return "osd_opreply";
68 case CEPH_MSG_WATCH_NOTIFY: return "watch_notify";
65 default: return "unknown"; 69 default: return "unknown";
66 } 70 }
67} 71}
@@ -116,9 +120,29 @@ int ceph_compare_options(struct ceph_options *new_opt,
116 if (ret) 120 if (ret)
117 return ret; 121 return ret;
118 122
119 ret = strcmp_null(opt1->secret, opt2->secret); 123 if (opt1->key && !opt2->key)
120 if (ret) 124 return -1;
121 return ret; 125 if (!opt1->key && opt2->key)
126 return 1;
127 if (opt1->key && opt2->key) {
128 if (opt1->key->type != opt2->key->type)
129 return -1;
130 if (opt1->key->created.tv_sec != opt2->key->created.tv_sec)
131 return -1;
132 if (opt1->key->created.tv_nsec != opt2->key->created.tv_nsec)
133 return -1;
134 if (opt1->key->len != opt2->key->len)
135 return -1;
136 if (opt1->key->key && !opt2->key->key)
137 return -1;
138 if (!opt1->key->key && opt2->key->key)
139 return 1;
140 if (opt1->key->key && opt2->key->key) {
141 ret = memcmp(opt1->key->key, opt2->key->key, opt1->key->len);
142 if (ret)
143 return ret;
144 }
145 }
122 146
123 /* any matching mon ip implies a match */ 147 /* any matching mon ip implies a match */
124 for (i = 0; i < opt1->num_mon; i++) { 148 for (i = 0; i < opt1->num_mon; i++) {
@@ -175,6 +199,7 @@ enum {
175 Opt_fsid, 199 Opt_fsid,
176 Opt_name, 200 Opt_name,
177 Opt_secret, 201 Opt_secret,
202 Opt_key,
178 Opt_ip, 203 Opt_ip,
179 Opt_last_string, 204 Opt_last_string,
180 /* string args above */ 205 /* string args above */
@@ -191,6 +216,7 @@ static match_table_t opt_tokens = {
191 {Opt_fsid, "fsid=%s"}, 216 {Opt_fsid, "fsid=%s"},
192 {Opt_name, "name=%s"}, 217 {Opt_name, "name=%s"},
193 {Opt_secret, "secret=%s"}, 218 {Opt_secret, "secret=%s"},
219 {Opt_key, "key=%s"},
194 {Opt_ip, "ip=%s"}, 220 {Opt_ip, "ip=%s"},
195 /* string args above */ 221 /* string args above */
196 {Opt_noshare, "noshare"}, 222 {Opt_noshare, "noshare"},
@@ -202,11 +228,56 @@ void ceph_destroy_options(struct ceph_options *opt)
202{ 228{
203 dout("destroy_options %p\n", opt); 229 dout("destroy_options %p\n", opt);
204 kfree(opt->name); 230 kfree(opt->name);
205 kfree(opt->secret); 231 if (opt->key) {
232 ceph_crypto_key_destroy(opt->key);
233 kfree(opt->key);
234 }
206 kfree(opt); 235 kfree(opt);
207} 236}
208EXPORT_SYMBOL(ceph_destroy_options); 237EXPORT_SYMBOL(ceph_destroy_options);
209 238
239/* get secret from key store */
240static 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 ceph_crypto_key *ckey;
245
246 ukey = request_key(&key_type_ceph, name, NULL);
247 if (!ukey || IS_ERR(ukey)) {
248 /* request_key errors don't map nicely to mount(2)
249 errors; don't even try, but still printk */
250 key_err = PTR_ERR(ukey);
251 switch (key_err) {
252 case -ENOKEY:
253 pr_warning("ceph: Mount failed due to key not found: %s\n", name);
254 break;
255 case -EKEYEXPIRED:
256 pr_warning("ceph: Mount failed due to expired key: %s\n", name);
257 break;
258 case -EKEYREVOKED:
259 pr_warning("ceph: Mount failed due to revoked key: %s\n", name);
260 break;
261 default:
262 pr_warning("ceph: Mount failed due to unknown key error"
263 " %d: %s\n", key_err, name);
264 }
265 err = -EPERM;
266 goto out;
267 }
268
269 ckey = ukey->payload.data;
270 err = ceph_crypto_key_clone(dst, ckey);
271 if (err)
272 goto out_key;
273 /* pass through, err is 0 */
274
275out_key:
276 key_put(ukey);
277out:
278 return err;
279}
280
210int ceph_parse_options(struct ceph_options **popt, char *options, 281int ceph_parse_options(struct ceph_options **popt, char *options,
211 const char *dev_name, const char *dev_name_end, 282 const char *dev_name, const char *dev_name_end,
212 int (*parse_extra_token)(char *c, void *private), 283 int (*parse_extra_token)(char *c, void *private),
@@ -294,9 +365,24 @@ int ceph_parse_options(struct ceph_options **popt, char *options,
294 GFP_KERNEL); 365 GFP_KERNEL);
295 break; 366 break;
296 case Opt_secret: 367 case Opt_secret:
297 opt->secret = kstrndup(argstr[0].from, 368 opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
298 argstr[0].to-argstr[0].from, 369 if (!opt->key) {
299 GFP_KERNEL); 370 err = -ENOMEM;
371 goto out;
372 }
373 err = ceph_crypto_key_unarmor(opt->key, argstr[0].from);
374 if (err < 0)
375 goto out;
376 break;
377 case Opt_key:
378 opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
379 if (!opt->key) {
380 err = -ENOMEM;
381 goto out;
382 }
383 err = get_secret(opt->key, argstr[0].from);
384 if (err < 0)
385 goto out;
300 break; 386 break;
301 387
302 /* misc */ 388 /* misc */
@@ -393,8 +479,8 @@ void ceph_destroy_client(struct ceph_client *client)
393 ceph_osdc_stop(&client->osdc); 479 ceph_osdc_stop(&client->osdc);
394 480
395 /* 481 /*
396 * make sure mds and osd connections close out before destroying 482 * make sure osd connections close out before destroying the
397 * the auth module, which is needed to free those connections' 483 * auth module, which is needed to free those connections'
398 * ceph_authorizers. 484 * ceph_authorizers.
399 */ 485 */
400 ceph_msgr_flush(); 486 ceph_msgr_flush();
@@ -495,10 +581,14 @@ static int __init init_ceph_lib(void)
495 if (ret < 0) 581 if (ret < 0)
496 goto out; 582 goto out;
497 583
498 ret = ceph_msgr_init(); 584 ret = ceph_crypto_init();
499 if (ret < 0) 585 if (ret < 0)
500 goto out_debugfs; 586 goto out_debugfs;
501 587
588 ret = ceph_msgr_init();
589 if (ret < 0)
590 goto out_crypto;
591
502 pr_info("loaded (mon/osd proto %d/%d, osdmap %d/%d %d/%d)\n", 592 pr_info("loaded (mon/osd proto %d/%d, osdmap %d/%d %d/%d)\n",
503 CEPH_MONC_PROTOCOL, CEPH_OSDC_PROTOCOL, 593 CEPH_MONC_PROTOCOL, CEPH_OSDC_PROTOCOL,
504 CEPH_OSDMAP_VERSION, CEPH_OSDMAP_VERSION_EXT, 594 CEPH_OSDMAP_VERSION, CEPH_OSDMAP_VERSION_EXT,
@@ -506,6 +596,8 @@ static int __init init_ceph_lib(void)
506 596
507 return 0; 597 return 0;
508 598
599out_crypto:
600 ceph_crypto_shutdown();
509out_debugfs: 601out_debugfs:
510 ceph_debugfs_cleanup(); 602 ceph_debugfs_cleanup();
511out: 603out:
@@ -516,6 +608,7 @@ static void __exit exit_ceph_lib(void)
516{ 608{
517 dout("exit_ceph_lib\n"); 609 dout("exit_ceph_lib\n");
518 ceph_msgr_exit(); 610 ceph_msgr_exit();
611 ceph_crypto_shutdown();
519 ceph_debugfs_cleanup(); 612 ceph_debugfs_cleanup();
520} 613}
521 614