]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson: update osd when peer gets authenticated
authorKefu Chai <kchai@redhat.com>
Sat, 6 Apr 2019 13:00:59 +0000 (21:00 +0800)
committerKefu Chai <kchai@redhat.com>
Tue, 9 Apr 2019 03:38:04 +0000 (11:38 +0800)
* common/auth_handler.h: add an abstract class of AuthHandler, the one who is interested in
  an authenticated peer should implement this class
* mon/MonClient: let mon::Client implement AuthServer, as it has access the keyring. it
  will update the registered AuthHandler if the client (peer) is
  authenticated.
* osd: implement AuthHandler class. we will keep track of the connected
  sessions along their caps in a follow-up change.

Signed-off-by: Kefu Chai <kchai@redhat.com>
src/crimson/common/auth_handler.h [new file with mode: 0644]
src/crimson/mon/MonClient.cc
src/crimson/mon/MonClient.h
src/crimson/osd/osd.cc
src/crimson/osd/osd.h

diff --git a/src/crimson/common/auth_handler.h b/src/crimson/common/auth_handler.h
new file mode 100644 (file)
index 0000000..521c75d
--- /dev/null
@@ -0,0 +1,18 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+class EntityName;
+class AuthCapsInfo;
+
+namespace ceph::common {
+class AuthHandler {
+public:
+  // the peer just got authorized
+  virtual void handle_authentication(const EntityName& name,
+                                    uint64_t global_id,
+                                    const AuthCapsInfo& caps) = 0;
+  virtual ~AuthHandler() = default;
+};
+}
index 73ebf0be356a52e7990c9d2486e96dd7ee45ae88..d47bf04cf13f4b1bc5e3a7f1db591cc979ea0f0a 100644 (file)
@@ -59,6 +59,7 @@ public:
   seastar::future<> close();
   bool is_my_peer(const entity_addr_t& addr) const;
   AuthAuthorizer* get_authorizer(peer_type_t peer) const;
+  KeyStore& get_keys();
   seastar::future<> renew_tickets();
   ceph::net::ConnectionRef get_conn();
 
@@ -114,6 +115,10 @@ AuthAuthorizer* Connection::get_authorizer(peer_type_t peer) const
   }
 }
 
+KeyStore& Connection::get_keys() {
+  return rotating_keyring;
+}
+
 std::unique_ptr<AuthClientHandler>
 Connection::create_auth(Ref<MAuthReply> m,
                         const EntityName& name,
@@ -264,16 +269,17 @@ auto create_auth_methods(uint32_t entity_type)
 }
 }
 
-Client::Client(ceph::net::Messenger& messenger)
+Client::Client(ceph::net::Messenger& messenger,
+               ceph::common::AuthHandler& auth_handler)
   // currently, crimson is OSD-only
   : want_keys{CEPH_ENTITY_TYPE_MON |
               CEPH_ENTITY_TYPE_OSD |
               CEPH_ENTITY_TYPE_MGR},
     timer{[this] { tick(); }},
-    msgr{messenger}
+    msgr{messenger},
+    auth_handler{auth_handler}
 {}
 
-Client::Client(Client&&) = default;
 Client::~Client() = default;
 
 seastar::future<> Client::start() {
@@ -376,6 +382,55 @@ AuthAuthorizer* Client::get_authorizer(peer_type_t peer) const
   return ms_get_authorizer(peer);
 }
 
+int Client::handle_auth_request(ceph::net::ConnectionRef con,
+                                AuthConnectionMetaRef auth_meta,
+                                bool more,
+                                uint32_t auth_method,
+                                const ceph::bufferlist& payload,
+                                ceph::bufferlist *reply)
+{
+  auth_meta->auth_mode = payload[0];
+  if (auth_meta->auth_mode < AUTH_MODE_AUTHORIZER ||
+      auth_meta->auth_mode > AUTH_MODE_AUTHORIZER_MAX) {
+    return -EACCES;
+  }
+  AuthAuthorizeHandler* ah = get_auth_authorize_handler(con->get_peer_type(),
+                                                        auth_method);
+  if (!ah) {
+    logger().error("no AuthAuthorizeHandler found for auth method: {}",
+                   auth_method);
+    return -EOPNOTSUPP;
+  }
+  ceph_assert(active_con);
+  bool was_challenge = (bool)auth_meta->authorizer_challenge;
+  EntityName name;
+  uint64_t global_id;
+  AuthCapsInfo caps_info;
+  bool is_valid = ah->verify_authorizer(
+    nullptr,
+    &active_con->get_keys(),
+    payload,
+    auth_meta->get_connection_secret_length(),
+    reply,
+    &name,
+    &global_id,
+    &caps_info,
+    &auth_meta->session_key,
+    &auth_meta->connection_secret,
+    &auth_meta->authorizer_challenge);
+  if (is_valid) {
+    auth_handler.handle_authentication(name, global_id, caps_info);
+    return 1;
+  }
+  if (!more && !was_challenge && auth_meta->authorizer_challenge) {
+    logger().info("added challenge on {}", con);
+    return 0;
+  } else {
+    logger().info("bad authorizer on {}", con);
+    return -EACCES;
+  }
+}
+
 seastar::future<> Client::handle_monmap(ceph::net::ConnectionRef conn,
                                         Ref<MMonMap> m)
 {
index 1d9e368a77f271a906c4bd41c8d9b79fc9537c9a..c96bf80f1295048fbdb5d5b3c26ab70267bebe63 100644 (file)
@@ -11,7 +11,9 @@
 
 #include "auth/KeyRing.h"
 
+#include "crimson/auth/AuthServer.h"
 #include "crimson/common/auth_service.h"
+#include "crimson/common/auth_handler.h"
 #include "crimson/net/Dispatcher.h"
 #include "crimson/net/Fwd.h"
 
@@ -38,7 +40,8 @@ namespace ceph::mon {
 class Connection;
 
 class Client : public ceph::net::Dispatcher,
-              public ceph::common::AuthService
+              public ceph::common::AuthService,
+              public ceph::auth::AuthServer
 {
   EntityName entity_name;
   KeyRing keyring;
@@ -53,6 +56,7 @@ class Client : public ceph::net::Dispatcher,
   seastar::gate tick_gate;
 
   ceph::net::Messenger& msgr;
+  ceph::common::AuthHandler& auth_handler;
 
   // commands
   using get_version_t = seastar::future<version_t, version_t>;
@@ -68,8 +72,7 @@ class Client : public ceph::net::Dispatcher,
   MonSub sub;
 
 public:
-  Client(ceph::net::Messenger& messenger);
-  Client(Client&&);
+  Client(ceph::net::Messenger&, ceph::common::AuthHandler&);
   ~Client();
   seastar::future<> start();
   seastar::future<> stop();
@@ -88,6 +91,13 @@ public:
   seastar::future<> renew_subs();
   // AuthService methods
   AuthAuthorizer* get_authorizer(peer_type_t peer) const override;
+  // AuthServer methods
+  int handle_auth_request(ceph::net::ConnectionRef conn,
+                         AuthConnectionMetaRef auth_meta,
+                         bool more,
+                         uint32_t auth_method,
+                         const ceph::bufferlist& payload,
+                         ceph::bufferlist *reply);
 
 private:
   void tick();
index 945f0cd6dc115fd4ce8c2728a20f18cd4ea1b2eb..3c7105235afb0e1468814112d4aaf12a5ef41689 100644 (file)
@@ -59,7 +59,7 @@ OSD::OSD(int id, uint32_t nonce,
     beacon_timer{[this] { send_beacon(); }},
     cluster_msgr{cluster_msgr},
     public_msgr{public_msgr},
-    monc{new ceph::mon::Client{public_msgr}},
+    monc{new ceph::mon::Client{public_msgr, *this}},
     mgrc{new ceph::mgr::Client{public_msgr, *this}},
     heartbeat{new Heartbeat{*this, *monc, hb_front_msgr, hb_back_msgr}},
     heartbeat_timer{[this] { update_heartbeat_peers(); }},
@@ -67,6 +67,10 @@ OSD::OSD(int id, uint32_t nonce,
       local_conf().get_val<std::string>("osd_data"))}
 {
   osdmaps[0] = boost::make_local_shared<OSDMap>();
+  for (auto msgr : {std::ref(cluster_msgr), std::ref(public_msgr),
+                 std::ref(hb_front_msgr), std::ref(hb_back_msgr)}) {
+    msgr.get().set_auth_server(monc.get());
+  }
 }
 
 OSD::~OSD() = default;
@@ -417,6 +421,13 @@ seastar::future<> OSD::ms_handle_remote_reset(ceph::net::ConnectionRef conn)
   return seastar::now();
 }
 
+void OSD::handle_authentication(const EntityName& name,
+                                 uint64_t global_id,
+                                 const AuthCapsInfo& caps)
+{
+  // todo
+}
+
 MessageRef OSD::get_stats()
 {
   // todo: m-to-n: collect stats using map-reduce
index d6ef79e43aa478e17808c635495ed01b2a5e4291..baeff0cc0f2bc3238115bd706d93c63a23e988b4 100644 (file)
@@ -10,6 +10,7 @@
 #include <seastar/core/shared_future.hh>
 #include <seastar/core/timer.hh>
 
+#include "crimson/common/auth_handler.h"
 #include "crimson/common/simple_lru.h"
 #include "crimson/common/shared_lru.h"
 #include "crimson/mgr/client.h"
@@ -46,6 +47,7 @@ template<typename T> using Ref = boost::intrusive_ptr<T>;
 
 class OSD : public ceph::net::Dispatcher,
            private OSDMapService,
+           private ceph::common::AuthHandler,
            private ceph::mgr::WithStats {
   seastar::gate gate;
   const int whoami;
@@ -88,9 +90,15 @@ class OSD : public ceph::net::Dispatcher,
   seastar::future<> ms_handle_connect(ceph::net::ConnectionRef conn) override;
   seastar::future<> ms_handle_reset(ceph::net::ConnectionRef conn) override;
   seastar::future<> ms_handle_remote_reset(ceph::net::ConnectionRef conn) override;
+
   // mgr::WithStats methods
   MessageRef get_stats() override;
 
+  // AuthHandler methods
+  void handle_authentication(const EntityName& name,
+                            uint64_t global_id,
+                            const AuthCapsInfo& caps) final;
+
 public:
   OSD(int id, uint32_t nonce,
       ceph::net::Messenger& cluster_msgr,