diff options
Diffstat (limited to '')
-rw-r--r-- | src/crimson/auth/AuthClient.h | 71 | ||||
-rw-r--r-- | src/crimson/auth/AuthServer.h | 41 | ||||
-rw-r--r-- | src/crimson/auth/DummyAuth.h | 78 | ||||
-rw-r--r-- | src/crimson/auth/KeyRing.cc | 79 | ||||
-rw-r--r-- | src/crimson/auth/KeyRing.h | 15 |
5 files changed, 284 insertions, 0 deletions
diff --git a/src/crimson/auth/AuthClient.h b/src/crimson/auth/AuthClient.h new file mode 100644 index 000000000..cd21b3838 --- /dev/null +++ b/src/crimson/auth/AuthClient.h @@ -0,0 +1,71 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include <cstdint> +#include <string> +#include <tuple> +#include <vector> +#include "include/buffer_fwd.h" +#include "crimson/net/Fwd.h" + +class CryptoKey; + +namespace crimson::auth { + +class error : public std::logic_error { +public: + using std::logic_error::logic_error; +}; + +using method_t = uint32_t; + +// TODO: revisit interfaces for non-dummy implementations +class AuthClient { +public: + virtual ~AuthClient() {} + + struct auth_request_t { + method_t auth_method; + std::vector<uint32_t> preferred_modes; + ceph::bufferlist auth_bl; + }; + /// Build an authentication request to begin the handshake + /// + /// @throw auth::error if unable to build the request + virtual auth_request_t get_auth_request(crimson::net::ConnectionRef conn, + AuthConnectionMetaRef auth_meta) = 0; + + /// Handle server's request to continue the handshake + /// + /// @throw auth::error if unable to build the request + virtual ceph::bufferlist handle_auth_reply_more( + crimson::net::ConnectionRef conn, + AuthConnectionMetaRef auth_meta, + const ceph::bufferlist& bl) = 0; + + /// Handle server's indication that authentication succeeded + /// + /// @return 0 if authenticated, a negative number otherwise + virtual int handle_auth_done( + crimson::net::ConnectionRef conn, + AuthConnectionMetaRef auth_meta, + uint64_t global_id, + uint32_t con_mode, + const bufferlist& bl) = 0; + + /// Handle server's indication that the previous auth attempt failed + /// + /// @return 0 if will try next auth method, a negative number if we have no + /// more options + virtual int handle_auth_bad_method( + crimson::net::ConnectionRef conn, + AuthConnectionMetaRef auth_meta, + uint32_t old_auth_method, + int result, + const std::vector<uint32_t>& allowed_methods, + const std::vector<uint32_t>& allowed_modes) = 0; +}; + +} // namespace crimson::auth diff --git a/src/crimson/auth/AuthServer.h b/src/crimson/auth/AuthServer.h new file mode 100644 index 000000000..d75c8f586 --- /dev/null +++ b/src/crimson/auth/AuthServer.h @@ -0,0 +1,41 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include <cstdint> +#include <utility> +#include <vector> +#include "crimson/net/Fwd.h" + +struct AuthAuthorizeHandler; + +namespace crimson::auth { + +class AuthServer { +public: + virtual ~AuthServer() {} + + // Get authentication methods and connection modes for the given peer type + virtual std::pair<std::vector<uint32_t>, std::vector<uint32_t>> + get_supported_auth_methods(int peer_type) = 0; + // Get support connection modes for the given peer type and auth method + virtual uint32_t pick_con_mode( + int peer_type, + uint32_t auth_method, + const std::vector<uint32_t>& preferred_modes) = 0; + // return an AuthAuthorizeHandler for the given peer type and auth method + virtual AuthAuthorizeHandler* get_auth_authorize_handler( + int peer_type, + int auth_method) = 0; + // Handle an authentication request on an incoming connection + virtual int handle_auth_request( + crimson::net::ConnectionRef conn, + AuthConnectionMetaRef auth_meta, + bool more, //< true if this is not the first part of the handshake + uint32_t auth_method, + const bufferlist& bl, + bufferlist *reply) = 0; +}; + +} // namespace crimson::auth diff --git a/src/crimson/auth/DummyAuth.h b/src/crimson/auth/DummyAuth.h new file mode 100644 index 000000000..7c26140a2 --- /dev/null +++ b/src/crimson/auth/DummyAuth.h @@ -0,0 +1,78 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "AuthClient.h" +#include "AuthServer.h" + +namespace crimson::auth { + +class DummyAuthClientServer : public AuthClient, + public AuthServer { +public: + DummyAuthClientServer() {} + + // client + std::pair<std::vector<uint32_t>, std::vector<uint32_t>> + get_supported_auth_methods(int peer_type) final { + return {{CEPH_AUTH_NONE}, {CEPH_AUTH_NONE}}; + } + + uint32_t pick_con_mode(int peer_type, + uint32_t auth_method, + const std::vector<uint32_t>& preferred_modes) final { + ceph_assert(auth_method == CEPH_AUTH_NONE); + ceph_assert(preferred_modes.size() && + preferred_modes[0] == CEPH_CON_MODE_CRC); + return CEPH_CON_MODE_CRC; + } + + AuthAuthorizeHandler* get_auth_authorize_handler(int peer_type, + int auth_method) final { + return nullptr; + } + + AuthClient::auth_request_t get_auth_request( + crimson::net::ConnectionRef conn, + AuthConnectionMetaRef auth_meta) override { + return {CEPH_AUTH_NONE, {CEPH_CON_MODE_CRC}, {}}; + } + + ceph::bufferlist handle_auth_reply_more( + crimson::net::ConnectionRef conn, + AuthConnectionMetaRef auth_meta, + const bufferlist& bl) override { + ceph_abort(); + } + + int handle_auth_done( + crimson::net::ConnectionRef conn, + AuthConnectionMetaRef auth_meta, + uint64_t global_id, + uint32_t con_mode, + const bufferlist& bl) override { + return 0; + } + + int handle_auth_bad_method( + crimson::net::ConnectionRef conn, + AuthConnectionMetaRef auth_meta, + uint32_t old_auth_method, + int result, + const std::vector<uint32_t>& allowed_methods, + const std::vector<uint32_t>& allowed_modes) override { + ceph_abort(); + } + + // server + int handle_auth_request( + crimson::net::ConnectionRef conn, + AuthConnectionMetaRef auth_meta, + bool more, + uint32_t auth_method, + const bufferlist& bl, + bufferlist *reply) override { + return 1; + } +}; + +} // namespace crimson::auth diff --git a/src/crimson/auth/KeyRing.cc b/src/crimson/auth/KeyRing.cc new file mode 100644 index 000000000..436e29c1b --- /dev/null +++ b/src/crimson/auth/KeyRing.cc @@ -0,0 +1,79 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "KeyRing.h" + +#include <boost/algorithm/string.hpp> + +#include <seastar/core/do_with.hh> +#include <seastar/core/fstream.hh> +#include <seastar/core/future-util.hh> +#include <seastar/core/reactor.hh> + +#include "common/buffer_seastar.h" +#include "auth/KeyRing.h" +#include "include/denc.h" +#include "crimson/common/buffer_io.h" +#include "crimson/common/config_proxy.h" + +namespace crimson::auth { + +seastar::future<KeyRing*> load_from_keyring(KeyRing* keyring) +{ + std::vector<std::string> paths; + boost::split(paths, crimson::common::local_conf()->keyring, + boost::is_any_of(",;")); + std::pair<bool, std::string> found; + return seastar::map_reduce(paths, [](auto path) { + return seastar::engine().file_exists(path).then([path](bool file_exists) { + return std::make_pair(file_exists, path); + }); + }, std::move(found), [](auto found, auto file_exists_and_path) { + if (!found.first && file_exists_and_path.first) { + found = std::move(file_exists_and_path); + } + return found; + }).then([keyring] (auto file_exists_and_path) { + const auto& [exists, path] = file_exists_and_path; + if (exists) { + return read_file(path).then([keyring](auto buf) { + bufferlist bl; + bl.append(buffer::create(std::move(buf))); + auto i = bl.cbegin(); + keyring->decode(i); + return seastar::make_ready_future<KeyRing*>(keyring); + }); + } else { + return seastar::make_ready_future<KeyRing*>(keyring); + } + }); +} + +seastar::future<KeyRing*> load_from_keyfile(KeyRing* keyring) +{ + auto& path = crimson::common::local_conf()->keyfile; + if (!path.empty()) { + return read_file(path).then([keyring](auto buf) { + EntityAuth ea; + ea.key.decode_base64(std::string(buf.begin(), + buf.end())); + keyring->add(crimson::common::local_conf()->name, ea); + return seastar::make_ready_future<KeyRing*>(keyring); + }); + } else { + return seastar::make_ready_future<KeyRing*>(keyring); + } +} + +seastar::future<KeyRing*> load_from_key(KeyRing* keyring) +{ + auto& key = crimson::common::local_conf()->key; + if (!key.empty()) { + EntityAuth ea; + ea.key.decode_base64(key); + keyring->add(crimson::common::local_conf()->name, ea); + } + return seastar::make_ready_future<KeyRing*>(keyring); +} + +} // namespace crimson::auth diff --git a/src/crimson/auth/KeyRing.h b/src/crimson/auth/KeyRing.h new file mode 100644 index 000000000..850f1bb79 --- /dev/null +++ b/src/crimson/auth/KeyRing.h @@ -0,0 +1,15 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#pragma once + +#include <seastar/core/future.hh> + +class KeyRing; + +namespace crimson::auth { + // see KeyRing::from_ceph_context + seastar::future<KeyRing*> load_from_keyring(KeyRing* keyring); + seastar::future<KeyRing*> load_from_keyfile(KeyRing* keyring); + seastar::future<KeyRing*> load_from_key(KeyRing* keyring); +} |