From c58c5754dfd26eef359cad8b29e825120af59c64 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 12 Apr 2019 14:19:38 -0500 Subject: [PATCH] msg/async/ProtocolV1: use AuthServer and AuthClient Stop using the old ms_* auth methods and instead use the new interfaces (like V2). Signed-off-by: Sage Weil --- src/msg/async/ProtocolV1.cc | 187 +++++++++++++++++++++--------------- src/msg/async/ProtocolV1.h | 6 +- 2 files changed, 113 insertions(+), 80 deletions(-) diff --git a/src/msg/async/ProtocolV1.cc b/src/msg/async/ProtocolV1.cc index 88797674536..6ca7a093461 100644 --- a/src/msg/async/ProtocolV1.cc +++ b/src/msg/async/ProtocolV1.cc @@ -9,6 +9,8 @@ #include "AsyncMessenger.h" #include "common/EventTrace.h" #include "include/random.h" +#include "auth/AuthClient.h" +#include "auth/AuthServer.h" #define dout_subsys ceph_subsys_ms #undef dout_prefix @@ -72,7 +74,6 @@ ProtocolV1::ProtocolV1(AsyncConnection *connection) once_ready(false), state(NONE), global_seq(0), - authorizer(nullptr), wait_for_seq(false) { temp_buffer = new char[4096]; } @@ -82,20 +83,12 @@ ProtocolV1::~ProtocolV1() { ceph_assert(sent.empty()); delete[] temp_buffer; - - if (authorizer) { - delete authorizer; - } } void ProtocolV1::connect() { this->state = START_CONNECT; // reset connect state variables - if (authorizer) { - delete authorizer; - authorizer = nullptr; - } authorizer_buf.clear(); memset(&connect_msg, 0, sizeof(connect_msg)); memset(&connect_reply, 0, sizeof(connect_reply)); @@ -1243,14 +1236,12 @@ void ProtocolV1::discard_out_queue() { out_q.clear(); } -void ProtocolV1::reset_recv_state() { +void ProtocolV1::reset_recv_state() +{ // clean up state internal variables and states - if (state == CONNECTING_SEND_CONNECT_MSG) { - if (authorizer) { - delete authorizer; - } - authorizer = nullptr; - } + auth_meta.reset(new AuthConnectionMeta); + authorizer_more.clear(); + session_security.reset(); // clean read and write callbacks connection->pendingReadLen.reset(); @@ -1442,13 +1433,37 @@ CtPtr ProtocolV1::handle_my_addr_write(int r) { return CONTINUE(send_connect_message); } -CtPtr ProtocolV1::send_connect_message() { +CtPtr ProtocolV1::send_connect_message() +{ state = CONNECTING_SEND_CONNECT_MSG; ldout(cct, 20) << __func__ << dendl; + ceph_assert(messenger->auth_client); + + bufferlist auth_bl; + vector preferred_modes; - if (!authorizer) { - authorizer = messenger->ms_deliver_get_authorizer(connection->peer_type); + if (connection->peer_type != CEPH_ENTITY_TYPE_MON) { + if (authorizer_more.length()) { + ldout(cct,10) << __func__ << " using augmented (challenge) auth payload" + << dendl; + auth_bl = authorizer_more; + } else { + auto am = auth_meta; + authorizer_more.clear(); + connection->lock.unlock(); + int r = messenger->auth_client->get_auth_request( + connection, am.get(), + &am->auth_method, &preferred_modes, &auth_bl); + connection->lock.lock(); + if (r < 0) { + return _fault(); + } + if (state != CONNECTING_SEND_CONNECT_MSG) { + ldout(cct, 1) << __func__ << " state changed!" << dendl; + return _fault(); + } + } } ceph_msg_connect connect; @@ -1458,13 +1473,15 @@ CtPtr ProtocolV1::send_connect_message() { connect.connect_seq = connect_seq; connect.protocol_version = messenger->get_proto_version(connection->peer_type, true); - connect.authorizer_protocol = authorizer ? authorizer->protocol : 0; - connect.authorizer_len = authorizer ? authorizer->bl.length() : 0; - - if (authorizer) { + if (auth_bl.length()) { ldout(cct, 10) << __func__ - << " connect_msg.authorizer_len=" << connect.authorizer_len - << " protocol=" << connect.authorizer_protocol << dendl; + << " connect_msg.authorizer_len=" << auth_bl.length() + << " protocol=" << auth_meta->auth_method << dendl; + connect.authorizer_protocol = auth_meta->auth_method; + connect.authorizer_len = auth_bl.length(); + } else { + connect.authorizer_protocol = 0; + connect.authorizer_len = 0; } connect.flags = 0; @@ -1475,8 +1492,8 @@ CtPtr ProtocolV1::send_connect_message() { bufferlist bl; bl.append((char *)&connect, sizeof(connect)); - if (authorizer) { - bl.append(authorizer->bl.c_str(), authorizer->bl.length()); + if (auth_bl.length()) { + bl.append(auth_bl.c_str(), auth_bl.length()); } ldout(cct, 10) << __func__ << " connect sending gseq=" << global_seq @@ -1557,17 +1574,37 @@ CtPtr ProtocolV1::handle_connect_reply_auth(char *buffer, int r) { bufferlist authorizer_reply; authorizer_reply.append(buffer, connect_reply.authorizer_len); - if (connect_reply.tag == CEPH_MSGR_TAG_CHALLENGE_AUTHORIZER) { - ldout(cct, 10) << __func__ << " connect got auth challenge" << dendl; - authorizer->add_challenge(cct, authorizer_reply); - return CONTINUE(send_connect_message); - } - - auto iter = authorizer_reply.cbegin(); - if (authorizer && !authorizer->verify_reply(iter, - nullptr /* connection_secret */)) { - ldout(cct, 0) << __func__ << " failed verifying authorize reply" << dendl; - return _fault(); + if (connection->peer_type != CEPH_ENTITY_TYPE_MON) { + auto am = auth_meta; + bool more = (connect_reply.tag == CEPH_MSGR_TAG_CHALLENGE_AUTHORIZER); + bufferlist auth_retry_bl; + int r; + connection->lock.unlock(); + if (more) { + r = messenger->auth_client->handle_auth_reply_more( + connection, am.get(), authorizer_reply, &auth_retry_bl); + } else { + // these aren't used for v1 + CryptoKey skey; + string con_secret; + r = messenger->auth_client->handle_auth_done( + connection, am.get(), + 0 /* global id */, 0 /* con mode */, + authorizer_reply, + &skey, &con_secret); + } + connection->lock.lock(); + if (state != CONNECTING_SEND_CONNECT_MSG) { + ldout(cct, 1) << __func__ << " state changed" << dendl; + return _fault(); + } + if (r < 0) { + return _fault(); + } + if (more && r == 0) { + authorizer_more = auth_retry_bl; + return CONTINUE(send_connect_message); + } } return handle_connect_reply_2(); @@ -1595,6 +1632,7 @@ CtPtr ProtocolV1::handle_connect_reply_2() { if (connect_reply.tag == CEPH_MSGR_TAG_BADAUTHORIZER) { ldout(cct, 0) << __func__ << " connect got BADAUTHORIZER" << dendl; + authorizer_more.clear(); return _fault(); } @@ -1716,12 +1754,12 @@ CtPtr ProtocolV1::client_ready() { // If we have an authorizer, get a new AuthSessionHandler to deal with // ongoing security of the connection. PLR - if (authorizer != NULL) { + if (auth_meta->authorizer) { ldout(cct, 10) << __func__ << " setting up session_security with auth " - << authorizer << dendl; + << auth_meta->authorizer.get() << dendl; session_security.reset(get_auth_session_handler( - cct, authorizer->protocol, - authorizer->session_key, + cct, auth_meta->authorizer->protocol, + auth_meta->session_key, connection->get_features())); } else { // We have no authorizer, so we shouldn't be applying security to messages @@ -1943,41 +1981,43 @@ CtPtr ProtocolV1::handle_connect_message_2() { } bufferlist auth_bl_copy = authorizer_buf; + auto am = auth_meta; + am->auth_method = connect_msg.authorizer_protocol; connection->lock.unlock(); ldout(cct,10) << __func__ << " authorizor_protocol " << connect_msg.authorizer_protocol << " len " << auth_bl_copy.length() << dendl; - bool authorizer_valid; - bool need_challenge = HAVE_FEATURE(connect_msg.features, CEPHX_V2); - bool had_challenge = (bool)authorizer_challenge; - if (!messenger->ms_deliver_verify_authorizer( - connection, connection->peer_type, connect_msg.authorizer_protocol, - auth_bl_copy, authorizer_reply, authorizer_valid, session_key, - nullptr /* connection_secret */, - need_challenge ? &authorizer_challenge : nullptr) || - !authorizer_valid) { + bool more = (bool)auth_meta->authorizer_challenge; + int r = messenger->auth_server->handle_auth_request( + connection, + am.get(), + more, + am->auth_method, + auth_bl_copy, + &authorizer_reply); + if (r < 0) { connection->lock.lock(); if (state != ACCEPTING_WAIT_CONNECT_MSG_AUTH) { - ldout(cct, 1) << __func__ - << " state changed while accept, it must be mark_down" - << dendl; - ceph_assert(state == CLOSED); + ldout(cct, 1) << __func__ << " state changed" << dendl; return _fault(); } - - if (need_challenge && !had_challenge && authorizer_challenge) { - ldout(cct, 10) << __func__ << ": challenging authorizer" << dendl; - ceph_assert(authorizer_reply.length()); - return send_connect_message_reply(CEPH_MSGR_TAG_CHALLENGE_AUTHORIZER, - reply, authorizer_reply); - } else { - ldout(cct, 0) << __func__ << ": got bad authorizer, auth_reply_len=" - << authorizer_reply.length() << dendl; - session_security.reset(); - return send_connect_message_reply(CEPH_MSGR_TAG_BADAUTHORIZER, reply, - authorizer_reply); + ldout(cct, 0) << __func__ << ": got bad authorizer, auth_reply_len=" + << authorizer_reply.length() << dendl; + session_security.reset(); + return send_connect_message_reply(CEPH_MSGR_TAG_BADAUTHORIZER, reply, + authorizer_reply); + } + if (r == 0) { + connection->lock.lock(); + if (state != ACCEPTING_WAIT_CONNECT_MSG_AUTH) { + ldout(cct, 1) << __func__ << " state changed" << dendl; + return _fault(); } + ldout(cct, 10) << __func__ << ": challenging authorizer" << dendl; + ceph_assert(authorizer_reply.length()); + return send_connect_message_reply(CEPH_MSGR_TAG_CHALLENGE_AUTHORIZER, + reply, authorizer_reply); } // We've verified the authorizer for this AsyncConnection, so set up the @@ -1991,10 +2031,7 @@ CtPtr ProtocolV1::handle_connect_message_2() { connection->lock.lock(); if (state != ACCEPTING_WAIT_CONNECT_MSG_AUTH) { - ldout(cct, 1) << __func__ - << " state changed while accept, it must be mark_down" - << dendl; - ceph_assert(state == CLOSED); + ldout(cct, 1) << __func__ << " state changed" << dendl; return _fault(); } @@ -2276,8 +2313,6 @@ CtPtr ProtocolV1::replace(const AsyncConnectionRef& existing, // there shouldn't exist any buffer ceph_assert(connection->recv_start == connection->recv_end); - exproto->authorizer_challenge.reset(); - auto deactivate_existing = std::bind( [existing, new_worker, new_center, exproto, reply, authorizer_reply](ConnectedSocket &cs) mutable { @@ -2396,9 +2431,9 @@ CtPtr ProtocolV1::open(ceph_msg_connect_reply &reply, << connect_msg.authorizer_protocol << dendl; session_security.reset( - get_auth_session_handler(cct, connect_msg.authorizer_protocol, - session_key, - connection->get_features())); + get_auth_session_handler(cct, auth_meta->auth_method, + auth_meta->session_key, + connection->get_features())); bufferlist reply_bl; reply_bl.append((char *)&reply, sizeof(reply)); diff --git a/src/msg/async/ProtocolV1.h b/src/msg/async/ProtocolV1.h index 837af304208..43256543cde 100644 --- a/src/msg/async/ProtocolV1.h +++ b/src/msg/async/ProtocolV1.h @@ -114,14 +114,13 @@ protected: std::atomic out_seq{0}; std::atomic ack_left{0}; - CryptoKey session_key; std::shared_ptr session_security; - std::unique_ptr authorizer_challenge; // accept side // Open state ceph_msg_connect connect_msg; ceph_msg_connect_reply connect_reply; - bufferlist authorizer_buf; + bufferlist authorizer_buf; // auth(orizer) payload read off the wire + bufferlist authorizer_more; // connect-side auth retry (we added challenge) utime_t backoff; // backoff time utime_t recv_stamp; @@ -226,7 +225,6 @@ public: // Client Protocol private: int global_seq; - AuthAuthorizer *authorizer; CONTINUATION_DECL(ProtocolV1, send_client_banner); WRITE_HANDLER_CONTINUATION_DECL(ProtocolV1, handle_client_banner_write); -- 2.39.5