mirror of
https://github.com/ceph/ceph
synced 2025-04-22 15:26:10 +00:00
msg/async/ProtocolV1: use AuthServer and AuthClient
Stop using the old ms_* auth methods and instead use the new interfaces (like V2). Signed-off-by: Sage Weil <sage@redhat.com>
This commit is contained in:
parent
6578fd6248
commit
c58c5754df
@ -9,6 +9,8 @@
|
||||
#include "AsyncMessenger.h"
|
||||
#include "common/EventTrace.h"
|
||||
#include "include/random.h"
|
||||
#include "auth/AuthClient.h"
|
||||
#include "auth/AuthServer.h"
|
||||
|
||||
#define dout_subsys ceph_subsys_ms
|
||||
#undef dout_prefix
|
||||
@ -72,7 +74,6 @@ ProtocolV1::ProtocolV1(AsyncConnection *connection)
|
||||
once_ready(false),
|
||||
state(NONE),
|
||||
global_seq(0),
|
||||
authorizer(nullptr),
|
||||
wait_for_seq(false) {
|
||||
temp_buffer = new char[4096];
|
||||
}
|
||||
@ -82,20 +83,12 @@ ProtocolV1::~ProtocolV1() {
|
||||
ceph_assert(sent.empty());
|
||||
|
||||
delete[] temp_buffer;
|
||||
|
||||
if (authorizer) {
|
||||
delete authorizer;
|
||||
}
|
||||
}
|
||||
|
||||
void ProtocolV1::connect() {
|
||||
this->state = START_CONNECT;
|
||||
|
||||
// reset connect state variables
|
||||
if (authorizer) {
|
||||
delete authorizer;
|
||||
authorizer = nullptr;
|
||||
}
|
||||
authorizer_buf.clear();
|
||||
memset(&connect_msg, 0, sizeof(connect_msg));
|
||||
memset(&connect_reply, 0, sizeof(connect_reply));
|
||||
@ -1243,14 +1236,12 @@ void ProtocolV1::discard_out_queue() {
|
||||
out_q.clear();
|
||||
}
|
||||
|
||||
void ProtocolV1::reset_recv_state() {
|
||||
void ProtocolV1::reset_recv_state()
|
||||
{
|
||||
// clean up state internal variables and states
|
||||
if (state == CONNECTING_SEND_CONNECT_MSG) {
|
||||
if (authorizer) {
|
||||
delete authorizer;
|
||||
}
|
||||
authorizer = nullptr;
|
||||
}
|
||||
auth_meta.reset(new AuthConnectionMeta);
|
||||
authorizer_more.clear();
|
||||
session_security.reset();
|
||||
|
||||
// clean read and write callbacks
|
||||
connection->pendingReadLen.reset();
|
||||
@ -1442,13 +1433,37 @@ CtPtr ProtocolV1::handle_my_addr_write(int r) {
|
||||
return CONTINUE(send_connect_message);
|
||||
}
|
||||
|
||||
CtPtr ProtocolV1::send_connect_message() {
|
||||
CtPtr ProtocolV1::send_connect_message()
|
||||
{
|
||||
state = CONNECTING_SEND_CONNECT_MSG;
|
||||
|
||||
ldout(cct, 20) << __func__ << dendl;
|
||||
ceph_assert(messenger->auth_client);
|
||||
|
||||
if (!authorizer) {
|
||||
authorizer = messenger->ms_deliver_get_authorizer(connection->peer_type);
|
||||
bufferlist auth_bl;
|
||||
vector<uint32_t> preferred_modes;
|
||||
|
||||
if (connection->peer_type != CEPH_ENTITY_TYPE_MON) {
|
||||
if (authorizer_more.length()) {
|
||||
ldout(cct,10) << __func__ << " using augmented (challenge) auth payload"
|
||||
<< dendl;
|
||||
auth_bl = authorizer_more;
|
||||
} else {
|
||||
auto am = auth_meta;
|
||||
authorizer_more.clear();
|
||||
connection->lock.unlock();
|
||||
int r = messenger->auth_client->get_auth_request(
|
||||
connection, am.get(),
|
||||
&am->auth_method, &preferred_modes, &auth_bl);
|
||||
connection->lock.lock();
|
||||
if (r < 0) {
|
||||
return _fault();
|
||||
}
|
||||
if (state != CONNECTING_SEND_CONNECT_MSG) {
|
||||
ldout(cct, 1) << __func__ << " state changed!" << dendl;
|
||||
return _fault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ceph_msg_connect connect;
|
||||
@ -1458,13 +1473,15 @@ CtPtr ProtocolV1::send_connect_message() {
|
||||
connect.connect_seq = connect_seq;
|
||||
connect.protocol_version =
|
||||
messenger->get_proto_version(connection->peer_type, true);
|
||||
connect.authorizer_protocol = authorizer ? authorizer->protocol : 0;
|
||||
connect.authorizer_len = authorizer ? authorizer->bl.length() : 0;
|
||||
|
||||
if (authorizer) {
|
||||
if (auth_bl.length()) {
|
||||
ldout(cct, 10) << __func__
|
||||
<< " connect_msg.authorizer_len=" << connect.authorizer_len
|
||||
<< " protocol=" << connect.authorizer_protocol << dendl;
|
||||
<< " connect_msg.authorizer_len=" << auth_bl.length()
|
||||
<< " protocol=" << auth_meta->auth_method << dendl;
|
||||
connect.authorizer_protocol = auth_meta->auth_method;
|
||||
connect.authorizer_len = auth_bl.length();
|
||||
} else {
|
||||
connect.authorizer_protocol = 0;
|
||||
connect.authorizer_len = 0;
|
||||
}
|
||||
|
||||
connect.flags = 0;
|
||||
@ -1475,8 +1492,8 @@ CtPtr ProtocolV1::send_connect_message() {
|
||||
|
||||
bufferlist bl;
|
||||
bl.append((char *)&connect, sizeof(connect));
|
||||
if (authorizer) {
|
||||
bl.append(authorizer->bl.c_str(), authorizer->bl.length());
|
||||
if (auth_bl.length()) {
|
||||
bl.append(auth_bl.c_str(), auth_bl.length());
|
||||
}
|
||||
|
||||
ldout(cct, 10) << __func__ << " connect sending gseq=" << global_seq
|
||||
@ -1557,17 +1574,37 @@ CtPtr ProtocolV1::handle_connect_reply_auth(char *buffer, int r) {
|
||||
bufferlist authorizer_reply;
|
||||
authorizer_reply.append(buffer, connect_reply.authorizer_len);
|
||||
|
||||
if (connect_reply.tag == CEPH_MSGR_TAG_CHALLENGE_AUTHORIZER) {
|
||||
ldout(cct, 10) << __func__ << " connect got auth challenge" << dendl;
|
||||
authorizer->add_challenge(cct, authorizer_reply);
|
||||
return CONTINUE(send_connect_message);
|
||||
}
|
||||
|
||||
auto iter = authorizer_reply.cbegin();
|
||||
if (authorizer && !authorizer->verify_reply(iter,
|
||||
nullptr /* connection_secret */)) {
|
||||
ldout(cct, 0) << __func__ << " failed verifying authorize reply" << dendl;
|
||||
return _fault();
|
||||
if (connection->peer_type != CEPH_ENTITY_TYPE_MON) {
|
||||
auto am = auth_meta;
|
||||
bool more = (connect_reply.tag == CEPH_MSGR_TAG_CHALLENGE_AUTHORIZER);
|
||||
bufferlist auth_retry_bl;
|
||||
int r;
|
||||
connection->lock.unlock();
|
||||
if (more) {
|
||||
r = messenger->auth_client->handle_auth_reply_more(
|
||||
connection, am.get(), authorizer_reply, &auth_retry_bl);
|
||||
} else {
|
||||
// these aren't used for v1
|
||||
CryptoKey skey;
|
||||
string con_secret;
|
||||
r = messenger->auth_client->handle_auth_done(
|
||||
connection, am.get(),
|
||||
0 /* global id */, 0 /* con mode */,
|
||||
authorizer_reply,
|
||||
&skey, &con_secret);
|
||||
}
|
||||
connection->lock.lock();
|
||||
if (state != CONNECTING_SEND_CONNECT_MSG) {
|
||||
ldout(cct, 1) << __func__ << " state changed" << dendl;
|
||||
return _fault();
|
||||
}
|
||||
if (r < 0) {
|
||||
return _fault();
|
||||
}
|
||||
if (more && r == 0) {
|
||||
authorizer_more = auth_retry_bl;
|
||||
return CONTINUE(send_connect_message);
|
||||
}
|
||||
}
|
||||
|
||||
return handle_connect_reply_2();
|
||||
@ -1595,6 +1632,7 @@ CtPtr ProtocolV1::handle_connect_reply_2() {
|
||||
|
||||
if (connect_reply.tag == CEPH_MSGR_TAG_BADAUTHORIZER) {
|
||||
ldout(cct, 0) << __func__ << " connect got BADAUTHORIZER" << dendl;
|
||||
authorizer_more.clear();
|
||||
return _fault();
|
||||
}
|
||||
|
||||
@ -1716,12 +1754,12 @@ CtPtr ProtocolV1::client_ready() {
|
||||
|
||||
// If we have an authorizer, get a new AuthSessionHandler to deal with
|
||||
// ongoing security of the connection. PLR
|
||||
if (authorizer != NULL) {
|
||||
if (auth_meta->authorizer) {
|
||||
ldout(cct, 10) << __func__ << " setting up session_security with auth "
|
||||
<< authorizer << dendl;
|
||||
<< auth_meta->authorizer.get() << dendl;
|
||||
session_security.reset(get_auth_session_handler(
|
||||
cct, authorizer->protocol,
|
||||
authorizer->session_key,
|
||||
cct, auth_meta->authorizer->protocol,
|
||||
auth_meta->session_key,
|
||||
connection->get_features()));
|
||||
} else {
|
||||
// We have no authorizer, so we shouldn't be applying security to messages
|
||||
@ -1943,41 +1981,43 @@ CtPtr ProtocolV1::handle_connect_message_2() {
|
||||
}
|
||||
|
||||
bufferlist auth_bl_copy = authorizer_buf;
|
||||
auto am = auth_meta;
|
||||
am->auth_method = connect_msg.authorizer_protocol;
|
||||
connection->lock.unlock();
|
||||
ldout(cct,10) << __func__ << " authorizor_protocol "
|
||||
<< connect_msg.authorizer_protocol
|
||||
<< " len " << auth_bl_copy.length()
|
||||
<< dendl;
|
||||
bool authorizer_valid;
|
||||
bool need_challenge = HAVE_FEATURE(connect_msg.features, CEPHX_V2);
|
||||
bool had_challenge = (bool)authorizer_challenge;
|
||||
if (!messenger->ms_deliver_verify_authorizer(
|
||||
connection, connection->peer_type, connect_msg.authorizer_protocol,
|
||||
auth_bl_copy, authorizer_reply, authorizer_valid, session_key,
|
||||
nullptr /* connection_secret */,
|
||||
need_challenge ? &authorizer_challenge : nullptr) ||
|
||||
!authorizer_valid) {
|
||||
bool more = (bool)auth_meta->authorizer_challenge;
|
||||
int r = messenger->auth_server->handle_auth_request(
|
||||
connection,
|
||||
am.get(),
|
||||
more,
|
||||
am->auth_method,
|
||||
auth_bl_copy,
|
||||
&authorizer_reply);
|
||||
if (r < 0) {
|
||||
connection->lock.lock();
|
||||
if (state != ACCEPTING_WAIT_CONNECT_MSG_AUTH) {
|
||||
ldout(cct, 1) << __func__
|
||||
<< " state changed while accept, it must be mark_down"
|
||||
<< dendl;
|
||||
ceph_assert(state == CLOSED);
|
||||
ldout(cct, 1) << __func__ << " state changed" << dendl;
|
||||
return _fault();
|
||||
}
|
||||
|
||||
if (need_challenge && !had_challenge && authorizer_challenge) {
|
||||
ldout(cct, 10) << __func__ << ": challenging authorizer" << dendl;
|
||||
ceph_assert(authorizer_reply.length());
|
||||
return send_connect_message_reply(CEPH_MSGR_TAG_CHALLENGE_AUTHORIZER,
|
||||
reply, authorizer_reply);
|
||||
} else {
|
||||
ldout(cct, 0) << __func__ << ": got bad authorizer, auth_reply_len="
|
||||
<< authorizer_reply.length() << dendl;
|
||||
session_security.reset();
|
||||
return send_connect_message_reply(CEPH_MSGR_TAG_BADAUTHORIZER, reply,
|
||||
authorizer_reply);
|
||||
ldout(cct, 0) << __func__ << ": got bad authorizer, auth_reply_len="
|
||||
<< authorizer_reply.length() << dendl;
|
||||
session_security.reset();
|
||||
return send_connect_message_reply(CEPH_MSGR_TAG_BADAUTHORIZER, reply,
|
||||
authorizer_reply);
|
||||
}
|
||||
if (r == 0) {
|
||||
connection->lock.lock();
|
||||
if (state != ACCEPTING_WAIT_CONNECT_MSG_AUTH) {
|
||||
ldout(cct, 1) << __func__ << " state changed" << dendl;
|
||||
return _fault();
|
||||
}
|
||||
ldout(cct, 10) << __func__ << ": challenging authorizer" << dendl;
|
||||
ceph_assert(authorizer_reply.length());
|
||||
return send_connect_message_reply(CEPH_MSGR_TAG_CHALLENGE_AUTHORIZER,
|
||||
reply, authorizer_reply);
|
||||
}
|
||||
|
||||
// We've verified the authorizer for this AsyncConnection, so set up the
|
||||
@ -1991,10 +2031,7 @@ CtPtr ProtocolV1::handle_connect_message_2() {
|
||||
|
||||
connection->lock.lock();
|
||||
if (state != ACCEPTING_WAIT_CONNECT_MSG_AUTH) {
|
||||
ldout(cct, 1) << __func__
|
||||
<< " state changed while accept, it must be mark_down"
|
||||
<< dendl;
|
||||
ceph_assert(state == CLOSED);
|
||||
ldout(cct, 1) << __func__ << " state changed" << dendl;
|
||||
return _fault();
|
||||
}
|
||||
|
||||
@ -2276,8 +2313,6 @@ CtPtr ProtocolV1::replace(const AsyncConnectionRef& existing,
|
||||
// there shouldn't exist any buffer
|
||||
ceph_assert(connection->recv_start == connection->recv_end);
|
||||
|
||||
exproto->authorizer_challenge.reset();
|
||||
|
||||
auto deactivate_existing = std::bind(
|
||||
[existing, new_worker, new_center, exproto, reply,
|
||||
authorizer_reply](ConnectedSocket &cs) mutable {
|
||||
@ -2396,9 +2431,9 @@ CtPtr ProtocolV1::open(ceph_msg_connect_reply &reply,
|
||||
<< connect_msg.authorizer_protocol << dendl;
|
||||
|
||||
session_security.reset(
|
||||
get_auth_session_handler(cct, connect_msg.authorizer_protocol,
|
||||
session_key,
|
||||
connection->get_features()));
|
||||
get_auth_session_handler(cct, auth_meta->auth_method,
|
||||
auth_meta->session_key,
|
||||
connection->get_features()));
|
||||
|
||||
bufferlist reply_bl;
|
||||
reply_bl.append((char *)&reply, sizeof(reply));
|
||||
|
@ -114,14 +114,13 @@ protected:
|
||||
std::atomic<uint64_t> out_seq{0};
|
||||
std::atomic<uint64_t> ack_left{0};
|
||||
|
||||
CryptoKey session_key;
|
||||
std::shared_ptr<AuthSessionHandler> session_security;
|
||||
std::unique_ptr<AuthAuthorizerChallenge> authorizer_challenge; // accept side
|
||||
|
||||
// Open state
|
||||
ceph_msg_connect connect_msg;
|
||||
ceph_msg_connect_reply connect_reply;
|
||||
bufferlist authorizer_buf;
|
||||
bufferlist authorizer_buf; // auth(orizer) payload read off the wire
|
||||
bufferlist authorizer_more; // connect-side auth retry (we added challenge)
|
||||
|
||||
utime_t backoff; // backoff time
|
||||
utime_t recv_stamp;
|
||||
@ -226,7 +225,6 @@ public:
|
||||
// Client Protocol
|
||||
private:
|
||||
int global_seq;
|
||||
AuthAuthorizer *authorizer;
|
||||
|
||||
CONTINUATION_DECL(ProtocolV1, send_client_banner);
|
||||
WRITE_HANDLER_CONTINUATION_DECL(ProtocolV1, handle_client_banner_write);
|
||||
|
Loading…
Reference in New Issue
Block a user