From e2f2a7f6061b08a971c87468f8c69c5bf6f1a97e Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Sat, 6 Apr 2019 21:00:59 +0800 Subject: [PATCH] crimson: update osd when peer gets authenticated * 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 --- src/crimson/common/auth_handler.h | 18 +++++++++ src/crimson/mon/MonClient.cc | 61 +++++++++++++++++++++++++++++-- src/crimson/mon/MonClient.h | 16 ++++++-- src/crimson/osd/osd.cc | 13 ++++++- src/crimson/osd/osd.h | 8 ++++ 5 files changed, 109 insertions(+), 7 deletions(-) create mode 100644 src/crimson/common/auth_handler.h diff --git a/src/crimson/common/auth_handler.h b/src/crimson/common/auth_handler.h new file mode 100644 index 0000000000000..521c75d0a42d1 --- /dev/null +++ b/src/crimson/common/auth_handler.h @@ -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; +}; +} diff --git a/src/crimson/mon/MonClient.cc b/src/crimson/mon/MonClient.cc index 73ebf0be356a5..d47bf04cf13f4 100644 --- a/src/crimson/mon/MonClient.cc +++ b/src/crimson/mon/MonClient.cc @@ -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 Connection::create_auth(Ref 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 m) { diff --git a/src/crimson/mon/MonClient.h b/src/crimson/mon/MonClient.h index 1d9e368a77f27..c96bf80f12950 100644 --- a/src/crimson/mon/MonClient.h +++ b/src/crimson/mon/MonClient.h @@ -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; @@ -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(); diff --git a/src/crimson/osd/osd.cc b/src/crimson/osd/osd.cc index 945f0cd6dc115..3c7105235afb0 100644 --- a/src/crimson/osd/osd.cc +++ b/src/crimson/osd/osd.cc @@ -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("osd_data"))} { osdmaps[0] = boost::make_local_shared(); + 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 diff --git a/src/crimson/osd/osd.h b/src/crimson/osd/osd.h index d6ef79e43aa47..baeff0cc0f2bc 100644 --- a/src/crimson/osd/osd.h +++ b/src/crimson/osd/osd.h @@ -10,6 +10,7 @@ #include #include +#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 using Ref = boost::intrusive_ptr; 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, -- 2.39.5