Skip to content
This repository has been archived by the owner on Jun 23, 2022. It is now read-only.

fix(security): fix bug in negotiation_service::on_negotiation_request when rpc_session is closed #652

Merged
merged 18 commits into from
Nov 4, 2020
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/runtime/security/client_negotiation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "client_negotiation.h"
#include "negotiation_utils.h"
#include "negotiation_service.h"

#include <boost/algorithm/string/join.hpp>
#include <dsn/dist/fmt_logging.h>
Expand All @@ -29,7 +30,7 @@ namespace security {
DSN_DECLARE_bool(mandatory_auth);
extern const std::set<std::string> supported_mechanisms;

client_negotiation::client_negotiation(rpc_session *session) : negotiation(session)
client_negotiation::client_negotiation(rpc_session_ptr session) : negotiation(session)
{
_name = fmt::format("CLIENT_NEGOTIATION(SERVER={})", _session->remote_address().to_string());
}
Expand Down Expand Up @@ -179,8 +180,8 @@ void client_negotiation::send(negotiation_status::type status, const blob &msg)
req->msg = msg;

negotiation_rpc rpc(std::move(req), RPC_NEGOTIATION);
rpc.call(_session->remote_address(), nullptr, [this, rpc](error_code err) mutable {
handle_response(err, std::move(rpc.response()));
rpc.call(_session->remote_address(), nullptr, [rpc](error_code err) mutable {
negotiation_service::on_negotiation_response(err, rpc);
});
}

Expand Down
4 changes: 2 additions & 2 deletions src/runtime/security/client_negotiation.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ namespace security {
class client_negotiation : public negotiation
{
public:
client_negotiation(rpc_session *session);
client_negotiation(rpc_session_ptr session);

void start();
void handle_response(error_code err, const negotiation_response &&response);

private:
void handle_response(error_code err, const negotiation_response &&response);
void on_recv_mechanisms(const negotiation_response &resp);
void on_mechanism_selected(const negotiation_response &resp);
void on_challenge(const negotiation_response &resp);
Expand Down
6 changes: 2 additions & 4 deletions src/runtime/security/negotiation.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ typedef rpc_holder<negotiation_request, negotiation_response> negotiation_rpc;
class negotiation
{
public:
negotiation(rpc_session *session)
negotiation(rpc_session_ptr session)
: _session(session), _status(negotiation_status::type::INVALID)
{
_sasl = create_sasl_wrapper(_session->is_client());
Expand All @@ -49,9 +49,7 @@ class negotiation
bool check_status(negotiation_status::type status, negotiation_status::type expected_status);

protected:
// The ownership of the negotiation instance is held by rpc_session.
// So negotiation keeps only a raw pointer.
rpc_session *_session;
rpc_session_ptr _session;
std::string _name;
negotiation_status::type _status;
std::string _selected_mechanism;
Expand Down
30 changes: 26 additions & 4 deletions src/runtime/security/negotiation_service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@
#include "negotiation_service.h"
#include "negotiation_utils.h"
#include "server_negotiation.h"
#include "client_negotiation.h"

#include <dsn/utility/flags.h>
#include <dsn/tool-api/zlocks.h>
#include <dsn/dist/failure_detector/fd.code.definition.h>
#include <dsn/dist/fmt_logging.h>

namespace dsn {
namespace security {
Expand Down Expand Up @@ -52,7 +54,7 @@ void negotiation_service::open_service()
void negotiation_service::on_negotiation_request(negotiation_rpc rpc)
{
dassert(!rpc.dsn_request()->io_session->is_client(),
"only server session receive negotiation request");
"only server session receives negotiation request");

// reply SASL_AUTH_DISABLE if auth is not enable
if (!security::FLAGS_enable_auth) {
Expand All @@ -67,12 +69,32 @@ void negotiation_service::on_negotiation_request(negotiation_rpc rpc)
static_cast<server_negotiation *>(_negotiations[rpc.dsn_request()->io_session].get());
}

dassert(srv_negotiation != nullptr,
"negotiation is null for msg: {}",
rpc.dsn_request()->rpc_code().to_string());
if (nullptr == srv_negotiation) {
derror_f("negotiation is null for msg: {}", rpc.dsn_request()->rpc_code().to_string());
return;
}
srv_negotiation->handle_request(rpc);
}

void negotiation_service::on_negotiation_response(error_code err, negotiation_rpc rpc)
levy5307 marked this conversation as resolved.
Show resolved Hide resolved
{
dassert(rpc.dsn_request()->io_session->is_client(),
"only client session receives negotiation response");

client_negotiation *cli_negotiation = nullptr;
{
utils::auto_read_lock l(_lock);
cli_negotiation =
static_cast<client_negotiation *>(_negotiations[rpc.dsn_request()->io_session].get());
}

if (nullptr == cli_negotiation) {
derror_f("negotiation is null for msg: {}", rpc.dsn_request()->rpc_code().to_string());
return;
}
cli_negotiation->handle_response(err, std::move(rpc.response()));
}

void negotiation_service::on_rpc_connected(rpc_session *session)
{
std::unique_ptr<negotiation> nego = security::create_negotiation(session->is_client(), session);
Expand Down
1 change: 1 addition & 0 deletions src/runtime/security/negotiation_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class negotiation_service : public serverlet<negotiation_service>,
static void on_rpc_disconnected(rpc_session *session);
static bool on_rpc_recv_msg(message_ex *msg);
static bool on_rpc_send_msg(message_ex *msg);
static void on_negotiation_response(error_code err, negotiation_rpc rpc);

void open_service();

Expand Down
2 changes: 1 addition & 1 deletion src/runtime/security/server_negotiation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ namespace security {
DSN_DECLARE_string(service_fqdn);
DSN_DECLARE_string(service_name);

server_negotiation::server_negotiation(rpc_session *session) : negotiation(session)
server_negotiation::server_negotiation(rpc_session_ptr session) : negotiation(session)
{
_name = fmt::format("SERVER_NEGOTIATION(CLIENT={})", _session->remote_address().to_string());
}
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/security/server_negotiation.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ extern const std::set<std::string> supported_mechanisms;
class server_negotiation : public negotiation
{
public:
server_negotiation(rpc_session *session);
server_negotiation(rpc_session_ptr session);

void start();
void handle_request(negotiation_rpc rpc);
Expand Down