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

feat(security): receive mechanisms which are supported by server_negotiation #595

Merged
merged 15 commits into from
Aug 24, 2020
4 changes: 2 additions & 2 deletions include/dsn/tool-api/network.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ class rpc_session : public ref_counter
bool unlink_message_for_send();
virtual void send(uint64_t signature) = 0;
void on_send_completed(uint64_t signature = 0);
void on_failure(bool is_write = false);
void on_success();

protected:
///
Expand Down Expand Up @@ -302,8 +304,6 @@ class rpc_session : public ref_counter
void clear_send_queue(bool resend_msgs);
bool on_disconnected(bool is_write);
bool is_auth_success(message_ex *msg);
void on_failure(bool is_write = false);
void on_success();

protected:
// constant info
Expand Down
94 changes: 89 additions & 5 deletions src/runtime/security/client_negotiation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@
#include "client_negotiation.h"
#include "negotiation_utils.h"

#include <boost/algorithm/string/join.hpp>
#include <dsn/dist/fmt_logging.h>
#include <dsn/tool-api/async_calls.h>
#include <dsn/utility/smart_pointers.h>
#include <dsn/utility/flags.h>

namespace dsn {
namespace security {
DSN_DECLARE_bool(mandatory_auth);
extern const std::set<std::string> supported_mechanisms;

client_negotiation::client_negotiation(rpc_session *session) : negotiation(session)
{
Expand All @@ -36,18 +40,87 @@ void client_negotiation::start()
list_mechanisms();
}

void client_negotiation::handle_response(error_code err, const negotiation_response &&response)
{
// TBD(zlw)
}

void client_negotiation::list_mechanisms()
{
auto request = dsn::make_unique<negotiation_request>();
_status = request->status = negotiation_status::type::SASL_LIST_MECHANISMS;
send(std::move(request));
}

void client_negotiation::handle_response(error_code err, const negotiation_response &&response)
{
if (err != ERR_OK) {
fail_negotiation();
return;
}

// make the negotiation succeed if server doesn't enable auth and the auth is not mandantory
if (negotiation_status::type::SASL_AUTH_DISABLE == response.status && !FLAGS_mandatory_auth) {
ddebug_f("{}: treat negotiation succeed as server doesn't enable it", _name);
succ_negotiation();
return;
}

switch (_status) {
case negotiation_status::type::SASL_LIST_MECHANISMS:
recv_mechanisms(response);
break;
case negotiation_status::type::SASL_SELECT_MECHANISMS:
// TBD(zlw)
break;
case negotiation_status::type::SASL_INITIATE:
case negotiation_status::type::SASL_CHALLENGE_RESP:
// TBD(zlw)
break;
default:
fail_negotiation();
}
}

void client_negotiation::recv_mechanisms(const negotiation_response &resp)
{
if (resp.status != negotiation_status::type::SASL_LIST_MECHANISMS_RESP) {
dwarn_f("{}: get message({}) while expect({})",
_name,
enum_to_string(resp.status),
enum_to_string(negotiation_status::type::SASL_LIST_MECHANISMS_RESP));
fail_negotiation();
return;
}

std::string match_mechanism;
std::vector<std::string> server_support_mechanisms;
std::string resp_string = resp.msg;
utils::split_args(resp_string.c_str(), server_support_mechanisms, ',');

for (const std::string &server_support_mechanism : server_support_mechanisms) {
if (supported_mechanisms.find(server_support_mechanism) != supported_mechanisms.end()) {
match_mechanism = server_support_mechanism;
break;
}
}

if (match_mechanism.empty()) {
dwarn_f("server only support mechanisms of ({}), can't find expected ({})",
resp_string,
boost::join(supported_mechanisms, ","));
fail_negotiation();
return;
}

select_mechanism(match_mechanism);
}

void client_negotiation::select_mechanism(const std::string &mechanism)
{
_selected_mechanism = mechanism;

auto req = dsn::make_unique<negotiation_request>();
_status = req->status = negotiation_status::type::SASL_SELECT_MECHANISMS;
req->msg = mechanism;
send(std::move(req));
}

void client_negotiation::send(std::unique_ptr<negotiation_request> request)
{
negotiation_rpc rpc(std::move(request), RPC_NEGOTIATION);
Expand All @@ -56,5 +129,16 @@ void client_negotiation::send(std::unique_ptr<negotiation_request> request)
});
}

void client_negotiation::fail_negotiation()
{
_status = negotiation_status::type::SASL_AUTH_FAIL;
_session->on_failure(true);
}

void client_negotiation::succ_negotiation()
{
_status = negotiation_status::type::SASL_SUCC;
_session->on_success();
}
} // namespace security
} // namespace dsn
4 changes: 4 additions & 0 deletions src/runtime/security/client_negotiation.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ class client_negotiation : public negotiation
private:
void handle_response(error_code err, const negotiation_response &&response);
void list_mechanisms();
void recv_mechanisms(const negotiation_response &resp);
void select_mechanism(const std::string &mechanism);
void send(std::unique_ptr<negotiation_request> request);
void fail_negotiation();
void succ_negotiation();
};

} // namespace security
Expand Down
2 changes: 2 additions & 0 deletions src/runtime/security/negotiation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ namespace security {
/// TODO(zlw):we can't get string list from cflags now,
/// so we should get supported mechanisms from config in the later
const std::set<std::string> supported_mechanisms{"GSSAPI"};

DSN_DEFINE_bool("security", enable_auth, false, "whether open auth or not");
DSN_DEFINE_bool("security", mandatory_auth, false, "wheter to do authertication mandatorily");

negotiation::~negotiation() {}

Expand Down
1 change: 1 addition & 0 deletions src/runtime/security/negotiation.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class negotiation
rpc_session *_session;
std::string _name;
negotiation_status::type _status;
std::string _selected_mechanism;
};

std::unique_ptr<negotiation> create_negotiation(bool is_client, rpc_session *session);
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/security/negotiation_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ inline const char *enum_to_string(negotiation_status::type s)
return "negotiation_list_mechanisms_resp";
case negotiation_status::type::SASL_SELECT_MECHANISMS:
return "negotiation_select_mechanisms";
case negotiation_status::type::SASL_SELECT_MECHANISMS_OK:
return "negotiation_select_mechanisms_ok";
case negotiation_status::type::SASL_SELECT_MECHANISMS_RESP:
return "negotiation_select_mechanisms_resp";
case negotiation_status::type::SASL_SUCC:
return "negotiation_succ";
case negotiation_status::type::SASL_AUTH_FAIL:
Expand Down
44 changes: 22 additions & 22 deletions src/runtime/security/security.thrift
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,34 @@ namespace cpp dsn.security
// negotiation process:
//
// client server
// | --- SASL_LIST_MECHANISMS --> |
// | <-- SASL_LIST_MECHANISMS_RESP --- |
// | -- SASL_SELECT_MECHANISMS --> |
// | <-- SASL_SELECT_MECHANISMS_OK --- |
// | |
// | --- SASL_INITIATE --> |
// | |
// | <-- SASL_CHALLENGE --- |
// | --- SASL_CHALLENGE_RESP --> |
// | |
// | ..... |
// | |
// | <-- SASL_CHALLENGE --- |
// | --- SASL_CHALLENGE_RESP --> |
// | | (authentication will succeed
// | | if all chanllenges passed)
// | <-- SASL_SUCC --- |
// (client won't response | |
// if servers says ok) | |
// | --- RPC_CALL ---> |
// | <-- RPC_RESP ---- |
// | --- SASL_LIST_MECHANISMS --> |
// | <-- SASL_LIST_MECHANISMS_RESP --- |
// | -- SASL_SELECT_MECHANISMS --> |
// | <-- SASL_SELECT_MECHANISMS_RESP --- |
// | |
// | --- SASL_INITIATE --> |
// | |
// | <-- SASL_CHALLENGE --- |
// | --- SASL_CHALLENGE_RESP --> |
// | |
// | ..... |
// | |
// | <-- SASL_CHALLENGE --- |
// | --- SASL_CHALLENGE_RESP --> |
// | | (authentication will succeed
// | | if all challenges passed)
// | <-- SASL_SUCC --- |
// (client won't response | |
// if servers says ok) | |
// | --- RPC_CALL ---> |
// | <-- RPC_RESP ---- |

enum negotiation_status {
INVALID
SASL_LIST_MECHANISMS
SASL_LIST_MECHANISMS_RESP
SASL_SELECT_MECHANISMS
SASL_SELECT_MECHANISMS_OK
SASL_SELECT_MECHANISMS_RESP
SASL_INITIATE
SASL_CHALLENGE
SASL_CHALLENGE_RESP
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/security/security_types.cpp

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/runtime/security/security_types.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.