+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2009-2011 New Dream Network
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation. See file COPYING.
- *
- */
-
-#include "AuthAuthorizeHandler.h"
-#include "cephx/CephxAuthorizeHandler.h"
-#ifdef HAVE_GSSAPI
-#include "krb/KrbAuthorizeHandler.hpp"
-#endif
-#include "none/AuthNoneAuthorizeHandler.h"
-
-AuthAuthorizeHandler *AuthAuthorizeHandlerRegistry::get_handler(int protocol)
-{
- if (!supported.is_supported_auth(protocol)) {
- return NULL;
- }
-
- std::scoped_lock l{m_lock};
- map<int,AuthAuthorizeHandler*>::iterator iter = m_authorizers.find(protocol);
- if (iter != m_authorizers.end())
- return iter->second;
-
- switch (protocol) {
- case CEPH_AUTH_NONE:
- m_authorizers[protocol] = new AuthNoneAuthorizeHandler();
- return m_authorizers[protocol];
-
- case CEPH_AUTH_CEPHX:
- m_authorizers[protocol] = new CephxAuthorizeHandler();
- return m_authorizers[protocol];
-#ifdef HAVE_GSSAPI
- case CEPH_AUTH_GSS:
- m_authorizers[protocol] = new KrbAuthorizeHandler();
- return m_authorizers[protocol];
-#endif
- default:
- return nullptr;
- }
-}
-
-AuthAuthorizeHandlerRegistry::~AuthAuthorizeHandlerRegistry()
-{
- for (map<int,AuthAuthorizeHandler*>::iterator iter = m_authorizers.begin();
- iter != m_authorizers.end();
- ++iter)
- delete iter->second;
-}
#define CEPH_AUTHAUTHORIZEHANDLER_H
#include "Auth.h"
-#include "AuthMethodList.h"
#include "include/types.h"
#include "common/ceph_mutex.h"
// Different classes of session crypto handling
virtual int authorizer_session_crypto() = 0;
};
-class AuthAuthorizeHandlerRegistry {
- ceph::mutex m_lock;
- map<int,AuthAuthorizeHandler*> m_authorizers;
- AuthMethodList supported;
-
-public:
- AuthAuthorizeHandlerRegistry(CephContext *cct_, const std::string &methods)
- : m_lock{ceph::make_mutex("AuthAuthorizeHandlerRegistry::m_lock")},
- supported{cct_, methods}
- {}
- ~AuthAuthorizeHandlerRegistry();
-
- void get_supported_methods(std::vector<uint32_t> *v) {
- v->clear();
- for (auto m : supported.get_supported_set()) {
- v->push_back(m);
- }
- }
- AuthAuthorizeHandler *get_handler(int protocol);
-};
-
#endif
#include <vector>
class EntityName;
-class AuthMethodList;
class CryptoKey;
class AuthClient {
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "AuthRegistry.h"
+
+#include "cephx/CephxAuthorizeHandler.h"
+#ifdef HAVE_GSSAPI
+#include "krb/KrbAuthorizeHandler.hpp"
+#endif
+#include "none/AuthNoneAuthorizeHandler.h"
+#include "common/ceph_context.h"
+#include "common/debug.h"
+#include "auth/KeyRing.h"
+
+#define dout_subsys ceph_subsys_auth
+#undef dout_prefix
+#define dout_prefix *_dout << "AuthRegistry(" << this << ") "
+
+const char** AuthRegistry::get_tracked_conf_keys() const
+{
+ static const char *keys[] = {
+ "auth_supported",
+ "auth_client_required",
+ "auth_cluster_required",
+ "auth_service_required",
+ "keyring",
+ NULL
+ };
+ return keys;
+}
+
+void AuthRegistry::handle_conf_change(
+ const ConfigProxy& conf,
+ const std::set<std::string>& changed)
+{
+ std::scoped_lock l(lock);
+ _refresh_config();
+}
+
+
+void AuthRegistry::_parse_method_list(const string& s,
+ std::vector<uint32_t> *v)
+{
+ std::list<std::string> sup_list;
+ get_str_list(s, sup_list);
+ if (sup_list.empty()) {
+ lderr(cct) << "WARNING: empty auth protocol list" << dendl;
+ }
+ for (auto& i : sup_list) {
+ ldout(cct, 5) << "adding auth protocol: " << i << dendl;
+ if (i == "cephx") {
+ v->push_back(CEPH_AUTH_CEPHX);
+ } else if (i == "none") {
+ v->push_back(CEPH_AUTH_NONE);
+ } else if (i == "gss") {
+ v->push_back(CEPH_AUTH_GSS);
+ } else {
+ v->push_back(CEPH_AUTH_UNKNOWN);
+ lderr(cct) << "WARNING: unknown auth protocol defined: " << i << dendl;
+ }
+ }
+ if (v->empty()) {
+ lderr(cct) << "WARNING: no auth protocol defined, use 'cephx' by default"
+ << dendl;
+ v->push_back(CEPH_AUTH_CEPHX);
+ }
+ ldout(cct,20) << __func__ << " " << s << " -> " << *v << dendl;
+}
+
+void AuthRegistry::_refresh_config()
+{
+ if (cct->_conf->auth_supported.size()) {
+ _parse_method_list(cct->_conf->auth_supported, &cluster_methods);
+ _parse_method_list(cct->_conf->auth_supported, &service_methods);
+ _parse_method_list(cct->_conf->auth_supported, &client_methods);
+ } else {
+ _parse_method_list(cct->_conf->auth_cluster_required, &cluster_methods);
+ _parse_method_list(cct->_conf->auth_service_required, &service_methods);
+ _parse_method_list(cct->_conf->auth_client_required, &client_methods);
+ }
+
+ ldout(cct,10) << __func__ << " cluster_methods " << cluster_methods
+ << " service_methods " << service_methods
+ << " client_methods " << client_methods
+ << dendl;
+
+ // if we have no keyring, filter out cephx
+ _no_keyring_disabled_cephx = false;
+ KeyRing k;
+ int r = k.from_ceph_context(cct);
+ if (r == -ENOENT) {
+ for (auto *p : {&cluster_methods, &service_methods, &client_methods}) {
+ auto q = std::find(p->begin(), p->end(), CEPH_AUTH_CEPHX);
+ if (q != p->end()) {
+ p->erase(q);
+ _no_keyring_disabled_cephx = true;
+ }
+ }
+ }
+ if (_no_keyring_disabled_cephx) {
+ lderr(cct) << "no keyring found at " << cct->_conf->keyring
+ << ", disabling cephx" << dendl;
+ }
+}
+
+void AuthRegistry::get_supported_methods(int peer_type,
+ std::vector<uint32_t> *v)
+{
+ if (cct->get_module_type() == CEPH_ENTITY_TYPE_CLIENT) {
+ *v = client_methods;
+ return;
+ }
+ switch (peer_type) {
+ case CEPH_ENTITY_TYPE_MON:
+ case CEPH_ENTITY_TYPE_MGR:
+ case CEPH_ENTITY_TYPE_MDS:
+ case CEPH_ENTITY_TYPE_OSD:
+ *v = cluster_methods;
+ break;
+ default:
+ *v = service_methods;
+ break;
+ }
+}
+
+bool AuthRegistry::is_supported_method(int peer_type, int method)
+{
+ std::vector<uint32_t> s;
+ get_supported_methods(peer_type, &s);
+ return std::find(s.begin(), s.end(), method) != s.end();
+}
+
+bool AuthRegistry::any_supported_methods(int peer_type)
+{
+ std::vector<uint32_t> s;
+ get_supported_methods(peer_type, &s);
+ return !s.empty();
+}
+
+AuthAuthorizeHandler *AuthRegistry::get_handler(int peer_type, int method)
+{
+ std::scoped_lock l{lock};
+ ldout(cct,20) << __func__ << " peer_type " << peer_type << " method " << method
+ << " cluster_methods " << cluster_methods
+ << " service_methods " << service_methods
+ << " client_methods " << client_methods
+ << dendl;
+ if (cct->get_module_type() == CEPH_ENTITY_TYPE_CLIENT) {
+ return nullptr;
+ }
+ switch (peer_type) {
+ case CEPH_ENTITY_TYPE_MON:
+ case CEPH_ENTITY_TYPE_MGR:
+ case CEPH_ENTITY_TYPE_MDS:
+ case CEPH_ENTITY_TYPE_OSD:
+ if (std::find(cluster_methods.begin(), cluster_methods.end(), method) ==
+ cluster_methods.end()) {
+ return nullptr;
+ }
+ break;
+ default:
+ if (std::find(service_methods.begin(), service_methods.end(), method) ==
+ service_methods.end()) {
+ return nullptr;
+ }
+ break;
+ }
+
+ auto iter = authorize_handlers.find(method);
+ if (iter != authorize_handlers.end()) {
+ return iter->second;
+ }
+ AuthAuthorizeHandler *ah = nullptr;
+ switch (method) {
+ case CEPH_AUTH_NONE:
+ ah = new AuthNoneAuthorizeHandler();
+ break;
+ case CEPH_AUTH_CEPHX:
+ ah = new CephxAuthorizeHandler();
+ break;
+#ifdef HAVE_GSSAPI
+ case CEPH_AUTH_GSS:
+ ah = new KrbAuthorizeHandler();
+ break;
+#endif
+ }
+ if (ah) {
+ authorize_handlers[method] = ah;
+ }
+ return ah;
+}
+
+AuthRegistry::~AuthRegistry()
+{
+ for (auto i : authorize_handlers) {
+ delete i.second;
+ }
+}
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include <map>
+#include <vector>
+
+#include "AuthAuthorizeHandler.h"
+#include "AuthMethodList.h"
+#include "common/ceph_mutex.h"
+#include "common/ceph_context.h"
+#include "common/config_cacher.h"
+
+class AuthRegistry : public md_config_obs_t {
+ CephContext *cct;
+ ceph::mutex lock = ceph::make_mutex("AuthRegistry::lock");
+
+ std::map<int,AuthAuthorizeHandler*> authorize_handlers;
+
+ bool _no_keyring_disabled_cephx = false;
+
+ std::vector<uint32_t> cluster_methods; // CEPH_AUTH_*
+ std::vector<uint32_t> service_methods; // CEPH_AUTH_*
+ std::vector<uint32_t> client_methods; // CEPH_AUTH_*
+
+ void _parse_method_list(const string& str, std::vector<uint32_t> *v);
+ void _refresh_config();
+
+public:
+ AuthRegistry(CephContext *cct) : cct(cct) {
+ }
+ ~AuthRegistry();
+
+ void refresh_config() {
+ std::scoped_lock l(lock);
+ _refresh_config();
+ }
+
+ void get_supported_methods(int peer_type, std::vector<uint32_t> *v);
+ bool is_supported_method(int peer_type, int method);
+ bool any_supported_methods(int peer_type);
+
+ AuthAuthorizeHandler *get_handler(int peer_type, int method);
+
+ const char** get_tracked_conf_keys() const override;
+ void handle_conf_change(const ConfigProxy& conf,
+ const std::set<std::string>& changed) override;
+
+ bool no_keyring_disabled_cephx() {
+ std::scoped_lock l(lock);
+ return _no_keyring_disabled_cephx;
+ }
+};
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-
-#include "AuthServer.h"
-#include "common/ceph_context.h"
-
-AuthServer::AuthServer(CephContext *cct)
- : auth_ah_service_registry(
- new AuthAuthorizeHandlerRegistry(
- cct,
- cct->_conf->auth_supported.empty() ?
- cct->_conf->auth_service_required :
- cct->_conf->auth_supported)),
- auth_ah_cluster_registry(
- new AuthAuthorizeHandlerRegistry(
- cct,
- cct->_conf->auth_supported.empty() ?
- cct->_conf->auth_cluster_required :
- cct->_conf->auth_supported))
-{
-}
-
-AuthAuthorizeHandler *AuthServer::get_auth_authorize_handler(
- int peer_type,
- int auth_method)
-{
- switch (peer_type) {
- case CEPH_ENTITY_TYPE_MDS:
- case CEPH_ENTITY_TYPE_MON:
- case CEPH_ENTITY_TYPE_MGR:
- case CEPH_ENTITY_TYPE_OSD:
- return auth_ah_cluster_registry->get_handler(auth_method);
- default:
- return auth_ah_service_registry->get_handler(auth_method);
- }
-}
-
-void AuthServer::get_supported_auth_methods(
- int peer_type,
- vector<uint32_t> *methods)
-{
- switch (peer_type) {
- case CEPH_ENTITY_TYPE_MDS:
- case CEPH_ENTITY_TYPE_MON:
- case CEPH_ENTITY_TYPE_MGR:
- case CEPH_ENTITY_TYPE_OSD:
- return auth_ah_cluster_registry->get_supported_methods(methods);
- default:
- return auth_ah_service_registry->get_supported_methods(methods);
- }
-}
#pragma once
-#include "AuthAuthorizeHandler.h"
+#include "AuthRegistry.h"
#include <vector>
class Connection;
class AuthServer {
-private:
- std::unique_ptr<AuthAuthorizeHandlerRegistry> auth_ah_service_registry;
- std::unique_ptr<AuthAuthorizeHandlerRegistry> auth_ah_cluster_registry;
public:
- AuthServer(CephContext *cct);
+ AuthRegistry auth_registry;
+
+ AuthServer(CephContext *cct) : auth_registry(cct) {}
virtual ~AuthServer() {}
- AuthAuthorizeHandler *get_auth_authorize_handler(
+ virtual void get_supported_auth_methods(
int peer_type,
- int auth_method);
+ std::vector<uint32_t> *methods) {
+ auth_registry.get_supported_methods(peer_type, methods);
+ }
- virtual void get_supported_auth_methods(
+ AuthAuthorizeHandler *get_auth_authorize_handler(
int peer_type,
- std::vector<uint32_t> *methods);
+ int auth_method) {
+ return auth_registry.get_handler(peer_type, auth_method);
+ }
virtual int handle_auth_request(
Connection *con,
set(auth_srcs
- AuthAuthorizeHandler.cc
AuthClientHandler.cc
AuthMethodList.cc
- AuthServer.cc
+ AuthRegistry.cc
AuthSessionHandler.cc
Crypto.cc
KeyRing.cc
{ "leveldb_cache_size", "536870912" },
{ "leveldb_block_size", "65536" },
{ "leveldb_compression", "false"},
- { "leveldb_log", "" }
+ { "leveldb_log", "" },
+ { "keyring", "$mon_data/keyring" },
};
int flags = 0;
entity_name = cct->_conf->name;
- std::lock_guard l(monc_lock);
+ auth_registry.refresh_config();
- string method;
- if (!cct->_conf->auth_supported.empty())
- method = cct->_conf->auth_supported;
- else if (entity_name.get_type() == CEPH_ENTITY_TYPE_OSD ||
- entity_name.get_type() == CEPH_ENTITY_TYPE_MDS ||
- entity_name.get_type() == CEPH_ENTITY_TYPE_MON ||
- entity_name.get_type() == CEPH_ENTITY_TYPE_MGR)
- method = cct->_conf->auth_cluster_required;
- else
- method = cct->_conf->auth_client_required;
- auth_supported.reset(new AuthMethodList(cct, method));
- ldout(cct, 10) << "auth_supported " << auth_supported->get_supported_set() << " method " << method << dendl;
-
- int r = 0;
- keyring.reset(new KeyRing); // initializing keyring anyway
-
- if (auth_supported->is_supported_auth(CEPH_AUTH_CEPHX)) {
- r = keyring->from_ceph_context(cct);
- if (r == -ENOENT) {
- auth_supported->remove_supported_auth(CEPH_AUTH_CEPHX);
- if (!auth_supported->get_supported_set().empty()) {
- r = 0;
- no_keyring_disabled_cephx = true;
- } else {
- lderr(cct) << "ERROR: missing keyring, cannot use cephx for authentication" << dendl;
- }
+ std::lock_guard l(monc_lock);
+ keyring.reset(new KeyRing);
+ if (auth_registry.is_supported_method(messenger->get_mytype(),
+ CEPH_AUTH_CEPHX)) {
+ // this should succeed, because auth_registry just checked!
+ int r = keyring->from_ceph_context(cct);
+ if (r != 0) {
+ // but be somewhat graceful in case there was a race condition
+ lderr(cct) << "keyring not found" << dendl;
+ return r;
}
}
-
- if (r < 0) {
- return r;
+ if (!auth_registry.any_supported_methods(messenger->get_mytype())) {
+ return -ENOENT;
}
rotating_secrets.reset(
authenticated = true;
}
- if (authenticate_err < 0 && no_keyring_disabled_cephx) {
+ if (authenticate_err < 0 && auth_registry.no_keyring_disabled_cephx()) {
lderr(cct) << __func__ << " NOTE: no keyring found; disabled cephx authentication" << dendl;
}
}
for (auto& c : pending_cons) {
- c.second.start(monmap.get_epoch(), entity_name, *auth_supported);
+ c.second.start(monmap.get_epoch(), entity_name);
}
if (sub.reload()) {
{
auto peer = monmap.get_addrs(rank);
auto conn = messenger->connect_to_mon(peer);
- MonConnection mc(cct, conn, global_id, auth_supported->get_supported_set());
+ MonConnection mc(cct, conn, global_id, &auth_registry);
auto inserted = pending_cons.insert(make_pair(peer, move(mc)));
ldout(cct, 10) << "picked mon." << monmap.get_name(rank)
<< " con " << conn
MonConnection::MonConnection(
CephContext *cct, ConnectionRef con, uint64_t global_id,
- const list<uint32_t>& auth_supported)
- : cct(cct), con(con), global_id(global_id), auth_supported(auth_supported)
+ AuthRegistry *ar)
+ : cct(cct), con(con), global_id(global_id), auth_registry(ar)
{}
MonConnection::~MonConnection()
}
void MonConnection::start(epoch_t epoch,
- const EntityName& entity_name,
- const AuthMethodList& auth_supported)
+ const EntityName& entity_name)
{
if (con->get_peer_addr().is_msgr2()) {
ldout(cct, 10) << __func__ << " opening mon connection" << dendl;
m->monmap_epoch = epoch;
__u8 struct_v = 1;
encode(struct_v, m->auth_payload);
- encode(auth_supported.get_supported_set(), m->auth_payload);
+ vector<uint32_t> auth_supported;
+ auth_registry->get_supported_methods(con->get_peer_type(), &auth_supported);
+ encode(auth_supported, m->auth_payload);
encode(entity_name, m->auth_payload);
encode(global_id, m->auth_payload);
con->send_message(m);
{
// choose method
if (auth_method < 0) {
- auth_method = auth_supported.front();
+ vector<uint32_t> as;
+ auth_registry->get_supported_methods(con->get_peer_type(), &as);
+ auth_method = as.front();
}
*method = auth_method;
ldout(cct,10) << __func__ << " method " << *method << dendl;
ldout(cct,10) << __func__ << " old_auth_method " << old_auth_method
<< " result " << cpp_strerror(result)
<< " allowed_methods " << allowed_methods << dendl;
+ vector<uint32_t> auth_supported;
+ auth_registry->get_supported_methods(con->get_peer_type(), &auth_supported);
auto p = std::find(auth_supported.begin(), auth_supported.end(),
old_auth_method);
assert(p != auth_supported.end());
#include "auth/AuthClient.h"
#include "auth/AuthServer.h"
+#include "auth/AuthRegistry.h"
class MMonMap;
class MConfig;
MonConnection(CephContext *cct,
ConnectionRef conn,
uint64_t global_id,
- const list<uint32_t>& auto_supported);
+ AuthRegistry *auth_registry);
~MonConnection();
MonConnection(MonConnection&& rhs) = default;
MonConnection& operator=(MonConnection&&) = default;
RotatingKeyRing* keyring);
int authenticate(MAuthReply *m);
void start(epoch_t epoch,
- const EntityName& entity_name,
- const AuthMethodList& auth_supported);
+ const EntityName& entity_name);
bool have_session() const;
uint64_t get_global_id() const {
return global_id;
std::unique_ptr<AuthClientHandler> auth;
uint64_t global_id;
- const list<uint32_t>& auth_supported;
+
+ AuthRegistry *auth_registry;
};
class MonClient : public Dispatcher,
bool initialized;
bool stopping = false;
- bool no_keyring_disabled_cephx = false;
- bool no_ktfile_disabled_krb = false;
LogClient *log_client;
bool more_log_pending;
void send_log(bool flush = false);
- std::unique_ptr<AuthMethodList> auth_supported;
-
bool ms_dispatch(Message *m) override;
bool ms_handle_reset(Connection *con) override;
void ms_handle_remote_reset(Connection *con) override {}
mgr_messenger->add_dispatcher_tail(this); // for auth ms_* calls
mgr_messenger->set_auth_client(this);
+ auth_registry.refresh_config();
+
bootstrap();
// add features of myself into feature_map
session_map.feature_map.add_mon(con_self->get_features());
socket_priority(-1),
cct(cct_),
crcflags(get_default_crc_flags(cct->_conf)),
- auth_ah_service_registry(
- new AuthAuthorizeHandlerRegistry(
- cct,
- cct->_conf->auth_supported.empty() ?
- cct->_conf->auth_service_required :
- cct->_conf->auth_supported)),
- auth_ah_cluster_registry(
- new AuthAuthorizeHandlerRegistry(
- cct,
- cct->_conf->auth_supported.empty() ?
- cct->_conf->auth_cluster_required :
- cct->_conf->auth_supported))
-{}
+ auth_registry(cct)
+{
+ auth_registry.refresh_config();
+}
void Messenger::set_endpoint_addr(const entity_addr_t& a,
const entity_name_t &name)
}
}
}
- AuthAuthorizeHandler *ah = 0;
- switch (peer_type) {
- case CEPH_ENTITY_TYPE_MDS:
- case CEPH_ENTITY_TYPE_MON:
- case CEPH_ENTITY_TYPE_OSD:
- ah = auth_ah_cluster_registry->get_handler(protocol);
- break;
- default:
- ah = auth_ah_service_registry->get_handler(protocol);
- }
+ AuthAuthorizeHandler *ah = auth_registry.get_handler(peer_type, protocol);
if (get_mytype() == CEPH_ENTITY_TYPE_MON &&
peer_type != CEPH_ENTITY_TYPE_MON) {
// the monitor doesn't do authenticators for msgr1.
#include "include/ceph_features.h"
#include "auth/Crypto.h"
#include "common/item_history.h"
-#include "auth/AuthAuthorizeHandler.h"
+#include "auth/AuthRegistry.h"
#include "include/ceph_assert.h"
#include <errno.h>
class Timer;
-class AuthAuthorizerHandlerRegistry;
class AuthClient;
class AuthServer;
protected:
// for authentication
- std::unique_ptr<AuthAuthorizeHandlerRegistry> auth_ah_service_registry;
- std::unique_ptr<AuthAuthorizeHandlerRegistry> auth_ah_cluster_registry;
+ AuthRegistry auth_registry;
public:
/**