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
51785178 struct ceph_mds_session *s = con->private;
51795179 struct ceph_mds_client *mdsc = s->s_mdsc;
51805180 struct ceph_auth_client *ac = mdsc->fsc->client->monc.auth;
5181+ struct ceph_auth_handshake *auth = &s->s_auth;
51815182
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);
51835186 }
51845187
51855188 static 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
5353 */
5454 int (*build_request)(struct ceph_auth_client *ac, void *buf, void *end);
5555 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);
5759
5860 /*
5961 * Create authorizer for connecting to a service, and verify
@@ -69,7 +71,10 @@ struct ceph_auth_client_ops { · 9 unmodified lines
6971 void *challenge_buf,
7072 int challenge_buf_len);
7173 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);
7378 void (*invalidate_authorizer)(struct ceph_auth_client *ac,
7479 int peer_type);
7580
@@ -126,8 +131,11 @@ int ceph_auth_add_authorizer_challenge(struct ceph_auth_client *ac, · 50 unmodified lines
126131 struct ceph_authorizer *a,
127132 void *challenge_buf,
128133 int challenge_buf_len);
129−extern int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac,
130− struct ceph_authorizer *a);
134+int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac,
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);
131139 extern void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac,
132140 int peer_type);
133141
net/ceph/auth.c+9−3
@@ -240,7 +240,8 @@ int ceph_handle_auth_reply(struct ceph_auth_client *ac, · 239 unmodified lines
240240 ac->negotiating = false;
241241 }
242242
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);
244245 if (ret == -EAGAIN) {
245246 ret = ceph_build_auth_request(ac, reply_buf, reply_len);
246247 } else if (ret) {
@@ -332,13 +333,18 @@ int ceph_auth_add_authorizer_challenge(struct ceph_auth_client *ac, · 85 unmodified lines
332333 EXPORT_SYMBOL(ceph_auth_add_authorizer_challenge);
333334
334335 int 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)
336340 {
337341 int ret = 0;
338342
339343 mutex_lock(&ac->mutex);
340344 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);
342348 mutex_unlock(&ac->mutex);
343349 return ret;
344350 }
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
7070 * authenticate state, so nothing happens here.
7171 */
7272 static 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)
7476 {
7577 struct ceph_auth_none_info *xi = ac->private;
7678
net/ceph/auth_x.c+173−42
@@ -269,22 +269,21 @@ out: · 268 unmodified lines
269269
270270 static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
271271 struct ceph_crypto_key *secret,
272− void *buf, void *end)
272+ void **p, void *end)
273273 {
274− void *p = buf;
275274 u8 reply_struct_v;
276275 u32 num;
277276 int ret;
278277
279− ceph_decode_8_safe(&p, end, reply_struct_v, bad);
278+ ceph_decode_8_safe(p, end, reply_struct_v, bad);
280279 if (reply_struct_v != 1)
281280 return -EINVAL;
282281
283− ceph_decode_32_safe(&p, end, num, bad);
282+ ceph_decode_32_safe(p, end, num, bad);
284283 dout("%d tickets\n", num);
285284
286285 while (num--) {
287− ret = process_one_ticket(ac, secret, &p, end);
286+ ret = process_one_ticket(ac, secret, p, end);
288287 if (ret)
289288 return ret;
290289 }
@@ -527,7 +526,7 @@ static int ceph_x_build_request(struct ceph_auth_client *ac, · 236 unmodified lines
527526 if (ret < 0)
528527 return ret;
529528
530− auth->struct_v = 1;
529+ auth->struct_v = 2; /* nautilus+ */
531530 auth->key = 0;
532531 for (u = (u64 *)enc_buf; u + 1 <= (u64 *)(enc_buf + ret); u++)
533532 auth->key ^= *(__le64 *)u;
@@ -540,6 +539,10 @@ static int ceph_x_build_request(struct ceph_auth_client *ac, · 6 unmodified lines
540539 if (ret < 0)
541540 return ret;
542541
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);
543546 return p - buf;
544547 }
545548
@@ -566,8 +569,82 @@ e_range: · 20 unmodified lines
566569 return -ERANGE;
567570 }
568571
572+static 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+
640+e_inval:
641+ return -EINVAL;
642+}
643+
569644 static 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)
571648 {
572649 struct ceph_x_info *xi = ac->private;
573650 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
599676 dout("handle_reply op %d result %d\n", op, result);
600677 switch (op) {
601678 case CEPHX_GET_AUTH_SESSION_KEY:
602− /* verify auth key */
603− ret = ceph_x_proc_ticket_reply(ac, &xi->secret, p, end);
679+ /* AUTH ticket + [connection secret] + service tickets */
680+ ret = handle_auth_session_key(ac, &p, end, session_key,
681+ session_key_len, con_secret,
682+ con_secret_len);
604683 break;
605684
606685 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
608687 if (IS_ERR(th))
609688 return PTR_ERR(th);
610689
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);
612692 break;
613693
614694 default:
@@ -687,40 +767,44 @@ static int ceph_x_update_authorizer( · 72 unmodified lines
687767 return 0;
688768 }
689769
690−static int decrypt_authorize_challenge(struct ceph_x_authorizer *au,
691− void *challenge_buf,
692− int challenge_buf_len,
693− u64 *server_challenge)
770+/*
771+ * CephXAuthorizeChallenge
772+ */
773+static int decrypt_authorizer_challenge(struct ceph_crypto_key *secret,
774+ void *challenge, int challenge_len,
775+ u64 *server_challenge)
694776 {
695− struct ceph_x_authorize_challenge *ch =
696− challenge_buf + sizeof(struct ceph_x_encrypt_header);
777+ void *dp, *dend;
697778 int ret;
698779
699780 /* no leading len */
700− ret = __ceph_x_decrypt(&au->session_key, challenge_buf,
701− challenge_buf_len);
781+ ret = __ceph_x_decrypt(secret, challenge, challenge_len);
702782 if (ret < 0)
703783 return ret;
704− if (ret < sizeof(*ch)) {
705− pr_err("bad size %d for ceph_x_authorize_challenge\n", ret);
706− return -EINVAL;
707− }
708784
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);
710792 return 0;
793+
794+e_inval:
795+ return -EINVAL;
711796 }
712797
713798 static int ceph_x_add_authorizer_challenge(struct ceph_auth_client *ac,
714799 struct ceph_authorizer *a,
715− void *challenge_buf,
716− int challenge_buf_len)
800+ void *challenge, int challenge_len)
717801 {
718802 struct ceph_x_authorizer *au = (void *)a;
719803 u64 server_challenge;
720804 int ret;
721805
722− ret = decrypt_authorize_challenge(au, challenge_buf, challenge_buf_len,
723− &server_challenge);
806+ ret = decrypt_authorizer_challenge(&au->session_key, challenge,
807+ challenge_len, &server_challenge);
724808 if (ret) {
725809 pr_err("failed to decrypt authorize challenge: %d", ret);
726810 return ret;
@@ -735,29 +819,76 @@ static int ceph_x_add_authorizer_challenge(struct ceph_auth_client *ac, · 8 unmodified lines
735819 return 0;
736820 }
737821
822+/*
823+ * CephXAuthorizeReply
824+ */
825+static 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+
861+e_inval:
862+ return -EINVAL;
863+}
864+
738865 static 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)
740870 {
741871 struct ceph_x_authorizer *au = (void *)a;
742− void *p = au->enc_buf;
743− struct ceph_x_authorize_reply *reply = p + ceph_x_encrypt_offset();
872+ u64 nonce_plus_one;
744873 int ret;
745874
746− ret = ceph_x_decrypt(&au->session_key, &p, p + CEPHX_AU_ENC_BUF_LEN);
747− if (ret < 0)
875+ if (session_key) {
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)
748884 return ret;
749− if (ret < sizeof(*reply)) {
750− pr_err("bad size %d for ceph_x_authorize_reply\n", ret);
751− return -EINVAL;
885+
886+ if (nonce_plus_one != au->nonce + 1) {
887+ pr_err("failed to authenticate server\n");
888+ return -EPERM;
752889 }
753890
754− if (au->nonce + 1 != le64_to_cpu(reply->nonce_plus_one))
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;
891+ return 0;
761892 }
762893
763894 static 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
3838 __u8 struct_v;
3939 __le64 client_challenge;
4040 __le64 key;
41− /* ticket blob */
41+ /* old_ticket blob */
42+ /* nautilus+: other_keys */
4243 } __attribute__ ((packed));
4344
4445 struct ceph_x_service_ticket_request {
net/ceph/crypto.h+3−0
@@ -5,6 +5,9 @@ · 4 unmodified lines
55 #include <linux/ceph/types.h>
66 #include <linux/ceph/buffer.h>
77
8+#define CEPH_KEY_LEN 16
9+#define CEPH_MAX_CON_SECRET_LEN 64
10+
811 /*
912 * cryptographic secret
1013 */
net/ceph/osd_client.c+4−1
@@ -5623,8 +5623,11 @@ static int verify_authorizer_reply(struct ceph_connection *con) · 5622 unmodified lines
56235623 struct ceph_osd *o = con->private;
56245624 struct ceph_osd_client *osdc = o->o_osdc;
56255625 struct ceph_auth_client *ac = osdc->client->monc.auth;
5626+ struct ceph_auth_handshake *auth = &o->o_auth;
56265627
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);
56285631 }
56295632
56305633 static 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