]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
msg/async/ProtocolV1: use AuthServer and AuthClient
authorSage Weil <sage@redhat.com>
Fri, 12 Apr 2019 19:19:38 +0000 (14:19 -0500)
committerSage Weil <sage@redhat.com>
Wed, 24 Apr 2019 18:46:04 +0000 (13:46 -0500)
Stop using the old ms_* auth methods and instead use the new interfaces
(like V2).

Signed-off-by: Sage Weil <sage@redhat.com>
src/msg/async/ProtocolV1.cc
src/msg/async/ProtocolV1.h

index 8879767453684b415fcad7b3f6e6485d3d4dc624..6ca7a09346113e95e234df1222098bad77488b05 100644 (file)
@@ -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<uint32_t> 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));
index 837af30420818073db5c9cfaba9a67d3f0b553f7..43256543cde322cbd2392e455a6ae72e996af228 100644 (file)
@@ -114,14 +114,13 @@ protected:
   std::atomic<uint64_t> out_seq{0};
   std::atomic<uint64_t> ack_left{0};
 
-  CryptoKey session_key;
   std::shared_ptr<AuthSessionHandler> session_security;
-  std::unique_ptr<AuthAuthorizerChallenge> 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);