History

libceph, ceph: incorporate nautilus cephx changes

- request service tickets together with auth ticket. Currently we get auth ticket via CEPHX_GET_AUTH_SESSION_KEY op and then request service tickets via CEPHX_GET_PRINCIPAL_SESSION_KEY op in a separate message. Since nautilus, desired service tickets are shared togther with auth ticket in CEPHX_GET_AUTH_SESSION_KEY reply. - propagate session key and connection secret, if any. In preparation for msgr2, update handle_reply() and verify_authorizer_reply() auth ops to propagate session key and connection secret. Since nautilus, if secure mode is negotiated, connection secret is shared either in CEPHX_GET_AUTH_SESSION_KEY reply (for mons) or in a final authorizer reply (for osds and mdses).

Ilya Dryomov committed 6 years ago

Commit 285ea341 parent 6610fff8 files · +210 −53Browse files

Unified · Split

8 files
  1. fs/ceph/mds_client.c +4 −1
  2. include/linux/ceph/auth.h +12 −4
  3. net/ceph/auth.c +9 −3
  4. net/ceph/auth_none.c +3 −1
  5. net/ceph/auth_x.c +173 −42
  6. net/ceph/auth_x_protocol.h +2 −1
  7. net/ceph/crypto.h +3 −0
  8. net/ceph/osd_client.c +4 −1
fs/ceph/mds_client.c+4−1
@@ -5178,8 +5178,11 @@ static int verify_authorizer_reply(struct ceph_connection *con) · 5177 unmodified lines
5178 struct ceph_mds_session *s = con->private;5178 struct ceph_mds_session *s = con->private;
5179 struct ceph_mds_client *mdsc = s->s_mdsc;5179 struct ceph_mds_client *mdsc = s->s_mdsc;
5180 struct ceph_auth_client *ac = mdsc->fsc->client->monc.auth;5180 struct ceph_auth_client *ac = mdsc->fsc->client->monc.auth;
5181 struct ceph_auth_handshake *auth = &s->s_auth;
5181 5182
5182 return ceph_auth_verify_authorizer_reply(ac, s->s_auth.authorizer);5183 return ceph_auth_verify_authorizer_reply(ac, auth->authorizer,
5184 auth->authorizer_reply_buf, auth->authorizer_reply_buf_len,
5185 NULL, NULL, NULL, NULL);
5183}5186}
5184 5187
5185static int invalidate_authorizer(struct ceph_connection *con)5188static int invalidate_authorizer(struct ceph_connection *con)
include/linux/ceph/auth.h+12−4
@@ -53,7 +53,9 @@ struct ceph_auth_client_ops { · 52 unmodified lines
53 */53 */
54 int (*build_request)(struct ceph_auth_client *ac, void *buf, void *end);54 int (*build_request)(struct ceph_auth_client *ac, void *buf, void *end);
55 int (*handle_reply)(struct ceph_auth_client *ac, int result,55 int (*handle_reply)(struct ceph_auth_client *ac, int result,
56 void *buf, void *end);56 void *buf, void *end, u8 *session_key,
57 int *session_key_len, u8 *con_secret,
58 int *con_secret_len);
57 59
58 /*60 /*
59 * Create authorizer for connecting to a service, and verify61 * Create authorizer for connecting to a service, and verify
@@ -69,7 +71,10 @@ struct ceph_auth_client_ops { · 9 unmodified lines
69 void *challenge_buf,71 void *challenge_buf,
70 int challenge_buf_len);72 int challenge_buf_len);
71 int (*verify_authorizer_reply)(struct ceph_auth_client *ac,73 int (*verify_authorizer_reply)(struct ceph_auth_client *ac,
72 struct ceph_authorizer *a);74 struct ceph_authorizer *a,
75 void *reply, int reply_len,
76 u8 *session_key, int *session_key_len,
77 u8 *con_secret, int *con_secret_len);
73 void (*invalidate_authorizer)(struct ceph_auth_client *ac,78 void (*invalidate_authorizer)(struct ceph_auth_client *ac,
74 int peer_type);79 int peer_type);
75 80
@@ -126,8 +131,11 @@ int ceph_auth_add_authorizer_challenge(struct ceph_auth_client *ac, · 50 unmodified lines
126 struct ceph_authorizer *a,131 struct ceph_authorizer *a,
127 void *challenge_buf,132 void *challenge_buf,
128 int challenge_buf_len);133 int challenge_buf_len);
129extern int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac,134int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac,
130 struct ceph_authorizer *a);135 struct ceph_authorizer *a,
136 void *reply, int reply_len,
137 u8 *session_key, int *session_key_len,
138 u8 *con_secret, int *con_secret_len);
131extern void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac,139extern void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac,
132 int peer_type);140 int peer_type);
133 141
net/ceph/auth.c+9−3
@@ -240,7 +240,8 @@ int ceph_handle_auth_reply(struct ceph_auth_client *ac, · 239 unmodified lines
240 ac->negotiating = false;240 ac->negotiating = false;
241 }241 }
242 242
243 ret = ac->ops->handle_reply(ac, result, payload, payload_end);243 ret = ac->ops->handle_reply(ac, result, payload, payload_end,
244 NULL, NULL, NULL, NULL);
244 if (ret == -EAGAIN) {245 if (ret == -EAGAIN) {
245 ret = ceph_build_auth_request(ac, reply_buf, reply_len);246 ret = ceph_build_auth_request(ac, reply_buf, reply_len);
246 } else if (ret) {247 } else if (ret) {
@@ -332,13 +333,18 @@ int ceph_auth_add_authorizer_challenge(struct ceph_auth_client *ac, · 85 unmodified lines
332EXPORT_SYMBOL(ceph_auth_add_authorizer_challenge);333EXPORT_SYMBOL(ceph_auth_add_authorizer_challenge);
333 334
334int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac,335int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac,
335 struct ceph_authorizer *a)336 struct ceph_authorizer *a,
337 void *reply, int reply_len,
338 u8 *session_key, int *session_key_len,
339 u8 *con_secret, int *con_secret_len)
336{340{
337 int ret = 0;341 int ret = 0;
338 342
339 mutex_lock(&ac->mutex);343 mutex_lock(&ac->mutex);
340 if (ac->ops && ac->ops->verify_authorizer_reply)344 if (ac->ops && ac->ops->verify_authorizer_reply)
341 ret = ac->ops->verify_authorizer_reply(ac, a);345 ret = ac->ops->verify_authorizer_reply(ac, a,
346 reply, reply_len, session_key, session_key_len,
347 con_secret, con_secret_len);
342 mutex_unlock(&ac->mutex);348 mutex_unlock(&ac->mutex);
343 return ret;349 return ret;
344}350}
net/ceph/auth_none.c+3−1
@@ -70,7 +70,9 @@ static int build_request(struct ceph_auth_client *ac, void *buf, void *end) · 69 unmodified lines
70 * authenticate state, so nothing happens here.70 * authenticate state, so nothing happens here.
71 */71 */
72static int handle_reply(struct ceph_auth_client *ac, int result,72static int handle_reply(struct ceph_auth_client *ac, int result,
73 void *buf, void *end)73 void *buf, void *end, u8 *session_key,
74 int *session_key_len, u8 *con_secret,
75 int *con_secret_len)
74{76{
75 struct ceph_auth_none_info *xi = ac->private;77 struct ceph_auth_none_info *xi = ac->private;
76 78
net/ceph/auth_x.c+173−42
@@ -269,22 +269,21 @@ out: · 268 unmodified lines
269 269
270static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,270static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
271 struct ceph_crypto_key *secret,271 struct ceph_crypto_key *secret,
272 void *buf, void *end)272 void **p, void *end)
273{273{
274 void *p = buf;
275 u8 reply_struct_v;274 u8 reply_struct_v;
276 u32 num;275 u32 num;
277 int ret;276 int ret;
278 277
279 ceph_decode_8_safe(&p, end, reply_struct_v, bad);278 ceph_decode_8_safe(p, end, reply_struct_v, bad);
280 if (reply_struct_v != 1)279 if (reply_struct_v != 1)
281 return -EINVAL;280 return -EINVAL;
282 281
283 ceph_decode_32_safe(&p, end, num, bad);282 ceph_decode_32_safe(p, end, num, bad);
284 dout("%d tickets\n", num);283 dout("%d tickets\n", num);
285 284
286 while (num--) {285 while (num--) {
287 ret = process_one_ticket(ac, secret, &p, end);286 ret = process_one_ticket(ac, secret, p, end);
288 if (ret)287 if (ret)
289 return ret;288 return ret;
290 }289 }
@@ -527,7 +526,7 @@ static int ceph_x_build_request(struct ceph_auth_client *ac, · 236 unmodified lines
527 if (ret < 0)526 if (ret < 0)
528 return ret;527 return ret;
529 528
530 auth->struct_v = 1;529 auth->struct_v = 2; /* nautilus+ */
531 auth->key = 0;530 auth->key = 0;
532 for (u = (u64 *)enc_buf; u + 1 <= (u64 *)(enc_buf + ret); u++)531 for (u = (u64 *)enc_buf; u + 1 <= (u64 *)(enc_buf + ret); u++)
533 auth->key ^= *(__le64 *)u;532 auth->key ^= *(__le64 *)u;
@@ -540,6 +539,10 @@ static int ceph_x_build_request(struct ceph_auth_client *ac, · 6 unmodified lines
540 if (ret < 0)539 if (ret < 0)
541 return ret;540 return ret;
542 541
542 /* nautilus+: request service tickets at the same time */
543 need = ac->want_keys & ~CEPH_ENTITY_TYPE_AUTH;
544 WARN_ON(!need);
545 ceph_encode_32_safe(&p, end, need, e_range);
543 return p - buf;546 return p - buf;
544 }547 }
545 548
@@ -566,8 +569,82 @@ e_range: · 20 unmodified lines
566 return -ERANGE;569 return -ERANGE;
567}570}
568 571
572static int handle_auth_session_key(struct ceph_auth_client *ac,
573 void **p, void *end,
574 u8 *session_key, int *session_key_len,
575 u8 *con_secret, int *con_secret_len)
576{
577 struct ceph_x_info *xi = ac->private;
578 struct ceph_x_ticket_handler *th;
579 void *dp, *dend;
580 int len;
581 int ret;
582
583 /* AUTH ticket */
584 ret = ceph_x_proc_ticket_reply(ac, &xi->secret, p, end);
585 if (ret)
586 return ret;
587
588 if (*p == end) {
589 /* pre-nautilus (or didn't request service tickets!) */
590 WARN_ON(session_key || con_secret);
591 return 0;
592 }
593
594 th = get_ticket_handler(ac, CEPH_ENTITY_TYPE_AUTH);
595 if (IS_ERR(th))
596 return PTR_ERR(th);
597
598 if (session_key) {
599 memcpy(session_key, th->session_key.key, th->session_key.len);
600 *session_key_len = th->session_key.len;
601 }
602
603 /* connection secret */
604 ceph_decode_32_safe(p, end, len, e_inval);
605 dout("%s connection secret blob len %d\n", __func__, len);
606 if (len > 0) {
607 dp = *p + ceph_x_encrypt_offset();
608 ret = ceph_x_decrypt(&th->session_key, p, *p + len);
609 if (ret < 0)
610 return ret;
611
612 dout("%s decrypted %d bytes\n", __func__, ret);
613 dend = dp + ret;
614
615 ceph_decode_32_safe(&dp, dend, len, e_inval);
616 if (len > CEPH_MAX_CON_SECRET_LEN) {
617 pr_err("connection secret too big %d\n", len);
618 return -EINVAL;
619 }
620
621 dout("%s connection secret len %d\n", __func__, len);
622 if (con_secret) {
623 memcpy(con_secret, dp, len);
624 *con_secret_len = len;
625 }
626 }
627
628 /* service tickets */
629 ceph_decode_32_safe(p, end, len, e_inval);
630 dout("%s service tickets blob len %d\n", __func__, len);
631 if (len > 0) {
632 ret = ceph_x_proc_ticket_reply(ac, &th->session_key,
633 p, *p + len);
634 if (ret)
635 return ret;
636 }
637
638 return 0;
639
640e_inval:
641 return -EINVAL;
642}
643
569static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result,644static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result,
570 void *buf, void *end)645 void *buf, void *end,
646 u8 *session_key, int *session_key_len,
647 u8 *con_secret, int *con_secret_len)
571{648{
572 struct ceph_x_info *xi = ac->private;649 struct ceph_x_info *xi = ac->private;
573 struct ceph_x_ticket_handler *th;650 struct ceph_x_ticket_handler *th;
@@ -599,8 +676,10 @@ static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result, · 25 unmodified lines
599 dout("handle_reply op %d result %d\n", op, result);676 dout("handle_reply op %d result %d\n", op, result);
600 switch (op) {677 switch (op) {
601 case CEPHX_GET_AUTH_SESSION_KEY:678 case CEPHX_GET_AUTH_SESSION_KEY:
602 /* verify auth key */679 /* AUTH ticket + [connection secret] + service tickets */
603 ret = ceph_x_proc_ticket_reply(ac, &xi->secret, p, end);680 ret = handle_auth_session_key(ac, &p, end, session_key,
681 session_key_len, con_secret,
682 con_secret_len);
604 break;683 break;
605 684
606 case CEPHX_GET_PRINCIPAL_SESSION_KEY:685 case CEPHX_GET_PRINCIPAL_SESSION_KEY:
@@ -608,7 +687,8 @@ static int ceph_x_handle_reply(struct ceph_auth_client *ac, int result, · 1 unmodified line
608 if (IS_ERR(th))687 if (IS_ERR(th))
609 return PTR_ERR(th);688 return PTR_ERR(th);
610 689
611 ret = ceph_x_proc_ticket_reply(ac, &th->session_key, p, end);690 /* service tickets */
691 ret = ceph_x_proc_ticket_reply(ac, &th->session_key, &p, end);
612 break;692 break;
613 693
614 default:694 default:
@@ -687,40 +767,44 @@ static int ceph_x_update_authorizer( · 72 unmodified lines
687 return 0;767 return 0;
688}768}
689 769
690static int decrypt_authorize_challenge(struct ceph_x_authorizer *au,770/*
691 void *challenge_buf,771 * CephXAuthorizeChallenge
692 int challenge_buf_len,772 */
693 u64 *server_challenge)773static int decrypt_authorizer_challenge(struct ceph_crypto_key *secret,
774 void *challenge, int challenge_len,
775 u64 *server_challenge)
694{776{
695 struct ceph_x_authorize_challenge *ch =777 void *dp, *dend;
696 challenge_buf + sizeof(struct ceph_x_encrypt_header);
697 int ret;778 int ret;
698 779
699 /* no leading len */780 /* no leading len */
700 ret = __ceph_x_decrypt(&au->session_key, challenge_buf,781 ret = __ceph_x_decrypt(secret, challenge, challenge_len);
701 challenge_buf_len);
702 if (ret < 0)782 if (ret < 0)
703 return ret;783 return ret;
704 if (ret < sizeof(*ch)) {
705 pr_err("bad size %d for ceph_x_authorize_challenge\n", ret);
706 return -EINVAL;
707 }
708 784
709 *server_challenge = le64_to_cpu(ch->server_challenge);785 dout("%s decrypted %d bytes\n", __func__, ret);
786 dp = challenge + sizeof(struct ceph_x_encrypt_header);
787 dend = dp + ret;
788
789 ceph_decode_skip_8(&dp, dend, e_inval); /* struct_v */
790 ceph_decode_64_safe(&dp, dend, *server_challenge, e_inval);
791 dout("%s server_challenge %llu\n", __func__, *server_challenge);
710 return 0;792 return 0;
793
794e_inval:
795 return -EINVAL;
711}796}
712 797
713static int ceph_x_add_authorizer_challenge(struct ceph_auth_client *ac,798static int ceph_x_add_authorizer_challenge(struct ceph_auth_client *ac,
714 struct ceph_authorizer *a,799 struct ceph_authorizer *a,
715 void *challenge_buf,800 void *challenge, int challenge_len)
716 int challenge_buf_len)
717{801{
718 struct ceph_x_authorizer *au = (void *)a;802 struct ceph_x_authorizer *au = (void *)a;
719 u64 server_challenge;803 u64 server_challenge;
720 int ret;804 int ret;
721 805
722 ret = decrypt_authorize_challenge(au, challenge_buf, challenge_buf_len,806 ret = decrypt_authorizer_challenge(&au->session_key, challenge,
723 &server_challenge);807 challenge_len, &server_challenge);
724 if (ret) {808 if (ret) {
725 pr_err("failed to decrypt authorize challenge: %d", ret);809 pr_err("failed to decrypt authorize challenge: %d", ret);
726 return ret;810 return ret;
@@ -735,29 +819,76 @@ static int ceph_x_add_authorizer_challenge(struct ceph_auth_client *ac, · 8 unmodified lines
735 return 0;819 return 0;
736}820}
737 821
822/*
823 * CephXAuthorizeReply
824 */
825static int decrypt_authorizer_reply(struct ceph_crypto_key *secret,
826 void **p, void *end, u64 *nonce_plus_one,
827 u8 *con_secret, int *con_secret_len)
828{
829 void *dp, *dend;
830 u8 struct_v;
831 int len;
832 int ret;
833
834 dp = *p + ceph_x_encrypt_offset();
835 ret = ceph_x_decrypt(secret, p, end);
836 if (ret < 0)
837 return ret;
838
839 dout("%s decrypted %d bytes\n", __func__, ret);
840 dend = dp + ret;
841
842 ceph_decode_8_safe(&dp, dend, struct_v, e_inval);
843 ceph_decode_64_safe(&dp, dend, *nonce_plus_one, e_inval);
844 dout("%s nonce_plus_one %llu\n", __func__, *nonce_plus_one);
845 if (struct_v >= 2) {
846 ceph_decode_32_safe(&dp, dend, len, e_inval);
847 if (len > CEPH_MAX_CON_SECRET_LEN) {
848 pr_err("connection secret too big %d\n", len);
849 return -EINVAL;
850 }
851
852 dout("%s connection secret len %d\n", __func__, len);
853 if (con_secret) {
854 memcpy(con_secret, dp, len);
855 *con_secret_len = len;
856 }
857 }
858
859 return 0;
860
861e_inval:
862 return -EINVAL;
863}
864
738static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac,865static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac,
739 struct ceph_authorizer *a)866 struct ceph_authorizer *a,
867 void *reply, int reply_len,
868 u8 *session_key, int *session_key_len,
869 u8 *con_secret, int *con_secret_len)
740{870{
741 struct ceph_x_authorizer *au = (void *)a;871 struct ceph_x_authorizer *au = (void *)a;
742 void *p = au->enc_buf;872 u64 nonce_plus_one;
743 struct ceph_x_authorize_reply *reply = p + ceph_x_encrypt_offset();
744 int ret;873 int ret;
745 874
746 ret = ceph_x_decrypt(&au->session_key, &p, p + CEPHX_AU_ENC_BUF_LEN);875 if (session_key) {
747 if (ret < 0)876 memcpy(session_key, au->session_key.key, au->session_key.len);
877 *session_key_len = au->session_key.len;
878 }
879
880 ret = decrypt_authorizer_reply(&au->session_key, &reply,
881 reply + reply_len, &nonce_plus_one,
882 con_secret, con_secret_len);
883 if (ret)
748 return ret;884 return ret;
749 if (ret < sizeof(*reply)) {885
750 pr_err("bad size %d for ceph_x_authorize_reply\n", ret);886 if (nonce_plus_one != au->nonce + 1) {
751 return -EINVAL;887 pr_err("failed to authenticate server\n");
888 return -EPERM;
752 }889 }
753 890
754 if (au->nonce + 1 != le64_to_cpu(reply->nonce_plus_one))891 return 0;
755 ret = -EPERM;
756 else
757 ret = 0;
758 dout("verify_authorizer_reply nonce %llx got %llx ret %d\n",
759 au->nonce, le64_to_cpu(reply->nonce_plus_one), ret);
760 return ret;
761}892}
762 893
763static void ceph_x_reset(struct ceph_auth_client *ac)894static void ceph_x_reset(struct ceph_auth_client *ac)
net/ceph/auth_x_protocol.h+2−1
@@ -38,7 +38,8 @@ struct ceph_x_authenticate { · 37 unmodified lines
38 __u8 struct_v;38 __u8 struct_v;
39 __le64 client_challenge;39 __le64 client_challenge;
40 __le64 key;40 __le64 key;
41 /* ticket blob */41 /* old_ticket blob */
42 /* nautilus+: other_keys */
42} __attribute__ ((packed));43} __attribute__ ((packed));
43 44
44struct ceph_x_service_ticket_request {45struct ceph_x_service_ticket_request {
net/ceph/crypto.h+3−0
@@ -5,6 +5,9 @@ · 4 unmodified lines
5#include <linux/ceph/types.h>5#include <linux/ceph/types.h>
6#include <linux/ceph/buffer.h>6#include <linux/ceph/buffer.h>
7 7
8#define CEPH_KEY_LEN 16
9#define CEPH_MAX_CON_SECRET_LEN 64
10
8/*11/*
9 * cryptographic secret12 * cryptographic secret
10 */13 */
net/ceph/osd_client.c+4−1
@@ -5623,8 +5623,11 @@ static int verify_authorizer_reply(struct ceph_connection *con) · 5622 unmodified lines
5623 struct ceph_osd *o = con->private;5623 struct ceph_osd *o = con->private;
5624 struct ceph_osd_client *osdc = o->o_osdc;5624 struct ceph_osd_client *osdc = o->o_osdc;
5625 struct ceph_auth_client *ac = osdc->client->monc.auth;5625 struct ceph_auth_client *ac = osdc->client->monc.auth;
5626 struct ceph_auth_handshake *auth = &o->o_auth;
5626 5627
5627 return ceph_auth_verify_authorizer_reply(ac, o->o_auth.authorizer);5628 return ceph_auth_verify_authorizer_reply(ac, auth->authorizer,
5629 auth->authorizer_reply_buf, auth->authorizer_reply_buf_len,
5630 NULL, NULL, NULL, NULL);
5628}5631}
5629 5632
5630static int invalidate_authorizer(struct ceph_connection *con)5633static int invalidate_authorizer(struct ceph_connection *con)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t