From fa5671c0173daba4b622a34f818f1d8b6e39e305 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Wed, 21 Oct 2009 16:49:28 -0700 Subject: [PATCH] auth: authorize keeps state --- src/auth/Auth.cc | 34 ++++++++++++++++++++++---------- src/auth/Auth.h | 17 ++++++++++++++-- src/auth/AuthClientHandler.cc | 30 +++++++++++----------------- src/auth/AuthClientHandler.h | 4 ++-- src/librados.cc | 2 +- src/mds/MDS.cc | 2 +- src/mds/MDS.h | 2 +- src/mon/Monitor.cc | 5 ++--- src/mon/Monitor.h | 2 +- src/msg/Dispatcher.h | 3 ++- src/msg/Messenger.h | 2 +- src/msg/SimpleMessenger.cc | 37 ++++++++++++++++++++++++++--------- src/msg/SimpleMessenger.h | 2 +- src/osd/OSD.cc | 6 +----- src/osd/OSD.h | 2 +- 15 files changed, 92 insertions(+), 58 deletions(-) diff --git a/src/auth/Auth.cc b/src/auth/Auth.cc index dd270fb0e2250..75d013ac1f703 100644 --- a/src/auth/Auth.cc +++ b/src/auth/Auth.cc @@ -168,19 +168,20 @@ bool AuthTicketsManager::verify_service_ticket_reply(CryptoKey& secret, * * ticket, {timestamp}^session_key */ -bool AuthTicketHandler::build_authorizer(bufferlist& bl, AuthContext& ctx) +bool AuthTicketHandler::build_authorizer(AuthAuthorizer& authorizer) { - ctx.timestamp = g_clock.now(); + authorizer.session_key = session_key; + authorizer.ctx.timestamp = g_clock.now(); dout(0) << "build_authorizer: service_id=" << service_id << dendl; - ::encode(service_id, bl); + ::encode(service_id, authorizer.bl); - ::encode(ticket, bl); + ::encode(ticket, authorizer.bl); AuthAuthorize msg; - msg.now = ctx.timestamp; - if (encode_encrypt(msg, session_key, bl) < 0) + msg.now = authorizer.ctx.timestamp; + if (encode_encrypt(msg, session_key, authorizer.bl) < 0) return false; return true; @@ -191,14 +192,14 @@ bool AuthTicketHandler::build_authorizer(bufferlist& bl, AuthContext& ctx) * * ticket, {timestamp}^session_key */ -bool AuthTicketsManager::build_authorizer(uint32_t service_id, bufferlist& bl, AuthContext& ctx) +bool AuthTicketsManager::build_authorizer(uint32_t service_id, AuthAuthorizer& authorizer) { map::iterator iter = tickets_map.find(service_id); if (iter == tickets_map.end()) return false; AuthTicketHandler& handler = iter->second; - return handler.build_authorizer(bl, ctx); + return handler.build_authorizer(authorizer); } /* @@ -255,11 +256,11 @@ bool verify_authorizer(KeysKeeper& keys, bufferlist::iterator& indata, if (encode_encrypt(reply, ticket_info.session_key, reply_bl) < 0) return false; - dout(0) << "verify_authorizer: ok" << dendl; + dout(0) << "verify_authorizer: ok reply_bl.length()=" << reply_bl.length() << dendl; return true; } - +#if 0 bool AuthTicketHandler::decode_reply_authorizer(bufferlist::iterator& indata, AuthAuthorizeReply& reply) { if (decode_decrypt(reply, session_key, indata) < 0) @@ -279,6 +280,19 @@ bool AuthTicketHandler::verify_reply_authorizer(AuthContext& ctx, AuthAuthorizeR return false; } +#endif + +bool AuthAuthorizer::verify_reply(bufferlist::iterator& indata) +{ + AuthAuthorizeReply reply; + if (decode_decrypt(reply, session_key, indata) < 0) + return false; + if (ctx.timestamp + 1 != reply.timestamp) { + return false; + } + + return true; +} diff --git a/src/auth/Auth.h b/src/auth/Auth.h index 237ec8771571e..39572a1829438 100644 --- a/src/auth/Auth.h +++ b/src/auth/Auth.h @@ -180,6 +180,17 @@ struct AuthAuthorizeReply { WRITE_CLASS_ENCODER(AuthAuthorizeReply); +struct AuthAuthorizer { + CryptoKey session_key; + AuthContext ctx; + + bufferlist bl; + + bool build_authorizer(); + bool verify_reply(bufferlist::iterator& reply); + void clear() { bl.clear(); } +}; + /* * AuthTicketHandler */ @@ -201,9 +212,11 @@ struct AuthTicketHandler { bool get_session_keys(uint32_t keys, entity_addr_t& principal_addr, bufferlist& bl); #endif // to access the service - bool build_authorizer(bufferlist& bl, AuthContext& ctx); + bool build_authorizer(AuthAuthorizer& authorizer); +#if 0 bool decode_reply_authorizer(bufferlist::iterator& indata, AuthAuthorizeReply& reply); bool verify_reply_authorizer(AuthContext& ctx, AuthAuthorizeReply& reply); +#endif bool has_key() { return has_key_flag; } }; @@ -221,7 +234,7 @@ struct AuthTicketsManager { handler.service_id = type; return handler; } - bool build_authorizer(uint32_t service_id, bufferlist& bl, AuthContext& context); + bool build_authorizer(uint32_t service_id, AuthAuthorizer& authorizer); bool has_key(uint32_t service_id); }; diff --git a/src/auth/AuthClientHandler.cc b/src/auth/AuthClientHandler.cc index 476200aeb7df5..aca588c882c42 100644 --- a/src/auth/AuthClientHandler.cc +++ b/src/auth/AuthClientHandler.cc @@ -243,9 +243,11 @@ int AuthClientAuthenticateHandler::generate_cephx_authenticate_request(bufferlis ::encode(header, bl); - if (!ticket_handler.build_authorizer(bl, ctx)) + if (!ticket_handler.build_authorizer(authorizer)) return -EINVAL; + bl.claim_append(authorizer.bl); + build_service_ticket_request(want, bl); return 0; @@ -357,9 +359,11 @@ int AuthClientAuthorizeHandler::_build_request() ::encode(header, bl); utime_t now; - if (!client->tickets.build_authorizer(service_id, bl, ctx)) + if (!client->tickets.build_authorizer(service_id, authorizer)) return -EINVAL; + bl.claim_append(authorizer.bl); + return 0; } @@ -377,19 +381,8 @@ int AuthClientAuthorizeHandler::_handle_response(int ret, bufferlist::iterator& switch (header.request_type & CEPHX_REQUEST_TYPE_MASK) { case CEPHX_OPEN_SESSION: { - AuthTicketHandler& ticket_handler = client->tickets.get_handler(service_id); - AuthAuthorizeReply reply; - if (!ticket_handler.decode_reply_authorizer(iter, reply)) { - ret = -EINVAL; - break; - } - ret = 0; - bool result = ticket_handler.verify_reply_authorizer(ctx, reply); - if (!result) { - ret = -EPERM; - } - - break; + ret = authorizer.verify_reply(iter); + break; } break; default: @@ -508,16 +501,15 @@ void AuthClientHandler::tick() } -int AuthClientHandler::build_authorizer(uint32_t service_id, bufferlist& bl) +int AuthClientHandler::build_authorizer(uint32_t service_id, AuthAuthorizer& authorizer) { - AuthContext ctx; - dout(0) << "going to build authorizer for peer_id=" << service_id << " service_id=" << service_id << dendl; - if (!tickets.build_authorizer(service_id, bl, ctx)) + if (!tickets.build_authorizer(service_id, authorizer)) return -EINVAL; dout(0) << "authorizer built successfully" << dendl; return 0; } + diff --git a/src/auth/AuthClientHandler.h b/src/auth/AuthClientHandler.h index 93d9a778aeeff..17255e9f31226 100644 --- a/src/auth/AuthClientHandler.h +++ b/src/auth/AuthClientHandler.h @@ -51,7 +51,7 @@ protected: Context *timeout_event; uint32_t id; Mutex lock; - AuthContext ctx; + AuthAuthorizer authorizer; // session state int status; @@ -204,7 +204,7 @@ public: int authorize(uint32_t service_id, double timeout); void tick(); - int build_authorizer(uint32_t service_id, bufferlist& bl); + int build_authorizer(uint32_t service_id, AuthAuthorizer& authorizer); }; diff --git a/src/librados.cc b/src/librados.cc index 2373c6544ef58..ef216d0bdeb0f 100644 --- a/src/librados.cc +++ b/src/librados.cc @@ -60,7 +60,7 @@ class RadosClient : public Dispatcher bool _dispatch(Message *m); bool ms_dispatch(Message *m); - bool ms_get_authorizer(int dest_type, bufferlist& authorizer, bool force_new) { + bool ms_get_authorizer(int dest_type, AuthAuthorizer& authorizer, bool force_new) { dout(0) << "RadosClient::ms_get_authorizer type=" << dest_type << dendl; uint32_t want = peer_id_to_entity_type(dest_type); if (monclient.auth.build_authorizer(want, authorizer) < 0) diff --git a/src/mds/MDS.cc b/src/mds/MDS.cc index 4d1bb0d3f7d98..94471fe644731 100644 --- a/src/mds/MDS.cc +++ b/src/mds/MDS.cc @@ -1155,7 +1155,7 @@ bool MDS::ms_dispatch(Message *m) return ret; } -bool MDS::ms_get_authorizer(int dest_type, bufferlist& authorizer, bool force_new) +bool MDS::ms_get_authorizer(int dest_type, AuthAuthorizer& authorizer, bool force_new) { dout(0) << "OSD::ms_get_authorizer type=" << dest_type << dendl; /* monitor authorization is being handled on different layer */ diff --git a/src/mds/MDS.h b/src/mds/MDS.h index 6e823be430d53..f9406b5952030 100644 --- a/src/mds/MDS.h +++ b/src/mds/MDS.h @@ -304,7 +304,7 @@ class MDS : public Dispatcher { private: bool ms_dispatch(Message *m); - bool ms_get_authorizer(int dest_type, bufferlist& authorizer, bool force_new); + bool ms_get_authorizer(int dest_type, AuthAuthorizer& authorizer, bool force_new); public: MDS(const char *n, Messenger *m, MonClient *mc); diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index 2215c707924c4..192730b98b6b3 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -920,7 +920,7 @@ int Monitor::do_authorize(bufferlist::iterator& indata, bufferlist& result_bl) return ret; } -bool Monitor::ms_get_authorizer(int dest_type, bufferlist& authorizer, bool force_new) +bool Monitor::ms_get_authorizer(int dest_type, AuthAuthorizer& authorizer, bool force_new) { AuthServiceTicketInfo auth_ticket_info; @@ -970,8 +970,7 @@ bool Monitor::ms_get_authorizer(int dest_type, bufferlist& authorizer, bool forc handler.service_id = service_id; handler.session_key = info.session_key; - AuthContext ctx; - handler.build_authorizer(authorizer, ctx); + handler.build_authorizer(authorizer); return true; } diff --git a/src/mon/Monitor.h b/src/mon/Monitor.h index 9437a82b595d0..583af6bc57502 100644 --- a/src/mon/Monitor.h +++ b/src/mon/Monitor.h @@ -208,7 +208,7 @@ public: private: bool ms_dispatch(Message *m); - bool ms_get_authorizer(int dest_type, bufferlist& authorizer, bool force_new); + bool ms_get_authorizer(int dest_type, AuthAuthorizer& authorizer, bool force_new); bool ms_verify_authorizer(Connection *con, int peer_type, bufferlist& authorizer_data, bufferlist& authorizer_reply, bool& isvalid); diff --git a/src/msg/Dispatcher.h b/src/msg/Dispatcher.h index 047d01f60e5e3..f45e3a61c3a0f 100644 --- a/src/msg/Dispatcher.h +++ b/src/msg/Dispatcher.h @@ -18,6 +18,7 @@ #include "Message.h" #include "config.h" +#include "auth/Auth.h" class Messenger; @@ -45,7 +46,7 @@ public: // authorization handshake provides mutual authentication of peers. // connecting side - virtual bool ms_get_authorizer(int dest_type, bufferlist& authorizer, bool force_new) { return false; }; + virtual bool ms_get_authorizer(int dest_type, AuthAuthorizer& authorizer, bool force_new) { return false; }; // accepting side virtual bool ms_verify_authorizer(Connection *con, int peer_type, bufferlist& authorizer, bufferlist& authorizer_reply, diff --git a/src/msg/Messenger.h b/src/msg/Messenger.h index d5e32c6d71f27..a6a6bf177038e 100644 --- a/src/msg/Messenger.h +++ b/src/msg/Messenger.h @@ -124,7 +124,7 @@ protected: (*p)->ms_handle_remote_reset(con); } - bool ms_deliver_get_authorizer(int peer_type, bufferlist& authorizer, bool force_new) { + bool ms_deliver_get_authorizer(int peer_type, AuthAuthorizer& authorizer, bool force_new) { for (list::iterator p = dispatchers.begin(); p != dispatchers.end(); p++) diff --git a/src/msg/SimpleMessenger.cc b/src/msg/SimpleMessenger.cc index 0a3b26d9e82f1..2d22a82662a85 100644 --- a/src/msg/SimpleMessenger.cc +++ b/src/msg/SimpleMessenger.cc @@ -600,7 +600,6 @@ int SimpleMessenger::Pipe::accept() } - dout(0) << "accepting: connect.authorize_len=" << connect.authorizer_len << dendl; authorizer.clear(); if (connect.authorizer_len) { bp = buffer::create(connect.authorizer_len); @@ -609,8 +608,8 @@ int SimpleMessenger::Pipe::accept() goto fail_unlocked; } authorizer.push_back(bp); + authorizer_reply.clear(); } - authorizer_reply.clear(); dout(0) << "accept got peer connect_seq " << connect.connect_seq << " global_seq " << connect.global_seq @@ -767,7 +766,7 @@ int SimpleMessenger::Pipe::accept() rc = tcp_write(sd, (char*)&reply, sizeof(reply)); if (rc < 0) goto fail_unlocked; - if (authorizer_reply.length()) { + if (reply.authorizer_len) { rc = tcp_write(sd, authorizer_reply.c_str(), authorizer_reply.length()); if (rc < 0) goto fail_unlocked; @@ -804,6 +803,7 @@ int SimpleMessenger::Pipe::accept() reply.global_seq = rank->get_global_seq(); reply.connect_seq = connect_seq; reply.flags = 0; + reply.authorizer_len = authorizer_reply.length(); if (policy.lossy) reply.flags = reply.flags | CEPH_MSG_CONNECT_LOSSY; @@ -815,6 +815,12 @@ int SimpleMessenger::Pipe::accept() if (rc < 0) goto fail; + if (reply.authorizer_len) { + rc = tcp_write(sd, authorizer_reply.c_str(), authorizer_reply.length()); + if (rc < 0) + goto fail; + } + lock.Lock(); if (state != STATE_CLOSED) { dout(10) << "accept starting writer, " << "state=" << state << dendl; @@ -863,7 +869,8 @@ int SimpleMessenger::Pipe::connect() char banner[strlen(CEPH_BANNER)]; entity_addr_t paddr; entity_addr_t peer_addr_for_me, socket_addr; - bufferlist authorizer; + AuthAuthorizer authorizer; + bufferlist authorizer_reply; // create socket? sd = ::socket(AF_INET, SOCK_STREAM, 0); @@ -968,7 +975,7 @@ int SimpleMessenger::Pipe::connect() connect.global_seq = gseq; connect.connect_seq = cseq; connect.protocol_version = get_proto_version(rank->my_type, peer_type, true); - connect.authorizer_len = authorizer.length(); + connect.authorizer_len = authorizer.bl.length(); dout(0) << "connect.authorizer_len=" << connect.authorizer_len << dendl; connect.flags = 0; if (policy.lossy) @@ -979,9 +986,9 @@ int SimpleMessenger::Pipe::connect() msg.msg_iov = msgvec; msg.msg_iovlen = 1; msglen = msgvec[0].iov_len; - if (authorizer.length()) { - msgvec[1].iov_base = authorizer.c_str(); - msgvec[1].iov_len = authorizer.length(); + if (authorizer.bl.length()) { + msgvec[1].iov_base = authorizer.bl.c_str(); + msgvec[1].iov_len = authorizer.bl.length(); msg.msg_iovlen++; msglen += msgvec[1].iov_len; } @@ -1008,6 +1015,18 @@ int SimpleMessenger::Pipe::connect() << " flags " << (int)reply.flags << dendl; + authorizer_reply.clear(); + + if (reply.authorizer_len) { + dout(10) << "reply.authorizer_len=" << reply.authorizer_len << dendl; + bufferptr bp = buffer::create(reply.authorizer_len); + if (tcp_read(sd, bp.c_str(), reply.authorizer_len) < 0) { + dout(10) << "connect couldn't read connect authorizer_reply" << dendl; + goto fail; + } + authorizer_reply.push_back(bp); + } + lock.Lock(); if (state != STATE_CONNECTING) { dout(0) << "connect got RESETSESSION but no longer connecting" << dendl; @@ -2129,7 +2148,7 @@ SimpleMessenger::Pipe *SimpleMessenger::connect_rank(const entity_addr_t& addr, -bool SimpleMessenger::get_authorizer(int peer_type, bufferlist& authorizer, bool force_new) +bool SimpleMessenger::get_authorizer(int peer_type, AuthAuthorizer& authorizer, bool force_new) { for (unsigned r = 0; r < max_local; r++) { if (!local[r]) diff --git a/src/msg/SimpleMessenger.h b/src/msg/SimpleMessenger.h index 2e924d2ff4aa1..34f1c0bab3ec8 100644 --- a/src/msg/SimpleMessenger.h +++ b/src/msg/SimpleMessenger.h @@ -433,7 +433,7 @@ public: return ++global_seq; } - bool get_authorizer(int peer_type, bufferlist& bl, bool force_new); + bool get_authorizer(int peer_type, AuthAuthorizer& bl, bool force_new); bool verify_authorizer(Connection *con, int peer_type, bufferlist& auth, bufferlist& auth_reply, bool& isvalid); diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 8f2f9bcea9f55..b0993036f8824 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -1499,7 +1499,7 @@ bool OSD::ms_dispatch(Message *m) return true; } -bool OSD::ms_get_authorizer(int dest_type, bufferlist& authorizer, bool force_new) +bool OSD::ms_get_authorizer(int dest_type, AuthAuthorizer& authorizer, bool force_new) { dout(0) << "OSD::ms_get_authorizer type=" << dest_type << dendl; uint32_t want = peer_id_to_entity_type(dest_type); @@ -1579,10 +1579,6 @@ void OSD::_dispatch(Message *m) switch (m->get_type()) { - case CEPH_MSG_AUTH: - handle_auth((MAuth*)m); - break; - // -- don't need lock -- case CEPH_MSG_PING: dout(10) << "ping from " << m->get_source() << dendl; diff --git a/src/osd/OSD.h b/src/osd/OSD.h index 9ad41ebd04632..7bf0446beea21 100644 --- a/src/osd/OSD.h +++ b/src/osd/OSD.h @@ -852,7 +852,7 @@ protected: private: bool ms_dispatch(Message *m); - bool ms_get_authorizer(int dest_type, bufferlist& authorizer, bool force_new); + bool ms_get_authorizer(int dest_type, AuthAuthorizer& authorizer, bool force_new); bool ms_verify_authorizer(Connection *con, int peer_type, bufferlist& authorizer, bufferlist& authorizer_reply, bool& isvalid); -- 2.39.5