Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

msg/async, v2: authenticated onwire encryption and new preamble format #26466

Merged
merged 69 commits into from Feb 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
6faedd3
msg/async: emphasize ProtocolV2 does authenticated encryption.
rzarzynski Jan 21, 2019
56e3ced
msg/async: drop get_auth_meta() from Protocol.
rzarzynski Jan 22, 2019
364ff3b
auth: drop sign_bufferlist() from AuthSessionHandler.
rzarzynski Jan 22, 2019
d0f1c64
auth: drop get_protocol() and get_key() from AuthSessionHandler.
rzarzynski Jan 22, 2019
1c8c96c
auth: drop no_security() from AuthSessionHandler.
rzarzynski Jan 22, 2019
2cb5f06
auth: make AuthSessionHandler purely abstract.
rzarzynski Jan 22, 2019
9e5f39d
auth: introduce DummyAuthSessionHandler.
rzarzynski Jan 22, 2019
9fc0b20
auth: drop {en,de}crypt_message() from AuthSessionHandler.
rzarzynski Jan 22, 2019
1291a8a
auth/cephx: make _calc_signature() of CephxSessionHandler private.
rzarzynski Jan 23, 2019
9d07d69
auth, msg: dissect AuthStreamHandler from AuthSessionHandler.
rzarzynski Jan 22, 2019
4d041a1
msg/async: move crypto handling from ProtocolV2 into AuthStreamHandler.
rzarzynski Jan 23, 2019
f6c7be8
include: uint128_t -> ceph::uint128_t + using.
rzarzynski Jan 28, 2019
e78a95f
crypto: AES128GCM_StreamHandler brings authenticated encryption with …
rzarzynski Jan 24, 2019
3dcde6f
msg/async, auth: switch AuthStreamHandler::rxtx_t to std::unique_ptr.
rzarzynski Jan 24, 2019
aff725e
msg/async: set con_mode and session_security at both peers.
rzarzynski Jan 26, 2019
8fa8e84
msg/async: drop MessageFrame. Use MessageHeaderFrame instead.
rzarzynski Jan 27, 2019
8245a29
msg/async: ensure consistency between con_mode and session_security.
rzarzynski Jan 27, 2019
4314944
auth: drop AES128CBC_HMACSHA256_StreamHandler.
rzarzynski Jan 28, 2019
a2a290c
msg/async: simplify encryption handling in the PayloadFrame class.
rzarzynski Jan 30, 2019
3ef5dc9
msg/async: move Protocol* asserts in SignedEncryptedFrame to compile …
rzarzynski Jan 30, 2019
d64fc23
msg/async: decouple MessageHeaderFrame from SignedEncryptedFrame.
rzarzynski Jan 30, 2019
8aa9306
auth: introduce ceph::crypto::onwire interfaces.
rzarzynski Feb 5, 2019
b2b06ea
auth: implement ceph::crypto::onwire with OpenSSL EVP.
rzarzynski Feb 5, 2019
78b68f8
msg/async: expose message segmentation to ::write_message().
rzarzynski Feb 7, 2019
7769de7
msg/async: SignedEncryptedFrame uses ceph::crypto::onwire.
rzarzynski Feb 7, 2019
9401df6
msg/async: Messages in Protocol2 are crypto-processed only once.
rzarzynski Feb 8, 2019
0ac6876
auth, msg/async, v2: drop AuthStreamHandler and AES128GCM_StreamHandler.
rzarzynski Feb 10, 2019
cbc0945
msg/async: reset the rx stream handler in ::handle_read_frame_length_…
rzarzynski Feb 11, 2019
9c0d244
msg/async: slightly rework ProtocolV2 preamble crafting.
rzarzynski Feb 11, 2019
488d10e
msg/async: preamble of V2 Frames is now encrypted and authenticated.
rzarzynski Feb 11, 2019
cee7565
msg/async: reset crypto processors in ProtocolV2::reset_recv_state().
rzarzynski Feb 11, 2019
a0a7d55
msg/async: transmit V2 messages with new preable format.
rzarzynski Feb 12, 2019
8628613
msg/async: receive V2 messages with new preable format.
rzarzynski Feb 13, 2019
53d44db
msg/async: implement crc checking for main preamble of V2.
rzarzynski Feb 13, 2019
696d2dc
msg/async: perform V2 frame dispatch in dedicated method.
rzarzynski Feb 13, 2019
430abcf
msg/async: V2 uses segments instead of next_payload_len, part 1.
rzarzynski Feb 14, 2019
14589a0
msg/async: add debug around empty ClientIdent::addrs.
rzarzynski Feb 14, 2019
34d48a3
msg/async: get rid of the distiction on main and extra V2 preamble.
rzarzynski Feb 14, 2019
a582600
msg/async: bump up preamble block size to 32 bytes.
rzarzynski Feb 14, 2019
893b225
msg/async: switch to CRC32 for V2 preamble blocks.
rzarzynski Feb 14, 2019
07c5482
msg/async: rectify reseting security state in ProtocolV2::reset_recv_…
rzarzynski Feb 14, 2019
e0741e6
msg/async: V2 bypasses throttles just for development.
rzarzynski Feb 14, 2019
eb444b8
msg/async: initial multi-segment support for V2.
rzarzynski Feb 15, 2019
7e951db
msg/async: WaitFrame of V2 can be crypto processed now.
rzarzynski Feb 14, 2019
f5707f3
msg/async, v2: READ_MESSAGE_FRONT -> THROTTLE_DONE.
rzarzynski Feb 15, 2019
9ef345f
msg/async, v2: drop the throttles bypass.
rzarzynski Feb 15, 2019
ee8deb4
msg/async, v2: workaround con_mode handling.
rzarzynski Feb 16, 2019
e02b2f5
msg/async, v2: bring back the no-encryption ability.
rzarzynski Feb 17, 2019
dbf8700
msg/async, v2: improve debug around sending client indent.
rzarzynski Feb 14, 2019
28646a6
msg/async/ProtocolV2: clean up preamble comments
liewegas Feb 17, 2019
0b7ef07
msg/Connection: add get_con_mode()
liewegas Feb 17, 2019
2ee03d1
common/ceph_strings: get_con_mode_name()
liewegas Feb 17, 2019
94f4cb2
msg/DispatchQueue: include con_mode in <== line
liewegas Feb 17, 2019
3bd8283
msg/async: add con_mode to debug lines
liewegas Feb 18, 2019
61d2d4a
msg/async, v2: drop reserve() from onwire crypto's TxHandler.
rzarzynski Feb 19, 2019
7adfc31
msg/async, v2: get rid of magic numbers for alignment.
rzarzynski Feb 19, 2019
0d9299d
msg/async, v2: drop handling of extra segments in ::fill_preamble().
rzarzynski Feb 19, 2019
da07664
msg/async, v2: follow the const bl& concept in authenticated_encrypt_…
rzarzynski Feb 19, 2019
813a8e1
msg/async, v2: decouple onwire segment length from logical length.
rzarzynski Feb 19, 2019
4423434
msg/async, v2: get rid of the magic number for default alignment.
rzarzynski Feb 20, 2019
50b5174
msg/async, v2: get rid of magic number in SignedEncryptedFrame.
rzarzynski Feb 20, 2019
8d49bc3
msg/async, v2: drop magic numbers for segments.
rzarzynski Feb 20, 2019
fa7e6d6
msg/async, v2: fix cur_msg_size in ::reset_recv_state().
rzarzynski Feb 20, 2019
fe387e0
msg/async, v2: drop depedency on uint128_t. Clean up onwire crypto.
rzarzynski Feb 20, 2019
2c2867a
msg/async, v2: handle msg authentication failures.
rzarzynski Feb 21, 2019
8bb18a8
msg/async, v2: drop the scaffolding in preamble parsing.
rzarzynski Feb 21, 2019
2ef6329
msg/async, v2: drop ceph_msg_header2 fields duplicating segment info.
rzarzynski Feb 21, 2019
774bd9d
msg/async, v2: frame decoding operates on bufferlist.
rzarzynski Feb 21, 2019
1ea9756
msg/async, v2: fix wrong base for KeepAliveFrameAck.
rzarzynski Feb 23, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/auth/Auth.h
Expand Up @@ -170,10 +170,10 @@ struct AuthConnectionMeta {

int con_mode = 0; ///< negotiated mode

bool is_mode_crc() {
bool is_mode_crc() const {
return con_mode == CEPH_CON_MODE_CRC;
}
bool is_mode_secure() {
bool is_mode_secure() const {
return con_mode == CEPH_CON_MODE_SECURE;
}

Expand Down
11 changes: 6 additions & 5 deletions src/auth/AuthSessionHandler.cc
Expand Up @@ -21,13 +21,13 @@
#include "none/AuthNoneSessionHandler.h"
#include "unknown/AuthUnknownSessionHandler.h"

#include "common/ceph_crypto.h"
#define dout_subsys ceph_subsys_auth


AuthSessionHandler *get_auth_session_handler(
CephContext *cct, int protocol,
const CryptoKey& key,
const std::string& connection_secret,
uint64_t features)
{

Expand All @@ -41,16 +41,17 @@ AuthSessionHandler *get_auth_session_handler(
if (key.get_type() == CEPH_CRYPTO_NONE) {
return nullptr;
}
return new CephxSessionHandler(cct, key, connection_secret, features);
return new CephxSessionHandler(cct, key, features);
case CEPH_AUTH_NONE:
return new AuthNoneSessionHandler(cct, key, connection_secret);
return new AuthNoneSessionHandler();
case CEPH_AUTH_UNKNOWN:
return new AuthUnknownSessionHandler(cct, key, connection_secret);
return new AuthUnknownSessionHandler();
#ifdef HAVE_GSSAPI
case CEPH_AUTH_GSS:
return new KrbSessionHandler(cct, key, connection_secret);
return new KrbSessionHandler();
#endif
default:
return nullptr;
}
}

38 changes: 7 additions & 31 deletions src/auth/AuthSessionHandler.h
Expand Up @@ -27,49 +27,25 @@ class CephContext;
class Message;

struct AuthSessionHandler {
protected:
CephContext *cct;
int protocol;
CryptoKey key; // per mon authentication
std::string connection_secret; // per connection

public:
explicit AuthSessionHandler(CephContext *cct_) : cct(cct_), protocol(CEPH_AUTH_UNKNOWN) {}

AuthSessionHandler(CephContext *cct_, int protocol_,
const CryptoKey& key_,
const std::string& cs_)
: cct(cct_),
protocol(protocol_),
key(key_),
connection_secret(cs_) {}
virtual ~AuthSessionHandler() { }

virtual bool no_security() = 0;
virtual ~AuthSessionHandler() = default;
virtual int sign_message(Message *message) = 0;
virtual int check_message_signature(Message *message) = 0;
virtual int encrypt_message(Message *message) = 0;
virtual int decrypt_message(Message *message) = 0;
};

virtual int sign_bufferlist(bufferlist &in, bufferlist &out) {
return 0;
};
virtual int encrypt_bufferlist(bufferlist &in, bufferlist &out) {
struct DummyAuthSessionHandler : AuthSessionHandler {
int sign_message(Message*) final {
return 0;
}
virtual int decrypt_bufferlist(bufferlist &in, bufferlist &out) {
int check_message_signature(Message*) final {
return 0;
}

int get_protocol() {return protocol;}
CryptoKey get_key() {return key;}

};

struct DecryptionError : public std::exception {};

extern AuthSessionHandler *get_auth_session_handler(
CephContext *cct, int protocol,
const CryptoKey& key,
const std::string& connection_secret,
uint64_t features);

#endif
47 changes: 0 additions & 47 deletions src/auth/cephx/CephxSessionHandler.cc
Expand Up @@ -180,50 +180,3 @@ int CephxSessionHandler::check_message_signature(Message *m)

return 0;
}

int CephxSessionHandler::sign_bufferlist(bufferlist &in, bufferlist &out)
{
char exp_buf[CryptoKey::get_max_outbuf_size(in.length())];

try {
const CryptoKey::in_slice_t sin{in.length(),
reinterpret_cast<const unsigned char *>(in.c_str())};
const CryptoKey::out_slice_t sout{
sizeof(exp_buf),
reinterpret_cast<unsigned char *>(&exp_buf)};
key.encrypt(cct, sin, sout);
}
catch (std::exception &e) {
lderr(cct) << __func__ << " failed to encrypt signature block" << dendl;
return -1;
}


out.append(exp_buf, sizeof(exp_buf));

return 0;
}

int CephxSessionHandler::encrypt_bufferlist(bufferlist &in, bufferlist &out) {
std::string error;
try {
#warning fixme key
key.encrypt(cct, in, out, &error);
} catch (std::exception &e) {
lderr(cct) << __func__ << " failed to encrypt buffer: " << error << dendl;
return -1;
}
return 0;
}

int CephxSessionHandler::decrypt_bufferlist(bufferlist &in, bufferlist &out) {
std::string error;
try {
#warning fixme key
key.decrypt(cct, in, out, &error);
} catch (std::exception &e) {
lderr(cct) << __func__ << " failed to decrypt buffer: " << error << dendl;
return -1;
}
return 0;
}
38 changes: 12 additions & 26 deletions src/auth/cephx/CephxSessionHandler.h
Expand Up @@ -20,39 +20,25 @@ class CephContext;
class Message;

class CephxSessionHandler : public AuthSessionHandler {
CephContext *cct;
int protocol;
CryptoKey key; // per mon authentication
uint64_t features;

int _calc_signature(Message *m, uint64_t *psig);

public:
CephxSessionHandler(CephContext *cct_,
CephxSessionHandler(CephContext *cct,
const CryptoKey& session_key,
const std::string& connection_secret,
uint64_t features)
: AuthSessionHandler(cct_, CEPH_AUTH_CEPHX, session_key, connection_secret),
features(features) {}
~CephxSessionHandler() override {}

bool no_security() override {
return false;
const uint64_t features)
: cct(cct),
protocol(CEPH_AUTH_CEPHX),
key(session_key),
features(features) {
}

int _calc_signature(Message *m, uint64_t *psig);
~CephxSessionHandler() override = default;

int sign_message(Message *m) override;
int check_message_signature(Message *m) override ;

int sign_bufferlist(bufferlist &in, bufferlist &out) override;
int encrypt_bufferlist(bufferlist &in, bufferlist &out) override;
int decrypt_bufferlist(bufferlist &in, bufferlist &out) override;

// Cephx does not currently encrypt messages, so just return 0 if called. PLR

int encrypt_message(Message *m) override {
return 0;
}

int decrypt_message(Message *m) override {
return 0;
}

};

22 changes: 1 addition & 21 deletions src/auth/krb/KrbSessionHandler.hpp
Expand Up @@ -29,27 +29,7 @@

#define dout_subsys ceph_subsys_auth


class CephContext;
class Message;

class KrbSessionHandler : public AuthSessionHandler {

public:
KrbSessionHandler(CephContext* ceph_ctx,
const CryptoKey& session_key,
const std::string& connection_secret) :
AuthSessionHandler(ceph_ctx, CEPH_AUTH_GSS, session_key,
connection_secret) { }
~KrbSessionHandler() override = default;

bool no_security() override { return true; }
int sign_message(Message* msg) override { return 0; }
int check_message_signature(Message* msg) override { return 0; }
int encrypt_message(Message* msg) override { return 0; }
int decrypt_message(Message* msg) override { return 0; }

private:
struct KrbSessionHandler : DummyAuthSessionHandler {
};

#endif //-- KRB_SESSION_HANDLER_HPP
Expand Down
35 changes: 1 addition & 34 deletions src/auth/none/AuthNoneSessionHandler.h
Expand Up @@ -13,40 +13,7 @@
*/

#include "auth/AuthSessionHandler.h"
#include "msg/Message.h"

class CephContext;

class AuthNoneSessionHandler : public AuthSessionHandler {
public:
AuthNoneSessionHandler(CephContext *cct_,
const CryptoKey& session_key,
const std::string& connection_secret)
: AuthSessionHandler(cct_, CEPH_AUTH_NONE, session_key, connection_secret) {}
~AuthNoneSessionHandler() override {}

bool no_security() override {
return true;
}

// The None suite neither signs nor encrypts messages, so these functions just return success.
// Since nothing was signed or encrypted, don't increment the stats. PLR

int sign_message(Message *m) override {
return 0;
}

int check_message_signature(Message *m) override {
return 0;
}

int encrypt_message(Message *m) override {
return 0;
}

int decrypt_message(Message *m) override {
return 0;
}

struct AuthNoneSessionHandler : DummyAuthSessionHandler {
};

38 changes: 1 addition & 37 deletions src/auth/unknown/AuthUnknownSessionHandler.h
Expand Up @@ -13,43 +13,7 @@
*/

#include "auth/AuthSessionHandler.h"
#include "msg/Message.h"

#define dout_subsys ceph_subsys_auth

class CephContext;

class AuthUnknownSessionHandler : public AuthSessionHandler {
public:
AuthUnknownSessionHandler(CephContext *cct_,
const CryptoKey& session_key,
const std::string& connection_secret)
: AuthSessionHandler(cct_, CEPH_AUTH_UNKNOWN,
session_key, connection_secret) {}
~AuthUnknownSessionHandler() override {}

bool no_security() override {
return true;
}

// The Unknown suite neither signs nor encrypts messages, so these functions just return success.
// Since nothing was signed or encrypted, don't increment the stats. PLR

int sign_message(Message *m) override {
return 0;
}

int check_message_signature(Message *m) override {
return 0;
}

int encrypt_message(Message *m) override {
return 0;
}

int decrypt_message(Message *m) override {
return 0;
}

struct AuthUnknownSessionHandler : DummyAuthSessionHandler {
};

10 changes: 10 additions & 0 deletions src/common/ceph_strings.cc
Expand Up @@ -17,6 +17,16 @@ const char *ceph_entity_type_name(int type)
}
}

const char *ceph_con_mode_name(int con_mode)
{
switch (con_mode) {
case CEPH_CON_MODE_UNKNOWN: return "unknown";
case CEPH_CON_MODE_CRC: return "crc";
case CEPH_CON_MODE_SECURE: return "secure";
default: return "???";
}
}

const char *ceph_osd_op_name(int op)
{
switch (op) {
Expand Down
4 changes: 0 additions & 4 deletions src/crimson/net/SocketConnection.cc
Expand Up @@ -710,14 +710,10 @@ SocketConnection::handle_connect_reply(msgr_tag_t tag)
h.backoff = 0ms;
set_features(h.reply.features & h.connect.features);
if (h.authorizer) {
std::string connection_secret; // this is not used here, we just need
// to make get_auth_session_handler
// call happy
session_security.reset(
get_auth_session_handler(nullptr,
h.authorizer->protocol,
h.authorizer->session_key,
connection_secret,
features));
}
h.authorizer.reset();
Expand Down
5 changes: 4 additions & 1 deletion src/include/buffer.h
Expand Up @@ -883,9 +883,12 @@ inline namespace v14_2_0 {
contiguous_filler(char* const pos) : pos(pos) {}

public:
void advance(const unsigned len) {
pos += len;
}
void copy_in(const unsigned len, const char* const src) {
memcpy(pos, src, len);
pos += len;
advance(len);
}
char* c_str() {
return pos;
Expand Down
2 changes: 2 additions & 0 deletions src/include/ceph_fs.h
Expand Up @@ -78,6 +78,8 @@ struct ceph_dir_layout {
#define CEPH_CON_MODE_CRC 0x1
#define CEPH_CON_MODE_SECURE 0x2

extern const char *ceph_con_mode_name(int con_mode);

/* For options with "_", like: GSS_GSS
which means: Mode/Protocol to validate "authentication_authorization",
where:
Expand Down
3 changes: 3 additions & 0 deletions src/include/inline_memory.h
Expand Up @@ -70,7 +70,10 @@ void *maybe_inline_memcpy(void *dest, const void *src, size_t l,

#if defined(__GNUC__) && defined(__x86_64__)

namespace ceph {
typedef unsigned uint128_t __attribute__ ((mode (TI)));
}
using ceph::uint128_t;
rzarzynski marked this conversation as resolved.
Show resolved Hide resolved

static inline bool mem_is_zero(const char *data, size_t len)
__attribute__((always_inline));
Expand Down