* TAG_AUTH_REQUEST: client->server::
__le32 method; // CEPH_AUTH_{NONE, CEPHX, ...}
+ __le32 num_preferred_modes;
+ list<__le32> mode // CEPH_CON_MODE_*
method specific payload
* TAG_AUTH_BAD_METHOD server -> client: reject client-selected auth method::
__le32 method
__le32 negative error result code
__le32 num_methods
- __le32 allowed_methods[num_methods] // CEPH_AUTH_{NONE, CEPHX, ...}
+ list<__le32> allowed_methods // CEPH_AUTH_{NONE, CEPHX, ...}
+ __le32 num_modes
+ list<__le32> allowed_modes // CEPH_CON_MODE_*
- Returns the attempted auth method, and error code (-EOPNOTSUPP if
the method is unsupported), and the list of allowed authentication
* TAG_AUTH_DONE: (server->client)::
__le64 global_id
+ __le32 connection mode // CEPH_CON_MODE_*
method specific payload
- - The server is the one to decide authentication has completed.
+ - The server is the one to decide authentication has completed and what
+ the final connection mode will be.
Example of authentication phase interaction when the client uses an
int auth_mode = 0; ///< AUTH_MODE_*
- enum {
- CON_MODE_INTEGRITY, // crc: protect against bit errors
- CON_MODE_AUTHENTICITY, // secure hash: protect against MITM
- CON_MODE_SECRECY, // encrypted
- };
- int con_mode = CON_MODE_INTEGRITY;
-
- bool is_integrity_mode() {
- return con_mode == CON_MODE_INTEGRITY;
- }
- bool is_authenticity_mode() {
- return con_mode == CON_MODE_AUTHENTICITY;
+ /// server: client's preferred con_modes
+ std::vector<uint32_t> preferred_con_modes;
+
+ int con_mode = 0; ///< negotiated mode
+
+ bool is_mode_crc() {
+ return con_mode == CEPH_CON_MODE_CRC;
}
- bool is_secrecy_mode() {
- return con_mode == CON_MODE_SECRECY;
+ bool is_mode_secure() {
+ return con_mode == CEPH_CON_MODE_SECURE;
}
CryptoKey session_key; ///< per-ticket key
virtual int get_auth_request(
Connection *con,
- uint32_t *method, bufferlist *out) = 0;
+ uint32_t *method,
+ std::vector<uint32_t> *preferred_modes,
+ bufferlist *out) = 0;
virtual int handle_auth_reply_more(
Connection *con,
const bufferlist& bl,
virtual int handle_auth_done(
Connection *con,
uint64_t global_id,
+ uint32_t con_mode,
const bufferlist& bl,
CryptoKey *session_key,
CryptoKey *connection_key) = 0;
Connection *con,
uint32_t old_auth_method,
int result,
- const std::vector<uint32_t>& allowed_methods) = 0;
+ const std::vector<uint32_t>& allowed_methods,
+ const std::vector<uint32_t>& allowed_modes) = 0;
};
ldout(cct,20) << __func__ << " " << s << " -> " << *v << dendl;
}
+void AuthRegistry::_parse_mode_list(const string& s,
+ std::vector<uint32_t> *v)
+{
+ std::list<std::string> sup_list;
+ get_str_list(s, sup_list);
+ if (sup_list.empty()) {
+ lderr(cct) << "WARNING: empty auth protocol list" << dendl;
+ }
+ for (auto& i : sup_list) {
+ ldout(cct, 5) << "adding con mode: " << i << dendl;
+ if (i == "crc") {
+ v->push_back(CEPH_CON_MODE_CRC);
+ } else if (i == "secure") {
+ v->push_back(CEPH_CON_MODE_SECURE);
+ } else {
+ v->push_back(CEPH_CON_MODE_UNKNOWN);
+ lderr(cct) << "WARNING: unknown connection mode " << i << dendl;
+ }
+ }
+ if (v->empty()) {
+ lderr(cct) << "WARNING: no connection modes defined, use 'crc' by default"
+ << dendl;
+ v->push_back(CEPH_CON_MODE_CRC);
+ }
+ ldout(cct,20) << __func__ << " " << s << " -> " << *v << dendl;
+}
+
void AuthRegistry::_refresh_config()
{
if (cct->_conf->auth_supported.size()) {
_parse_method_list(cct->_conf->auth_service_required, &service_methods);
_parse_method_list(cct->_conf->auth_client_required, &client_methods);
}
+ _parse_mode_list(cct->_conf.get_val<string>("ms_mon_cluster_mode"),
+ &mon_cluster_modes);
+ _parse_mode_list(cct->_conf.get_val<string>("ms_mon_service_mode"),
+ &mon_service_modes);
+ _parse_mode_list(cct->_conf.get_val<string>("ms_cluster_mode"),
+ &cluster_modes);
+ _parse_mode_list(cct->_conf.get_val<string>("ms_service_mode"),
+ &service_modes);
+ _parse_mode_list(cct->_conf.get_val<string>("ms_client_mode"),
+ &client_modes);
ldout(cct,10) << __func__ << " cluster_methods " << cluster_methods
<< " service_methods " << service_methods
}
}
-void AuthRegistry::get_supported_methods(int peer_type,
- std::vector<uint32_t> *v)
+void AuthRegistry::get_supported_methods(
+ int peer_type,
+ std::vector<uint32_t> *methods,
+ std::vector<uint32_t> *modes)
{
- if (cct->get_module_type() == CEPH_ENTITY_TYPE_CLIENT) {
- *v = client_methods;
+ switch (cct->get_module_type()) {
+ case CEPH_ENTITY_TYPE_CLIENT:
+ // i am client
+ if (methods) {
+ *methods = client_methods;
+ }
+ if (modes) {
+ *modes = client_modes;
+ }
return;
- }
- switch (peer_type) {
case CEPH_ENTITY_TYPE_MON:
- case CEPH_ENTITY_TYPE_MGR:
- case CEPH_ENTITY_TYPE_MDS:
- case CEPH_ENTITY_TYPE_OSD:
- *v = cluster_methods;
- break;
+ // i am mon
+ switch (peer_type) {
+ case CEPH_ENTITY_TYPE_MON:
+ // they are mon
+ if (methods) {
+ *methods = cluster_methods;
+ }
+ if (modes) {
+ *modes = mon_cluster_modes;
+ }
+ break;
+ default:
+ // they are anything but mons
+ if (methods) {
+ *methods = service_methods;
+ }
+ if (modes) {
+ *modes = mon_service_modes;
+ }
+ }
+ return;
default:
- *v = service_methods;
- break;
+ // i am a non-mon daemon
+ switch (peer_type) {
+ case CEPH_ENTITY_TYPE_MON:
+ case CEPH_ENTITY_TYPE_MGR:
+ case CEPH_ENTITY_TYPE_MDS:
+ case CEPH_ENTITY_TYPE_OSD:
+ // they are another daemon
+ if (methods) {
+ *methods = cluster_methods;
+ }
+ if (modes) {
+ *modes = cluster_modes;
+ }
+ break;
+ default:
+ // they are a client
+ if (methods) {
+ *methods = service_methods;
+ }
+ if (modes) {
+ *modes = service_modes;
+ }
+ break;
+ }
}
}
return !s.empty();
}
+void AuthRegistry::get_supported_modes(
+ int peer_type,
+ uint32_t auth_method,
+ std::vector<uint32_t> *modes)
+{
+ std::vector<uint32_t> s;
+ get_supported_methods(peer_type, nullptr, &s);
+ if (auth_method == CEPH_AUTH_NONE) {
+ // filter out all but crc for AUTH_NONE
+ for (auto mode : s) {
+ if (mode == CEPH_CON_MODE_CRC) {
+ modes->push_back(mode);
+ }
+ }
+ } else {
+ *modes = s;
+ }
+}
+
AuthAuthorizeHandler *AuthRegistry::get_handler(int peer_type, int method)
{
std::scoped_lock l{lock};
bool _no_keyring_disabled_cephx = false;
- std::vector<uint32_t> cluster_methods; // CEPH_AUTH_*
- std::vector<uint32_t> service_methods; // CEPH_AUTH_*
- std::vector<uint32_t> client_methods; // CEPH_AUTH_*
+ // CEPH_AUTH_*
+ std::vector<uint32_t> cluster_methods;
+ std::vector<uint32_t> service_methods;
+ std::vector<uint32_t> client_methods;
+
+ // CEPH_CON_MODE_*
+ std::vector<uint32_t> mon_cluster_modes;
+ std::vector<uint32_t> mon_service_modes;
+ std::vector<uint32_t> cluster_modes;
+ std::vector<uint32_t> service_modes;
+ std::vector<uint32_t> client_modes;
void _parse_method_list(const string& str, std::vector<uint32_t> *v);
+ void _parse_mode_list(const string& str, std::vector<uint32_t> *v);
void _refresh_config();
public:
_refresh_config();
}
- void get_supported_methods(int peer_type, std::vector<uint32_t> *v);
+ void get_supported_methods(int peer_type,
+ std::vector<uint32_t> *methods,
+ std::vector<uint32_t> *modes=nullptr);
bool is_supported_method(int peer_type, int method);
bool any_supported_methods(int peer_type);
+ void get_supported_modes(int peer_type,
+ uint32_t auth_method,
+ std::vector<uint32_t> *modes);
+
AuthAuthorizeHandler *get_handler(int peer_type, int method);
const char** get_tracked_conf_keys() const override;
virtual void get_supported_auth_methods(
int peer_type,
- std::vector<uint32_t> *methods) {
- auth_registry.get_supported_methods(peer_type, methods);
+ std::vector<uint32_t> *methods,
+ std::vector<uint32_t> *modes = nullptr) {
+ auth_registry.get_supported_methods(peer_type, methods, modes);
+ }
+ virtual void get_supported_con_modes(
+ int peer_type,
+ uint32_t auth_method,
+ std::vector<uint32_t> *modes) {
+ auth_registry.get_supported_modes(peer_type, auth_method, modes);
}
AuthAuthorizeHandler *get_auth_authorize_handler(
.set_long_description("If not specified, use ms_type")
.add_see_also("ms_type"),
+ Option("ms_mon_cluster_mode", Option::TYPE_STR, Option::LEVEL_BASIC)
+ .set_default("crc secure")
+ .set_description("Connection modes (crc, secure) for intra-mon connections in order of preference")
+ .add_see_also("ms_mon_service_mode")
+ .add_see_also("ms_service_mode")
+ .add_see_also("ms_cluster_mode")
+ .add_see_also("ms_client_mode"),
+
+ Option("ms_mon_service_mode", Option::TYPE_STR, Option::LEVEL_BASIC)
+ .set_default("crc secure")
+ .set_description("Connection modes (crc, secure) for connections to mons in order of preference")
+ .add_see_also("ms_service_mode")
+ .add_see_also("ms_mon_cluster_mode")
+ .add_see_also("ms_cluster_mode")
+ .add_see_also("ms_client_mode"),
+
+ Option("ms_cluster_mode", Option::TYPE_STR, Option::LEVEL_BASIC)
+ .set_default("crc secure")
+ .set_description("Connection modes (crc, secure) for intra-cluster connections in order of preference")
+ .add_see_also("ms_service_mode")
+ .add_see_also("ms_client_mode"),
+
+ Option("ms_service_mode", Option::TYPE_STR, Option::LEVEL_BASIC)
+ .set_default("crc secure")
+ .set_description("Connection modes (crc, secure) for connections to daemons in order of preference")
+ .add_see_also("ms_cluster_mode")
+ .add_see_also("ms_client_mode"),
+
+ Option("ms_client_mode", Option::TYPE_STR, Option::LEVEL_BASIC)
+ .set_default("crc secure")
+ .set_description("Connection modes (crc, secure) for connections from clients in order of preference")
+ .add_see_also("ms_cluster_mode")
+ .add_see_also("ms_service_mode"),
+
Option("ms_tcp_nodelay", Option::TYPE_BOOL, Option::LEVEL_ADVANCED)
.set_default(true)
.set_description("Disable Nagle's algorithm and send queued network traffic immediately"),
#define CEPH_AUTH_NONE 0x1
#define CEPH_AUTH_CEPHX 0x2
+/* msgr2 protocol modes */
+#define CEPH_CON_MODE_UNKNOWN 0x0
+#define CEPH_CON_MODE_CRC 0x1
+#define CEPH_CON_MODE_SECURE 0x2
+
/* For options with "_", like: GSS_GSS
which means: Mode/Protocol to validate "authentication_authorization",
where:
int MonClient::get_auth_request(
Connection *con,
uint32_t *auth_method,
+ std::vector<uint32_t> *preferred_modes,
bufferlist *bl)
{
std::lock_guard l(monc_lock);
for (auto& i : pending_cons) {
if (i.second.is_con(con)) {
return i.second.get_auth_request(
- auth_method, bl,
+ auth_method, preferred_modes, bl,
entity_name, want_keys, rotating_secrets.get());
}
}
}
auth_meta->authorizer.reset(auth->build_authorizer(con->get_peer_type()));
auth_meta->auth_method = auth_meta->authorizer->protocol;
+ auth_registry.get_supported_modes(con->get_peer_type(),
+ auth_meta->auth_method,
+ preferred_modes);
*bl = auth_meta->authorizer->bl;
return 0;
}
int MonClient::handle_auth_done(
Connection *con,
uint64_t global_id,
+ uint32_t con_mode,
const bufferlist& bl,
CryptoKey *session_key,
CryptoKey *connection_key)
Connection *con,
uint32_t old_auth_method,
int result,
- const std::vector<uint32_t>& allowed_methods)
+ const std::vector<uint32_t>& allowed_methods,
+ const std::vector<uint32_t>& allowed_modes)
{
con->get_auth_meta()->allowed_methods = allowed_methods;
if (i.second.is_con(con)) {
int r = i.second.handle_auth_bad_method(old_auth_method,
result,
- allowed_methods);
+ allowed_methods,
+ allowed_modes);
if (r == 0) {
return r; // try another method on this con
}
}
int MonConnection::get_auth_request(
- uint32_t *method, bufferlist *bl,
+ uint32_t *method,
+ std::vector<uint32_t> *preferred_modes,
+ bufferlist *bl,
const EntityName& entity_name,
uint32_t want_keys,
RotatingKeyRing* keyring)
auth_method = as.front();
}
*method = auth_method;
- ldout(cct,10) << __func__ << " method " << *method << dendl;
+ auth_registry->get_supported_modes(con->get_peer_type(), auth_method,
+ preferred_modes);
+ ldout(cct,10) << __func__ << " method " << *method
+ << " preferred_modes " << *preferred_modes << dendl;
if (auth) {
auth.reset();
int MonConnection::handle_auth_bad_method(
uint32_t old_auth_method,
int result,
- const std::vector<uint32_t>& allowed_methods)
+ const std::vector<uint32_t>& allowed_methods,
+ const std::vector<uint32_t>& allowed_modes)
{
ldout(cct,10) << __func__ << " old_auth_method " << old_auth_method
<< " result " << cpp_strerror(result)
}
int get_auth_request(
- uint32_t *method, bufferlist *out,
+ uint32_t *method,
+ std::vector<uint32_t> *preferred_modes,
+ bufferlist *out,
const EntityName& entity_name,
uint32_t want_keys,
RotatingKeyRing* keyring);
int handle_auth_bad_method(
uint32_t old_auth_method,
int result,
- const std::vector<uint32_t>& allowed_methods);
+ const std::vector<uint32_t>& allowed_methods,
+ const std::vector<uint32_t>& allowed_modes);
bool is_con(Connection *c) const {
return con.get() == c;
int get_auth_request(
Connection *con,
uint32_t *method,
+ std::vector<uint32_t> *preferred_modes,
bufferlist *bl) override;
int handle_auth_reply_more(
Connection *con,
int handle_auth_done(
Connection *con,
uint64_t global_id,
+ uint32_t con_mode,
const bufferlist& bl,
CryptoKey *session_key,
CryptoKey *connection_key) override;
Connection *con,
uint32_t old_auth_method,
int result,
- const std::vector<uint32_t>& allowed_methods) override;
+ const std::vector<uint32_t>& allowed_methods,
+ const std::vector<uint32_t>& allowed_modes) override;
// AuthServer
int handle_auth_request(
Connection *con,
// AuthClient methods -- for mon <-> mon communication
int Monitor::get_auth_request(
Connection *con,
- uint32_t *method, bufferlist *out)
+ uint32_t *method,
+ vector<uint32_t> *preferred_modes,
+ bufferlist *out)
{
AuthAuthorizer *auth;
if (!ms_get_authorizer(con->get_peer_type(), &auth)) {
return -EACCES;
}
+ if (con->get_peer_type() != CEPH_ENTITY_TYPE_MON) {
+ return -EACCES;
+ }
auto auth_meta = con->get_auth_meta();
auth_meta->authorizer.reset(auth);
*method = auth->protocol;
+ auth_registry.get_supported_modes(CEPH_ENTITY_TYPE_MON, auth->protocol,
+ preferred_modes);
*out = auth->bl;
return 0;
}
int Monitor::handle_auth_done(
Connection *con,
uint64_t global_id,
+ uint32_t con_mode,
const bufferlist& bl,
CryptoKey *session_key,
CryptoKey *connection_key)
Connection *con,
uint32_t old_auth_method,
int result,
- const std::vector<uint32_t>& allowed_methods)
+ const std::vector<uint32_t>& allowed_methods,
+ const std::vector<uint32_t>& allowed_modes)
{
derr << __func__ << " hmm, they didn't like " << old_auth_method
<< " result " << cpp_strerror(result) << dendl;
// AuthClient
int get_auth_request(
Connection *con,
- uint32_t *method, bufferlist *out) override;
+ uint32_t *method,
+ vector<uint32_t> *preferred_modes,
+ bufferlist *out) override;
int handle_auth_reply_more(
Connection *con,
const bufferlist& bl,
int handle_auth_done(
Connection *con,
uint64_t global_id,
+ uint32_t con_mode,
const bufferlist& bl,
CryptoKey *session_key,
CryptoKey *connection_key) override;
Connection *con,
uint32_t old_auth_method,
int result,
- const std::vector<uint32_t>& allowed_methods) override;
+ const std::vector<uint32_t>& allowed_methods,
+ const std::vector<uint32_t>& allowed_modes) override;
// /AuthClient
// AuthServer
int handle_auth_request(
};
struct AuthRequestFrame
- : public PayloadFrame<AuthRequestFrame, uint32_t, bufferlist> {
+ : public PayloadFrame<AuthRequestFrame,
+ uint32_t, vector<uint32_t>, bufferlist> {
const ProtocolV2::Tag tag = ProtocolV2::Tag::AUTH_REQUEST;
using PayloadFrame::PayloadFrame;
- AuthRequestFrame(uint32_t method) : AuthRequestFrame(method, bufferlist()) {}
-
inline uint32_t &method() { return get_val<0>(); }
- inline bufferlist &auth_payload() { return get_val<1>(); }
+ inline vector<uint32_t> &preferred_modes() { return get_val<1>(); }
+ inline bufferlist &auth_payload() { return get_val<2>(); }
};
struct AuthBadMethodFrame
: public PayloadFrame<AuthBadMethodFrame,
- uint32_t, int32_t, std::vector<uint32_t>> {
+ uint32_t, // method
+ int32_t, // result
+ std::vector<uint32_t>, // allowed_methods
+ std::vector<uint32_t>> { // allowed_modes
const ProtocolV2::Tag tag = ProtocolV2::Tag::AUTH_BAD_METHOD;
using PayloadFrame::PayloadFrame;
inline uint32_t &method() { return get_val<0>(); }
inline int32_t &result() { return get_val<1>(); }
inline std::vector<uint32_t> &allowed_methods() { return get_val<2>(); }
+ inline std::vector<uint32_t> &allowed_modes() { return get_val<3>(); }
};
struct AuthReplyMoreFrame
};
struct AuthDoneFrame
- : public PayloadFrame<AuthDoneFrame, uint64_t, bufferlist> {
+ : public PayloadFrame<AuthDoneFrame,
+ uint64_t, // global_id
+ uint32_t, // con_mode
+ bufferlist> { // auth method payload
const ProtocolV2::Tag tag = ProtocolV2::Tag::AUTH_DONE;
using PayloadFrame::PayloadFrame;
inline uint64_t &global_id() { return get_val<0>(); }
- inline bufferlist &auth_payload() { return get_val<1>(); }
+ inline uint32_t &con_mode() { return get_val<1>(); }
+ inline bufferlist &auth_payload() { return get_val<2>(); }
};
template <class T, typename... Args>
void ProtocolV2::sign_payload(bufferlist &payload) {
ldout(cct, 21) << __func__ << " len=" << payload.length() << dendl;
- if (auth_meta.is_authenticity_mode() && session_security) {
+ if (false && session_security) {
uint32_t pad_len;
calculate_payload_size(payload.length(), nullptr, &pad_len);
auto padding = bufferptr(buffer::create(pad_len));
void ProtocolV2::verify_signature(char *payload, uint32_t length) {
ldout(cct, 21) << __func__ << " len=" << length << dendl;
- if (auth_meta.is_authenticity_mode() && session_security) {
+ if (false && session_security) {
uint32_t payload_len = length - CEPH_CRYPTO_HMACSHA256_DIGESTSIZE;
const char *p = payload + payload_len;
char signature[CEPH_CRYPTO_HMACSHA256_DIGESTSIZE];
void ProtocolV2::encrypt_payload(bufferlist &payload) {
ldout(cct, 21) << __func__ << " len=" << payload.length() << dendl;
- if (auth_meta.is_secrecy_mode() && session_security) {
+ if (auth_meta.is_mode_secure()) {
uint32_t pad_len;
calculate_payload_size(payload.length(), nullptr, nullptr, &pad_len);
if (pad_len) {
void ProtocolV2::decrypt_payload(char *payload, uint32_t &length) {
ldout(cct, 21) << __func__ << " len=" << length << dendl;
- if (auth_meta.is_secrecy_mode() && session_security) {
+ if (auth_meta.is_mode_secure() && session_security) {
bufferlist in;
in.push_back(buffer::create_static(length, payload));
bufferlist out;
void ProtocolV2::calculate_payload_size(uint32_t length, uint32_t *total_len,
uint32_t *sig_pad_len,
uint32_t *enc_pad_len) {
- bool is_signed = auth_meta.is_authenticity_mode();
- bool is_encrypted = auth_meta.is_secrecy_mode();
+ bool is_signed = auth_meta.is_mode_secure(); // REMOVE ME
+ bool is_encrypted = auth_meta.is_mode_secure();
uint32_t sig_pad_l = 0;
uint32_t enc_pad_l = 0;
// the message payload
ldout(cct, 1) << __func__ << " reading message payload extra bytes left="
<< next_payload_len << dendl;
- ceph_assert(session_security && (auth_meta.is_authenticity_mode() ||
- auth_meta.is_secrecy_mode()));
+ ceph_assert(session_security && (auth_meta.is_mode_secure()));
extra.push_back(buffer::create(next_payload_len));
return READB(next_payload_len, extra.c_str(), handle_message_extra_bytes);
}
ceph_msg_footer footer{current_header.front_crc, current_header.middle_crc,
current_header.data_crc, 0, current_header.flags};
- if (auth_meta.is_authenticity_mode() || auth_meta.is_secrecy_mode()) {
+ if (auth_meta.is_mode_secure()) {
bufferlist msg_payload;
msg_payload.claim_append(front);
msg_payload.claim_append(middle);
ceph_assert(messenger->auth_client);
bufferlist bl;
+ vector<uint32_t> preferred_modes;
connection->lock.unlock();
int r = messenger->auth_client->get_auth_request(
- connection, &auth_meta.auth_method, &bl);
+ connection, &auth_meta.auth_method, &preferred_modes, &bl);
connection->lock.lock();
if (state != State::CONNECTING) {
return _fault();
connection->dispatch_queue->queue_reset(connection);
return nullptr;
}
- AuthRequestFrame frame(auth_meta.auth_method, bl);
+ AuthRequestFrame frame(auth_meta.auth_method, preferred_modes, bl);
return WRITE(frame.get_buffer(), "auth request", read_frame);
}
ldout(cct, 1) << __func__ << " method=" << bad_method.method()
<< " result " << cpp_strerror(bad_method.result())
<< ", allowed methods=" << bad_method.allowed_methods()
+ << ", allowed modes=" << bad_method.allowed_modes()
<< dendl;
ceph_assert(messenger->auth_client);
connection->lock.unlock();
int r = messenger->auth_client->handle_auth_bad_method(
connection, bad_method.method(), bad_method.result(),
- bad_method.allowed_methods());
+ bad_method.allowed_methods(),
+ bad_method.allowed_modes());
connection->lock.lock();
if (state != State::CONNECTING || r < 0) {
return _fault();
int r = messenger->auth_client->handle_auth_done(
connection,
auth_done.global_id(),
+ auth_done.con_mode(),
auth_done.auth_payload(),
&auth_meta.session_key,
&auth_meta.connection_secret);
}
CtPtr ProtocolV2::handle_auth_request(char *payload, uint32_t length) {
- AuthRequestFrame auth_request(payload, length);
- ldout(cct, 10) << __func__ << " AuthRequest(method=" << auth_request.method()
- << ", auth_len=" << auth_request.auth_payload().length() << ")"
+ AuthRequestFrame request(payload, length);
+ ldout(cct, 10) << __func__ << " AuthRequest(method=" << request.method()
+ << ", preferred_modes=" << request.preferred_modes()
+ << ", payload_len=" << request.auth_payload().length() << ")"
<< dendl;
- auth_meta.auth_method = auth_request.method();
- return _handle_auth_request(auth_request.auth_payload(), false);
+ auth_meta.auth_method = request.method();
+ auth_meta.preferred_con_modes = request.preferred_modes();
+ return _handle_auth_request(request.auth_payload(), false);
+}
+
+CtPtr ProtocolV2::_auth_bad_method(int r)
+{
+ ceph_assert(r < 0);
+ std::vector<uint32_t> allowed_methods;
+ std::vector<uint32_t> allowed_modes;
+ messenger->auth_server->get_supported_auth_methods(
+ connection->get_peer_type(), &allowed_methods, &allowed_modes);
+ ldout(cct, 1) << __func__ << " auth_method " << auth_meta.auth_method
+ << " r " << cpp_strerror(r)
+ << ", allowed_methods " << allowed_methods
+ << ", allowed_modes " << allowed_modes
+ << dendl;
+ AuthBadMethodFrame bad_method(auth_meta.auth_method, r, allowed_methods,
+ allowed_modes);
+ return WRITE(bad_method.get_buffer(), "bad auth method", read_frame);
}
CtPtr ProtocolV2::_handle_auth_request(bufferlist& auth_payload, bool more)
return _fault();
}
if (r == 1) {
- AuthDoneFrame auth_done(connection->peer_global_id, reply);
- return WRITE(auth_done.get_buffer(), "auth done", read_frame);
+ // select a connection mode
+ std::vector<uint32_t> allowed_modes;
+ messenger->auth_server->get_supported_con_modes(
+ connection->get_peer_type(), auth_meta.auth_method, &allowed_modes);
+ for (auto mode : allowed_modes) {
+ if (std::find(auth_meta.preferred_con_modes.begin(),
+ auth_meta.preferred_con_modes.end(),
+ mode) != auth_meta.preferred_con_modes.end()) {
+ auth_meta.con_mode = mode;
+ break;
+ }
+ }
+ if (auth_meta.con_mode == 0) {
+ ldout(cct, 1) << __func__ << " failed to select connection mode, i allow "
+ << allowed_modes
+ << ", client prefers " << auth_meta.preferred_con_modes
+ << dendl;
+ return _auth_bad_method(-EOPNOTSUPP);
+ } else {
+ AuthDoneFrame auth_done(connection->peer_global_id, auth_meta.con_mode,
+ reply);
+ return WRITE(auth_done.get_buffer(), "auth done", read_frame);
+ }
} else if (r == 0) {
AuthReplyMoreFrame more(reply);
return WRITE(more.get_buffer(), "auth reply more", read_frame);
// kick the client and maybe they'll come back later
return _fault();
} else {
- ceph_assert(r < 0);
- std::vector<uint32_t> allowed_methods;
- messenger->auth_server->get_supported_auth_methods(
- connection->get_peer_type(), &allowed_methods);
- ldout(cct, 1) << __func__ << " auth_method " << auth_meta.auth_method
- << " r " << cpp_strerror(r)
- << ", allowed_methods " << allowed_methods
- << dendl;
- AuthBadMethodFrame bad_method(auth_meta.auth_method, r, allowed_methods);
- return WRITE(bad_method.get_buffer(), "bad auth method", read_frame);
+ return _auth_bad_method(r);
}
}
Ct<ProtocolV2> *handle_auth_request(char *payload, uint32_t length);
Ct<ProtocolV2> *handle_auth_request_more(char *payload, uint32_t length);
Ct<ProtocolV2> *_handle_auth_request(bufferlist& auth_payload, bool more);
+ Ct<ProtocolV2> *_auth_bad_method(int r);
Ct<ProtocolV2> *handle_client_ident(char *payload, uint32_t length);
Ct<ProtocolV2> *handle_ident_missing_features_write(int r);
Ct<ProtocolV2> *handle_reconnect(char *payload, uint32_t length);