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 <kchai@redhat.com>
This commit is contained in:
Kefu Chai 2019-04-06 21:00:59 +08:00
parent 30c822120a
commit e2f2a7f606
5 changed files with 109 additions and 7 deletions

View File

@ -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;
};
}

View 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)
{

View 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();

View 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

View 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,