/*
Ceph X protocol
- First, the principal has to authenticate with the authenticator. A
- shared-secret mechanism is being used, and the negotitaion goes like this:
+ See doc/dev/cephx.rst
- A = Authenticator
- P = Principle
- S = Service
-
- 1. Obtaining principal/auth session key
-
- (Authenticate Request)
- p->a : principal, principal_addr. authenticate me!
-
- ...authenticator does lookup in database...
-
- a->p : A= {principal/auth session key, validity}^principal_secret (*)
- B= {principal ticket, validity, principal/auth session key}^authsecret
-
-
- [principal/auth session key, validity] = service ticket
- [principal ticket, validity, principal/auth session key] = service ticket info
-
- (*) annotation: ^ signifies 'encrypted by'
-
- At this point, if is genuine, the principal should have the principal/auth
- session key at hand. The next step would be to request an authorization to
- use some other service:
-
- 2. Obtaining principal/service session key
-
- p->a : B, {principal_addr, timestamp}^principal/auth session key. authorize
- me!
- a->p : E= {service ticket}^svcsecret
- F= {principal/service session key, validity}^principal/auth session key
-
- principal_addr, timestamp = authenticator
-
- service ticket = principal name, client network address, validity, principal/service session key
-
- Note that steps 1 and 2 are pretty much the same thing; contacting the
- authenticator and requesting for a key.
-
- Following this the principal should have a principal/service session key that
- could be used later on for creating a session:
-
- 3. Opening a session to a service
-
- p->s : E + {principal_addr, timestamp}^principal/service session key
- s->p : {timestamp+1}^principal/service/session key
-
- timestamp+1 = reply authenticator
-
- Now, the principal is fully authenticated with the service. So, logically we
- have 2 main actions here. The first one would be to obtain a session key to
- the service (steps 1 and 2), and the second one would be to authenticate with
- the service, using that ticket.
*/
/* authenticate requests */
uint64_t server_challenge;
void encode(bufferlist& bl) const {
+ using ceph::encode;
__u8 struct_v = 1;
- ::encode(struct_v, bl);
- ::encode(server_challenge, bl);
+ encode(struct_v, bl);
+ encode(server_challenge, bl);
}
- void decode(bufferlist::iterator& bl) {
+ void decode(bufferlist::const_iterator& bl) {
+ using ceph::decode;
__u8 struct_v;
- ::decode(struct_v, bl);
- ::decode(server_challenge, bl);
+ decode(struct_v, bl);
+ decode(server_challenge, bl);
}
};
WRITE_CLASS_ENCODER(CephXServerChallenge)
__u16 request_type;
void encode(bufferlist& bl) const {
- ::encode(request_type, bl);
+ using ceph::encode;
+ encode(request_type, bl);
}
- void decode(bufferlist::iterator& bl) {
- ::decode(request_type, bl);
+ void decode(bufferlist::const_iterator& bl) {
+ using ceph::decode;
+ decode(request_type, bl);
}
};
WRITE_CLASS_ENCODER(CephXRequestHeader)
int32_t status;
void encode(bufferlist& bl) const {
- ::encode(request_type, bl);
- ::encode(status, bl);
+ using ceph::encode;
+ encode(request_type, bl);
+ encode(status, bl);
}
- void decode(bufferlist::iterator& bl) {
- ::decode(request_type, bl);
- ::decode(status, bl);
+ void decode(bufferlist::const_iterator& bl) {
+ using ceph::decode;
+ decode(request_type, bl);
+ decode(status, bl);
}
};
WRITE_CLASS_ENCODER(CephXResponseHeader)
CephXTicketBlob() : secret_id(0) {}
void encode(bufferlist& bl) const {
+ using ceph::encode;
__u8 struct_v = 1;
- ::encode(struct_v, bl);
- ::encode(secret_id, bl);
- ::encode(blob, bl);
+ encode(struct_v, bl);
+ encode(secret_id, bl);
+ encode(blob, bl);
}
- void decode(bufferlist::iterator& bl) {
- __u8 struct_v;
- ::decode(struct_v, bl);
- ::decode(secret_id, bl);
- ::decode(blob, bl);
+ void decode(bufferlist::const_iterator& bl) {
+ using ceph::decode;
+ __u8 struct_v;
+ decode(struct_v, bl);
+ decode(secret_id, bl);
+ decode(blob, bl);
}
};
WRITE_CLASS_ENCODER(CephXTicketBlob)
uint64_t client_challenge;
uint64_t key;
CephXTicketBlob old_ticket;
+ uint32_t other_keys = 0; // replaces CephXServiceTicketRequest
void encode(bufferlist& bl) const {
- __u8 struct_v = 1;
- ::encode(struct_v, bl);
- ::encode(client_challenge, bl);
- ::encode(key, bl);
- ::encode(old_ticket, bl);
+ using ceph::encode;
+ __u8 struct_v = 2;
+ encode(struct_v, bl);
+ encode(client_challenge, bl);
+ encode(key, bl);
+ encode(old_ticket, bl);
+ encode(other_keys, bl);
}
- void decode(bufferlist::iterator& bl) {
+ void decode(bufferlist::const_iterator& bl) {
+ using ceph::decode;
__u8 struct_v;
- ::decode(struct_v, bl);
- ::decode(client_challenge, bl);
- ::decode(key, bl);
- ::decode(old_ticket, bl);
- }
+ decode(struct_v, bl);
+ decode(client_challenge, bl);
+ decode(key, bl);
+ decode(old_ticket, bl);
+ if (struct_v >= 2) {
+ decode(other_keys, bl);
+ }
+ }
};
WRITE_CLASS_ENCODER(CephXAuthenticate)
uint64_t server_challenge, client_challenge;
void encode(bufferlist& bl) const {
- ::encode(server_challenge, bl);
- ::encode(client_challenge, bl);
+ using ceph::encode;
+ encode(server_challenge, bl);
+ encode(client_challenge, bl);
}
- void decode(bufferlist::iterator& bl) {
- ::decode(server_challenge, bl);
- ::decode(client_challenge, bl);
+ void decode(bufferlist::const_iterator& bl) {
+ using ceph::decode;
+ decode(server_challenge, bl);
+ decode(client_challenge, bl);
}
};
WRITE_CLASS_ENCODER(CephXChallengeBlob)
uint32_t keys;
void encode(bufferlist& bl) const {
+ using ceph::encode;
__u8 struct_v = 1;
- ::encode(struct_v, bl);
- ::encode(keys, bl);
+ encode(struct_v, bl);
+ encode(keys, bl);
}
- void decode(bufferlist::iterator& bl) {
+ void decode(bufferlist::const_iterator& bl) {
+ using ceph::decode;
__u8 struct_v;
- ::decode(struct_v, bl);
- ::decode(keys, bl);
+ decode(struct_v, bl);
+ decode(keys, bl);
}
};
WRITE_CLASS_ENCODER(CephXServiceTicketRequest)
struct CephXAuthorizeReply {
uint64_t nonce_plus_one;
+ std::string connection_secret;
void encode(bufferlist& bl) const {
+ using ceph::encode;
__u8 struct_v = 1;
- ::encode(struct_v, bl);
- ::encode(nonce_plus_one, bl);
+ if (connection_secret.size()) {
+ struct_v = 2;
+ }
+ encode(struct_v, bl);
+ encode(nonce_plus_one, bl);
+ if (struct_v >= 2) {
+ struct_v = 2;
+ encode(connection_secret, bl);
+ }
}
- void decode(bufferlist::iterator& bl) {
+ void decode(bufferlist::const_iterator& bl) {
+ using ceph::decode;
__u8 struct_v;
- ::decode(struct_v, bl);
- ::decode(nonce_plus_one, bl);
+ decode(struct_v, bl);
+ decode(nonce_plus_one, bl);
+ if (struct_v >= 2) {
+ decode(connection_secret, bl);
+ }
}
};
WRITE_CLASS_ENCODER(CephXAuthorizeReply)
: AuthAuthorizer(CEPH_AUTH_CEPHX), cct(cct_), nonce(0) {}
bool build_authorizer();
- bool verify_reply(bufferlist::iterator& reply) override;
- bool add_challenge(CephContext *cct, bufferlist& challenge) override;
+ bool verify_reply(bufferlist::const_iterator& reply,
+ std::string *connection_secret) override;
+ bool add_challenge(CephContext *cct, const bufferlist& challenge) override;
};
// to build our ServiceTicket
bool verify_service_ticket_reply(CryptoKey& principal_secret,
- bufferlist::iterator& indata);
+ bufferlist::const_iterator& indata);
// to access the service
CephXAuthorizer *build_authorizer(uint64_t global_id) const;
explicit CephXTicketManager(CephContext *cct_) : global_id(0), cct(cct_) {}
bool verify_service_ticket_reply(CryptoKey& principal_secret,
- bufferlist::iterator& indata);
+ bufferlist::const_iterator& indata);
CephXTicketHandler& get_handler(uint32_t type) {
tickets_map_t::iterator i = tickets_map.find(type);
CephXTicketHandler newTicketHandler(cct, type);
std::pair < tickets_map_t::iterator, bool > res =
tickets_map.insert(std::make_pair(type, newTicketHandler));
- assert(res.second);
+ ceph_assert(res.second);
return res.first->second;
}
CephXAuthorizer *build_authorizer(uint32_t service_id) const;
utime_t validity;
void encode(bufferlist& bl) const {
+ using ceph::encode;
__u8 struct_v = 1;
- ::encode(struct_v, bl);
- ::encode(session_key, bl);
- ::encode(validity, bl);
+ encode(struct_v, bl);
+ encode(session_key, bl);
+ encode(validity, bl);
}
- void decode(bufferlist::iterator& bl) {
+ void decode(bufferlist::const_iterator& bl) {
+ using ceph::decode;
__u8 struct_v;
- ::decode(struct_v, bl);
- ::decode(session_key, bl);
- ::decode(validity, bl);
+ decode(struct_v, bl);
+ decode(session_key, bl);
+ decode(validity, bl);
}
};
WRITE_CLASS_ENCODER(CephXServiceTicket)
CryptoKey session_key;
void encode(bufferlist& bl) const {
+ using ceph::encode;
__u8 struct_v = 1;
- ::encode(struct_v, bl);
- ::encode(ticket, bl);
- ::encode(session_key, bl);
+ encode(struct_v, bl);
+ encode(ticket, bl);
+ encode(session_key, bl);
}
- void decode(bufferlist::iterator& bl) {
+ void decode(bufferlist::const_iterator& bl) {
+ using ceph::decode;
__u8 struct_v;
- ::decode(struct_v, bl);
- ::decode(ticket, bl);
- ::decode(session_key, bl);
+ decode(struct_v, bl);
+ decode(ticket, bl);
+ decode(session_key, bl);
}
};
WRITE_CLASS_ENCODER(CephXServiceTicketInfo)
struct CephXAuthorizeChallenge : public AuthAuthorizerChallenge {
uint64_t server_challenge;
void encode(bufferlist& bl) const {
+ using ceph::encode;
__u8 struct_v = 1;
- ::encode(struct_v, bl);
- ::encode(server_challenge, bl);
+ encode(struct_v, bl);
+ encode(server_challenge, bl);
}
- void decode(bufferlist::iterator& bl) {
+ void decode(bufferlist::const_iterator& bl) {
+ using ceph::decode;
__u8 struct_v;
- ::decode(struct_v, bl);
- ::decode(server_challenge, bl);
+ decode(struct_v, bl);
+ decode(server_challenge, bl);
}
};
WRITE_CLASS_ENCODER(CephXAuthorizeChallenge)
bool have_challenge = false;
uint64_t server_challenge_plus_one = 0;
void encode(bufferlist& bl) const {
+ using ceph::encode;
__u8 struct_v = 2;
- ::encode(struct_v, bl);
- ::encode(nonce, bl);
- ::encode(have_challenge, bl);
- ::encode(server_challenge_plus_one, bl);
+ encode(struct_v, bl);
+ encode(nonce, bl);
+ encode(have_challenge, bl);
+ encode(server_challenge_plus_one, bl);
}
- void decode(bufferlist::iterator& bl) {
+ void decode(bufferlist::const_iterator& bl) {
+ using ceph::decode;
__u8 struct_v;
- ::decode(struct_v, bl);
- ::decode(nonce, bl);
+ decode(struct_v, bl);
+ decode(nonce, bl);
if (struct_v >= 2) {
- ::decode(have_challenge, bl);
- ::decode(server_challenge_plus_one, bl);
+ decode(have_challenge, bl);
+ decode(server_challenge_plus_one, bl);
}
-
}
};
WRITE_CLASS_ENCODER(CephXAuthorize)
* Verify authorizer and generate reply authorizer
*/
extern bool cephx_verify_authorizer(
- CephContext *cct, KeyStore *keys,
- bufferlist::iterator& indata,
+ CephContext *cct,
+ KeyStore *keys,
+ bufferlist::const_iterator& indata,
+ size_t connection_secret_required_len,
CephXServiceTicketInfo& ticket_info,
std::unique_ptr<AuthAuthorizerChallenge> *challenge,
- bufferlist& reply_bl);
+ std::string *connection_secret,
+ bufferlist *reply_bl);
static constexpr uint64_t AUTH_ENC_MAGIC = 0xff009cad8826aa55ull;
template <typename T>
-void decode_decrypt_enc_bl(CephContext *cct, T& t, CryptoKey key, bufferlist& bl_enc,
+void decode_decrypt_enc_bl(CephContext *cct, T& t, CryptoKey key,
+ const bufferlist& bl_enc,
std::string &error)
{
uint64_t magic;
if (key.decrypt(cct, bl_enc, bl, &error) < 0)
return;
- bufferlist::iterator iter2 = bl.begin();
+ auto iter2 = bl.cbegin();
__u8 struct_v;
- ::decode(struct_v, iter2);
- ::decode(magic, iter2);
+ decode(struct_v, iter2);
+ decode(magic, iter2);
if (magic != AUTH_ENC_MAGIC) {
ostringstream oss;
oss << "bad magic in decode_decrypt, " << magic << " != " << AUTH_ENC_MAGIC;
return;
}
- ::decode(t, iter2);
+ decode(t, iter2);
}
template <typename T>
{
bufferlist bl;
__u8 struct_v = 1;
- ::encode(struct_v, bl);
+ encode(struct_v, bl);
uint64_t magic = AUTH_ENC_MAGIC;
- ::encode(magic, bl);
- ::encode(t, bl);
+ encode(magic, bl);
+ encode(t, bl);
key.encrypt(cct, bl, out, &error);
}
template <typename T>
int decode_decrypt(CephContext *cct, T& t, const CryptoKey& key,
- bufferlist::iterator& iter, std::string &error)
+ bufferlist::const_iterator& iter, std::string &error)
{
bufferlist bl_enc;
try {
- ::decode(bl_enc, iter);
+ decode(bl_enc, iter);
decode_decrypt_enc_bl(cct, t, key, bl_enc, error);
}
catch (buffer::error &e) {
if (!error.empty()){
return CEPHX_CRYPT_ERR;
}
- ::encode(bl_enc, out);
+ encode(bl_enc, out);
return 0;
}
-
#endif