auth.c (00498b994113a871a556f7ff24a4cf8a00611700) auth.c (cd1a677cad994021b19665ed476aea63f5d54f31)
1// SPDX-License-Identifier: GPL-2.0
2#include <linux/ceph/ceph_debug.h>
3
4#include <linux/module.h>
5#include <linux/err.h>
6#include <linux/slab.h>
7
8#include <linux/ceph/types.h>

--- 279 unchanged lines hidden (view full) ---

288 mutex_lock(&ac->mutex);
289 if (ac->ops)
290 ret = ac->ops->is_authenticated(ac);
291 mutex_unlock(&ac->mutex);
292 return ret;
293}
294EXPORT_SYMBOL(ceph_auth_is_authenticated);
295
1// SPDX-License-Identifier: GPL-2.0
2#include <linux/ceph/ceph_debug.h>
3
4#include <linux/module.h>
5#include <linux/err.h>
6#include <linux/slab.h>
7
8#include <linux/ceph/types.h>

--- 279 unchanged lines hidden (view full) ---

288 mutex_lock(&ac->mutex);
289 if (ac->ops)
290 ret = ac->ops->is_authenticated(ac);
291 mutex_unlock(&ac->mutex);
292 return ret;
293}
294EXPORT_SYMBOL(ceph_auth_is_authenticated);
295
296int __ceph_auth_get_authorizer(struct ceph_auth_client *ac,
297 struct ceph_auth_handshake *auth,
298 int peer_type, bool force_new,
299 int *proto, int *pref_mode, int *fallb_mode)
300{
301 int ret;
302
303 mutex_lock(&ac->mutex);
304 if (force_new && auth->authorizer) {
305 ceph_auth_destroy_authorizer(auth->authorizer);
306 auth->authorizer = NULL;
307 }
308 if (!auth->authorizer)
309 ret = ac->ops->create_authorizer(ac, peer_type, auth);
310 else if (ac->ops->update_authorizer)
311 ret = ac->ops->update_authorizer(ac, peer_type, auth);
312 else
313 ret = 0;
314 if (ret)
315 goto out;
316
317 *proto = ac->protocol;
318 if (pref_mode && fallb_mode) {
319 *pref_mode = ac->preferred_mode;
320 *fallb_mode = ac->fallback_mode;
321 }
322
323out:
324 mutex_unlock(&ac->mutex);
325 return ret;
326}
327EXPORT_SYMBOL(__ceph_auth_get_authorizer);
328
296int ceph_auth_create_authorizer(struct ceph_auth_client *ac,
297 int peer_type,
298 struct ceph_auth_handshake *auth)
299{
300 int ret = 0;
301
302 mutex_lock(&ac->mutex);
303 if (ac->ops && ac->ops->create_authorizer)

--- 60 unchanged lines hidden (view full) ---

364void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac, int peer_type)
365{
366 mutex_lock(&ac->mutex);
367 if (ac->ops && ac->ops->invalidate_authorizer)
368 ac->ops->invalidate_authorizer(ac, peer_type);
369 mutex_unlock(&ac->mutex);
370}
371EXPORT_SYMBOL(ceph_auth_invalidate_authorizer);
329int ceph_auth_create_authorizer(struct ceph_auth_client *ac,
330 int peer_type,
331 struct ceph_auth_handshake *auth)
332{
333 int ret = 0;
334
335 mutex_lock(&ac->mutex);
336 if (ac->ops && ac->ops->create_authorizer)

--- 60 unchanged lines hidden (view full) ---

397void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac, int peer_type)
398{
399 mutex_lock(&ac->mutex);
400 if (ac->ops && ac->ops->invalidate_authorizer)
401 ac->ops->invalidate_authorizer(ac, peer_type);
402 mutex_unlock(&ac->mutex);
403}
404EXPORT_SYMBOL(ceph_auth_invalidate_authorizer);
405
406/*
407 * msgr2 authentication
408 */
409
410static bool contains(const int *arr, int cnt, int val)
411{
412 int i;
413
414 for (i = 0; i < cnt; i++) {
415 if (arr[i] == val)
416 return true;
417 }
418
419 return false;
420}
421
422static int encode_con_modes(void **p, void *end, int pref_mode, int fallb_mode)
423{
424 WARN_ON(pref_mode == CEPH_CON_MODE_UNKNOWN);
425 if (fallb_mode != CEPH_CON_MODE_UNKNOWN) {
426 ceph_encode_32_safe(p, end, 2, e_range);
427 ceph_encode_32_safe(p, end, pref_mode, e_range);
428 ceph_encode_32_safe(p, end, fallb_mode, e_range);
429 } else {
430 ceph_encode_32_safe(p, end, 1, e_range);
431 ceph_encode_32_safe(p, end, pref_mode, e_range);
432 }
433
434 return 0;
435
436e_range:
437 return -ERANGE;
438}
439
440/*
441 * Similar to ceph_auth_build_hello().
442 */
443int ceph_auth_get_request(struct ceph_auth_client *ac, void *buf, int buf_len)
444{
445 int proto = ac->key ? CEPH_AUTH_CEPHX : CEPH_AUTH_NONE;
446 void *end = buf + buf_len;
447 void *lenp;
448 void *p;
449 int ret;
450
451 mutex_lock(&ac->mutex);
452 if (ac->protocol == CEPH_AUTH_UNKNOWN) {
453 ret = init_protocol(ac, proto);
454 if (ret) {
455 pr_err("auth protocol '%s' init failed: %d\n",
456 ceph_auth_proto_name(proto), ret);
457 goto out;
458 }
459 } else {
460 WARN_ON(ac->protocol != proto);
461 ac->ops->reset(ac);
462 }
463
464 p = buf;
465 ceph_encode_32_safe(&p, end, ac->protocol, e_range);
466 ret = encode_con_modes(&p, end, ac->preferred_mode, ac->fallback_mode);
467 if (ret)
468 goto out;
469
470 lenp = p;
471 p += 4; /* space for len */
472
473 ceph_encode_8_safe(&p, end, CEPH_AUTH_MODE_MON, e_range);
474 ret = ceph_auth_entity_name_encode(ac->name, &p, end);
475 if (ret)
476 goto out;
477
478 ceph_encode_64_safe(&p, end, ac->global_id, e_range);
479 ceph_encode_32(&lenp, p - lenp - 4);
480 ret = p - buf;
481
482out:
483 mutex_unlock(&ac->mutex);
484 return ret;
485
486e_range:
487 ret = -ERANGE;
488 goto out;
489}
490
491int ceph_auth_handle_reply_more(struct ceph_auth_client *ac, void *reply,
492 int reply_len, void *buf, int buf_len)
493{
494 int ret;
495
496 mutex_lock(&ac->mutex);
497 ret = ac->ops->handle_reply(ac, 0, reply, reply + reply_len,
498 NULL, NULL, NULL, NULL);
499 if (ret == -EAGAIN)
500 ret = build_request(ac, false, buf, buf_len);
501 else
502 WARN_ON(ret >= 0);
503 mutex_unlock(&ac->mutex);
504 return ret;
505}
506
507int ceph_auth_handle_reply_done(struct ceph_auth_client *ac,
508 u64 global_id, void *reply, int reply_len,
509 u8 *session_key, int *session_key_len,
510 u8 *con_secret, int *con_secret_len)
511{
512 int ret;
513
514 mutex_lock(&ac->mutex);
515 if (global_id && ac->global_id != global_id) {
516 dout("%s global_id %llu -> %llu\n", __func__, ac->global_id,
517 global_id);
518 ac->global_id = global_id;
519 }
520
521 ret = ac->ops->handle_reply(ac, 0, reply, reply + reply_len,
522 session_key, session_key_len,
523 con_secret, con_secret_len);
524 mutex_unlock(&ac->mutex);
525 return ret;
526}
527
528bool ceph_auth_handle_bad_method(struct ceph_auth_client *ac,
529 int used_proto, int result,
530 const int *allowed_protos, int proto_cnt,
531 const int *allowed_modes, int mode_cnt)
532{
533 mutex_lock(&ac->mutex);
534 WARN_ON(used_proto != ac->protocol);
535
536 if (result == -EOPNOTSUPP) {
537 if (!contains(allowed_protos, proto_cnt, ac->protocol)) {
538 pr_err("auth protocol '%s' not allowed\n",
539 ceph_auth_proto_name(ac->protocol));
540 goto not_allowed;
541 }
542 if (!contains(allowed_modes, mode_cnt, ac->preferred_mode) &&
543 (ac->fallback_mode == CEPH_CON_MODE_UNKNOWN ||
544 !contains(allowed_modes, mode_cnt, ac->fallback_mode))) {
545 pr_err("preferred mode '%s' not allowed\n",
546 ceph_con_mode_name(ac->preferred_mode));
547 if (ac->fallback_mode == CEPH_CON_MODE_UNKNOWN)
548 pr_err("no fallback mode\n");
549 else
550 pr_err("fallback mode '%s' not allowed\n",
551 ceph_con_mode_name(ac->fallback_mode));
552 goto not_allowed;
553 }
554 }
555
556 WARN_ON(result == -EOPNOTSUPP || result >= 0);
557 pr_err("auth protocol '%s' msgr authentication failed: %d\n",
558 ceph_auth_proto_name(ac->protocol), result);
559
560 mutex_unlock(&ac->mutex);
561 return true;
562
563not_allowed:
564 mutex_unlock(&ac->mutex);
565 return false;
566}
567
568int ceph_auth_get_authorizer(struct ceph_auth_client *ac,
569 struct ceph_auth_handshake *auth,
570 int peer_type, void *buf, int *buf_len)
571{
572 void *end = buf + *buf_len;
573 int pref_mode, fallb_mode;
574 int proto;
575 void *p;
576 int ret;
577
578 ret = __ceph_auth_get_authorizer(ac, auth, peer_type, true, &proto,
579 &pref_mode, &fallb_mode);
580 if (ret)
581 return ret;
582
583 p = buf;
584 ceph_encode_32_safe(&p, end, proto, e_range);
585 ret = encode_con_modes(&p, end, pref_mode, fallb_mode);
586 if (ret)
587 return ret;
588
589 ceph_encode_32_safe(&p, end, auth->authorizer_buf_len, e_range);
590 *buf_len = p - buf;
591 return 0;
592
593e_range:
594 return -ERANGE;
595}
596EXPORT_SYMBOL(ceph_auth_get_authorizer);
597
598int ceph_auth_handle_svc_reply_more(struct ceph_auth_client *ac,
599 struct ceph_auth_handshake *auth,
600 void *reply, int reply_len,
601 void *buf, int *buf_len)
602{
603 void *end = buf + *buf_len;
604 void *p;
605 int ret;
606
607 ret = ceph_auth_add_authorizer_challenge(ac, auth->authorizer,
608 reply, reply_len);
609 if (ret)
610 return ret;
611
612 p = buf;
613 ceph_encode_32_safe(&p, end, auth->authorizer_buf_len, e_range);
614 *buf_len = p - buf;
615 return 0;
616
617e_range:
618 return -ERANGE;
619}
620EXPORT_SYMBOL(ceph_auth_handle_svc_reply_more);
621
622int ceph_auth_handle_svc_reply_done(struct ceph_auth_client *ac,
623 struct ceph_auth_handshake *auth,
624 void *reply, int reply_len,
625 u8 *session_key, int *session_key_len,
626 u8 *con_secret, int *con_secret_len)
627{
628 return ceph_auth_verify_authorizer_reply(ac, auth->authorizer,
629 reply, reply_len, session_key, session_key_len,
630 con_secret, con_secret_len);
631}
632EXPORT_SYMBOL(ceph_auth_handle_svc_reply_done);
633
634bool ceph_auth_handle_bad_authorizer(struct ceph_auth_client *ac,
635 int peer_type, int used_proto, int result,
636 const int *allowed_protos, int proto_cnt,
637 const int *allowed_modes, int mode_cnt)
638{
639 mutex_lock(&ac->mutex);
640 WARN_ON(used_proto != ac->protocol);
641
642 if (result == -EOPNOTSUPP) {
643 if (!contains(allowed_protos, proto_cnt, ac->protocol)) {
644 pr_err("auth protocol '%s' not allowed by %s\n",
645 ceph_auth_proto_name(ac->protocol),
646 ceph_entity_type_name(peer_type));
647 goto not_allowed;
648 }
649 if (!contains(allowed_modes, mode_cnt, ac->preferred_mode) &&
650 (ac->fallback_mode == CEPH_CON_MODE_UNKNOWN ||
651 !contains(allowed_modes, mode_cnt, ac->fallback_mode))) {
652 pr_err("preferred mode '%s' not allowed by %s\n",
653 ceph_con_mode_name(ac->preferred_mode),
654 ceph_entity_type_name(peer_type));
655 if (ac->fallback_mode == CEPH_CON_MODE_UNKNOWN)
656 pr_err("no fallback mode\n");
657 else
658 pr_err("fallback mode '%s' not allowed by %s\n",
659 ceph_con_mode_name(ac->fallback_mode),
660 ceph_entity_type_name(peer_type));
661 goto not_allowed;
662 }
663 }
664
665 WARN_ON(result == -EOPNOTSUPP || result >= 0);
666 pr_err("auth protocol '%s' authorization to %s failed: %d\n",
667 ceph_auth_proto_name(ac->protocol),
668 ceph_entity_type_name(peer_type), result);
669
670 if (ac->ops->invalidate_authorizer)
671 ac->ops->invalidate_authorizer(ac, peer_type);
672
673 mutex_unlock(&ac->mutex);
674 return true;
675
676not_allowed:
677 mutex_unlock(&ac->mutex);
678 return false;
679}
680EXPORT_SYMBOL(ceph_auth_handle_bad_authorizer);