From 88588cf70a564f73d22873f864097d2c564b0b5d Mon Sep 17 00:00:00 2001 From: Yingxin Cheng Date: Fri, 19 Apr 2019 09:44:25 +0800 Subject: [PATCH] crimson/net: migrate protocol v1 to auth-client/server Signed-off-by: Yingxin Cheng Signed-off-by: Kefu Chai --- src/crimson/net/ProtocolV1.cc | 106 ++++++++++++++++++++++++++-------- src/crimson/net/ProtocolV1.h | 4 +- 2 files changed, 84 insertions(+), 26 deletions(-) diff --git a/src/crimson/net/ProtocolV1.cc b/src/crimson/net/ProtocolV1.cc index bc88913aaa0..a4917959eab 100644 --- a/src/crimson/net/ProtocolV1.cc +++ b/src/crimson/net/ProtocolV1.cc @@ -12,6 +12,8 @@ #include "auth/Auth.h" #include "auth/AuthSessionHandler.h" +#include "crimson/auth/AuthClient.h" +#include "crimson/auth/AuthServer.h" #include "crimson/common/log.h" #include "Config.h" #include "Dispatcher.h" @@ -170,6 +172,22 @@ void ProtocolV1::reset_session() seastar::future ProtocolV1::handle_connect_reply(msgr_tag_t tag) { + if (h.auth_payload.length() && conn.peer_type != CEPH_ENTITY_TYPE_MON) { + if (tag == CEPH_MSGR_TAG_CHALLENGE_AUTHORIZER) { // more + h.auth_more = messenger.get_auth_client()->handle_auth_reply_more( + conn.shared_from_this(), auth_meta, h.auth_payload); + return seastar::make_ready_future(stop_t::no); + } else { + int ret = messenger.get_auth_client()->handle_auth_done( + conn.shared_from_this(), auth_meta, 0, 0, h.auth_payload); + if (ret < 0) { + // fault + logger().warn("{} AuthClient::handle_auth_done() return {}", conn, ret); + throw std::system_error(make_error_code(error::negotiation_failure)); + } + } + } + switch (tag) { case CEPH_MSGR_TAG_FEATURES: logger().error("{} connect protocol feature mispatch", __func__); @@ -218,14 +236,15 @@ ProtocolV1::handle_connect_reply(msgr_tag_t tag) h.connect_seq++; h.backoff = 0ms; conn.set_features(h.reply.features & h.connect.features); - if (h.authorizer) { + if (auth_meta->authorizer) { session_security.reset( get_auth_session_handler(nullptr, - h.authorizer->protocol, - h.authorizer->session_key, + auth_meta->authorizer->protocol, + auth_meta->session_key, conn.features)); + } else { + session_security.reset(); } - h.authorizer = nullptr; return seastar::make_ready_future(stop_t::yes); }); break; @@ -236,6 +255,26 @@ ProtocolV1::handle_connect_reply(msgr_tag_t tag) } } +ceph::bufferlist ProtocolV1::get_auth_payload() +{ + // only non-mons connectings to mons use MAuth messages + if (conn.peer_type == CEPH_ENTITY_TYPE_MON && + messenger.get_mytype() != CEPH_ENTITY_TYPE_MON) { + return {}; + } else { + if (h.auth_more.length()) { + logger().info("using augmented (challenge) auth payload"); + return std::move(h.auth_more); + } else { + auto [auth_method, preferred_modes, auth_bl] = + messenger.get_auth_client()->get_auth_request( + conn.shared_from_this(), auth_meta); + auth_meta->auth_method = auth_method; + return auth_bl; + } + } +} + seastar::future ProtocolV1::repeat_connect() { @@ -249,13 +288,15 @@ ProtocolV1::repeat_connect() // this is fyi, actually, server decides! h.connect.flags = conn.policy.lossy ? CEPH_MSG_CONNECT_LOSSY : 0; - h.authorizer = dispatcher.ms_get_authorizer(conn.peer_type); + ceph_assert(messenger.get_auth_client()); + bufferlist bl; - if (h.authorizer) { - h.connect.authorizer_protocol = h.authorizer->protocol; - h.connect.authorizer_len = h.authorizer->bl.length(); + bufferlist auth_bl = get_auth_payload(); + if (auth_bl.length()) { + h.connect.authorizer_protocol = auth_meta->auth_method; + h.connect.authorizer_len = auth_bl.length(); bl.append(create_static(h.connect)); - bl.append(h.authorizer->bl); + bl.claim_append(auth_bl); } else { h.connect.authorizer_protocol = 0; h.connect.authorizer_len = 0; @@ -271,13 +312,7 @@ ProtocolV1::repeat_connect() ceph_assert(p.end()); return socket->read(h.reply.authorizer_len); }).then([this] (bufferlist bl) { - if (h.authorizer) { - auto reply = bl.cbegin(); - if (!h.authorizer->verify_reply(reply, nullptr)) { - logger().error("{} authorizer failed to verify reply", __func__); - throw std::system_error(make_error_code(error::negotiation_failure)); - } - } + h.auth_payload = std::move(bl); return handle_connect_reply(h.reply.tag); }); } @@ -377,6 +412,13 @@ seastar::future ProtocolV1::send_connect_reply_ready( h.reply.flags = h.reply.flags | CEPH_MSG_CONNECT_LOSSY; } h.reply.authorizer_len = authorizer_reply.length(); + + session_security.reset( + get_auth_session_handler(nullptr, + auth_meta->auth_method, + auth_meta->session_key, + conn.features)); + return socket->write(make_static_packet(h.reply)) .then([this, reply=std::move(authorizer_reply)]() mutable { if (reply.length()) { @@ -494,8 +536,10 @@ seastar::future ProtocolV1::repeat_handle_connect() conn.peer_type = h.connect.host_type; return socket->read(h.connect.authorizer_len); }).then([this] (bufferlist authorizer) { + memset(&h.reply, 0, sizeof(h.reply)); + // TODO: set reply.protocol_version if (h.connect.protocol_version != get_proto_version(h.connect.host_type, false)) { - return seastar::make_ready_future( + return send_connect_reply( CEPH_MSGR_TAG_BADPROTOVER, bufferlist{}); } if (require_auth_feature()) { @@ -503,17 +547,29 @@ seastar::future ProtocolV1::repeat_handle_connect() } if (auto feat_missing = conn.policy.features_required & ~(uint64_t)h.connect.features; feat_missing != 0) { - return seastar::make_ready_future( + return send_connect_reply( CEPH_MSGR_TAG_FEATURES, bufferlist{}); } - return dispatcher.ms_verify_authorizer(conn.peer_type, - h.connect.authorizer_protocol, - authorizer); - }).then([this] (ceph::net::msgr_tag_t tag, bufferlist&& authorizer_reply) { - memset(&h.reply, 0, sizeof(h.reply)); - if (tag) { - return send_connect_reply(tag, std::move(authorizer_reply)); + + bufferlist authorizer_reply; + auth_meta->auth_method = h.connect.authorizer_protocol; + auto more = static_cast(auth_meta->authorizer_challenge); + ceph_assert(messenger.get_auth_server()); + int r = messenger.get_auth_server()->handle_auth_request( + conn.shared_from_this(), auth_meta, more, auth_meta->auth_method, authorizer, + &authorizer_reply); + + if (r < 0) { + session_security.reset(); + return send_connect_reply( + CEPH_MSGR_TAG_BADAUTHORIZER, std::move(authorizer_reply)); + } else if (r == 0) { + ceph_assert(authorizer_reply.length()); + return send_connect_reply( + CEPH_MSGR_TAG_CHALLENGE_AUTHORIZER, std::move(authorizer_reply)); } + + // r > 0 if (auto existing = messenger.lookup_conn(conn.peer_addr); existing) { if (existing->protocol->proto_type != proto_t::v1) { logger().warn("{} existing {} proto version is {} not 1, close existing", diff --git a/src/crimson/net/ProtocolV1.h b/src/crimson/net/ProtocolV1.h index b3692a799c2..ac65c8f9957 100644 --- a/src/crimson/net/ProtocolV1.h +++ b/src/crimson/net/ProtocolV1.h @@ -50,7 +50,8 @@ class ProtocolV1 final : public Protocol { struct Handshake { ceph_msg_connect connect; ceph_msg_connect_reply reply; - AuthAuthorizer* authorizer = nullptr; + ceph::bufferlist auth_payload; // auth(orizer) payload read off the wire + ceph::bufferlist auth_more; // connect-side auth retry (we added challenge) std::chrono::milliseconds backoff; uint32_t connect_seq = 0; uint32_t peer_global_seq = 0; @@ -85,6 +86,7 @@ class ProtocolV1 final : public Protocol { void reset_session(); seastar::future handle_connect_reply(ceph::net::msgr_tag_t tag); seastar::future repeat_connect(); + ceph::bufferlist get_auth_payload(); // accepting seastar::future send_connect_reply( -- 2.39.5