map<string, bufferlist> caps;
void encode(bufferlist& bl) const {
+ __u8 struct_v = 1;
+ ::encode(struct_v, bl);
::encode(key, bl);
::encode(caps, bl);
}
void decode(bufferlist::iterator& bl) {
+ __u8 struct_v;
+ ::decode(struct_v, bl);
::decode(key, bl);
::decode(caps, bl);
}
AuthCapsInfo() : allow_all(false) {}
void encode(bufferlist& bl) const {
- uint32_t a = (uint32_t)allow_all;
+ __u8 struct_v = 1;
+ ::encode(struct_v, bl);
+ __u8 a = (__u8)allow_all;
::encode(a, bl);
::encode(caps, bl);
}
void decode(bufferlist::iterator& bl) {
- uint32_t a;
+ __u8 struct_v;
+ ::decode(struct_v, bl);
+ __u8 a;
::decode(a, bl);
allow_all = (bool)a;
::decode(caps, bl);
utime_t expiration;
void encode(bufferlist& bl) const {
+ __u8 struct_v = 1;
+ ::encode(struct_v, bl);
::encode(key, bl);
::encode(expiration, bl);
}
void decode(bufferlist::iterator& bl) {
+ __u8 struct_v;
+ ::decode(struct_v, bl);
::decode(key, bl);
::decode(expiration, bl);
}
RotatingSecrets() : max_ver(0) {}
void encode(bufferlist& bl) const {
+ __u8 struct_v = 1;
+ ::encode(struct_v, bl);
::encode(secrets, bl);
::encode(max_ver, bl);
}
void decode(bufferlist::iterator& bl) {
+ __u8 struct_v;
+ ::decode(struct_v, bl);
::decode(secrets, bl);
::decode(max_ver, bl);
}
return false;
}
-bool KeyRing::get_service_secret(uint32_t service_id, uint64_t secret_id, CryptoKey& secret)
-{
- Mutex::Locker l(lock);
- /* we ignore the service id, there's only one service id that we're handling */
+void KeyRing::dump_rotating()
{
- map<uint64_t, ExpiringCryptoKey>::iterator iter = rotating_secrets.secrets.begin();
- dout(0) << "dumping rotating secrets: this=" << dendl;
-
- for (; iter != rotating_secrets.secrets.end(); ++iter) {
- ExpiringCryptoKey& key = iter->second;
-
- dout(0) << "id: " << iter->first << dendl;
- dout(0) << "key.expiration: " << key.expiration << dendl;
- bufferptr& bp = key.key.get_secret();
- bufferlist bl;
- bl.append(bp);
- hexdump(" key", bl.c_str(), bl.length());
- }
+ dout(0) << "dump_rotating:" << dendl;
+ for (map<uint64_t, ExpiringCryptoKey>::iterator iter = rotating_secrets.secrets.begin();
+ iter != rotating_secrets.secrets.end();
+ ++iter)
+ dout(0) << " id " << iter->first << " " << iter->second.key
+ << " expires " << iter->second.expiration << dendl;
}
+bool KeyRing::get_service_secret(uint32_t service_id, uint64_t secret_id, CryptoKey& secret)
+{
+ Mutex::Locker l(lock);
+
+ /* we ignore the service id, there's only one service id that we're handling */
map<uint64_t, ExpiringCryptoKey>::iterator iter = rotating_secrets.secrets.find(secret_id);
if (iter == rotating_secrets.secrets.end()) {
dout(0) << "could not find secret_id=" << secret_id << dendl;
+ dump_rotating();
return false;
}
void import(KeyRing& other);
// weirdness
+ void dump_rotating();
void set_rotating(RotatingSecrets& secrets);
bool need_rotating_secrets();
bool get_service_secret(uint32_t service_id, uint64_t secret_id, CryptoKey& secret);
void encode(bufferlist& bl) const {
- __u8 v = 1;
- ::encode(v, bl);
+ __u8 struct_v = 1;
+ ::encode(struct_v, bl);
::encode(keys, bl);
}
void decode(bufferlist::iterator& bl) {
- __u8 v;
- ::decode(v, bl);
+ __u8 struct_v;
+ ::decode(struct_v, bl);
::decode(keys, bl);
}
};
if (data.rotating_ver <= rotating_ver)
return false;
-
- ::encode(data.rotating_ver, rotating_bl);
- ::encode(data.rotating_secrets, rotating_bl);
+
+ data.encode_rotating(rotating_bl);
rotating_ver = data.rotating_ver;
KeyServerData() : version(0), rotating_ver(0) {}
void encode(bufferlist& bl) const {
+ __u8 struct_v = 1;
+ ::encode(struct_v, bl);
::encode(version, bl);
::encode(rotating_ver, bl);
::encode(next_rotating_time, bl);
::encode(rotating_secrets, bl);
}
void decode(bufferlist::iterator& bl) {
+ __u8 struct_v;
+ ::decode(struct_v, bl);
::decode(version, bl);
::decode(rotating_ver, bl);
::decode(next_rotating_time, bl);
::decode(rotating_secrets, bl);
}
+ void encode_rotating(bufferlist& bl) {
+ __u8 struct_v = 1;
+ ::encode(struct_v, bl);
+ ::encode(rotating_ver, bl);
+ ::encode(rotating_secrets, bl);
+ }
void decode_rotating(bufferlist& rotating_bl) {
bufferlist::iterator iter = rotating_bl.begin();
+ __u8 struct_v;
+ ::decode(struct_v, iter);
::decode(rotating_ver, iter);
::decode(rotating_secrets, iter);
}
EntityAuth auth;
void encode(bufferlist& bl) const {
- __u32 _op = (__u32)op;
+ __u8 struct_v = 1;
+ ::encode(struct_v, bl);
+ __u32 _op = (__u32)op;
::encode(_op, bl);
if (op == AUTH_INC_SET_ROTATING) {
::encode(rotating_bl, bl);
}
}
void decode(bufferlist::iterator& bl) {
+ __u8 struct_v;
+ ::decode(struct_v, bl);
__u32 _op;
::decode(_op, bl);
op = (IncrementalOp)_op;
* Authentication
*/
-bool cephx_build_service_ticket(CephXSessionAuthInfo& info, bufferlist& reply)
+bool cephx_build_service_ticket_blob(CephXSessionAuthInfo& info, CephXTicketBlob& blob)
{
CephXServiceTicketInfo ticket_info;
ticket_info.session_key = info.session_key;
ticket_info.ticket = info.ticket;
ticket_info.ticket.caps = info.ticket.caps;
- ::encode(info.secret_id, reply);
+
dout(10) << "build_service_ticket encoded info.secret_id=" << info.secret_id
<< " ticket_info.ticket.name=" << ticket_info.ticket.name.to_str() << dendl;
- if (encode_encrypt(ticket_info, info.service_secret, reply) < 0)
+ blob.secret_id = info.secret_id;
+ if (encode_encrypt_enc_bl(ticket_info, info.service_secret, blob.blob) < 0)
return false;
-
return true;
}
CryptoKey& ticket_enc_key,
bufferlist& reply)
{
+ __u8 service_ticket_reply_v = 1;
+ ::encode(service_ticket_reply_v, reply);
+
uint32_t num = ticket_info_vec.size();
::encode(num, reply);
dout(10) << "build_service_ticket_reply encoding " << num
CephXSessionAuthInfo& info = *ticket_iter;
::encode(info.service_id, reply);
+ __u8 service_ticket_v = 1;
+ ::encode(service_ticket_v, reply);
+
CephXServiceTicket msg_a;
msg_a.session_key = info.session_key;
msg_a.validity = info.validity;
bufferlist service_ticket_bl;
- if (!cephx_build_service_ticket(info, service_ticket_bl))
+ CephXTicketBlob blob;
+ if (!cephx_build_service_ticket_blob(info, blob))
return false;
+ ::encode(blob, service_ticket_bl);
::encode((__u8)should_encrypt_ticket, reply);
* this ServiceTicket with the result.
*/
bool CephXTicketHandler::verify_service_ticket_reply(CryptoKey& secret,
- bufferlist::iterator& indata)
+ bufferlist::iterator& indata)
{
- CephXServiceTicket msg_a;
+ __u8 service_ticket_v;
+ ::decode(service_ticket_v, indata);
+ CephXServiceTicket msg_a;
if (decode_decrypt(msg_a, secret, indata) < 0) {
dout(0) << "verify_service_ticket_reply failed decode_decrypt with secret " << secret << dendl;
return false;
}
- __u8 ticket_enc;
+
+ __u8 ticket_enc;
::decode(ticket_enc, indata);
if (ticket_enc) {
dout(10) << "getting encrypted ticket" << dendl;
bool CephXTicketManager::verify_service_ticket_reply(CryptoKey& secret,
bufferlist::iterator& indata)
{
+ __u8 service_ticket_reply_v;
+ ::decode(service_ticket_reply_v, indata);
+
uint32_t num;
::decode(num, indata);
dout(10) << "verify_service_ticket_reply got " << num << " keys" << dendl;
a->session_key = session_key;
a->nonce = ((__u64)rand() << 32) + rand();
+ __u8 authorizer_v = 1;
+ ::encode(authorizer_v, a->bl);
+
::encode(global_id, a->bl);
::encode(service_id, a->bl);
+
::encode(ticket, a->bl);
CephXAuthorize msg;
bool cephx_verify_authorizer(KeyStore& keys, bufferlist::iterator& indata,
CephXServiceTicketInfo& ticket_info, bufferlist& reply_bl)
{
+ __u8 authorizer_v;
+ ::decode(authorizer_v, indata);
+
uint32_t service_id;
- uint64_t secret_id;
uint64_t global_id;
CryptoKey service_secret;
::decode(global_id, indata);
::decode(service_id, indata);
- ::decode(secret_id, indata);
- dout(10) << "verify_authorizer decrypted service_id=" << service_id << " secret_id=" << secret_id << dendl;
- if (secret_id == (uint64_t)-1) {
+ // ticket blob
+ CephXTicketBlob ticket;
+ ::decode(ticket, indata);
+ dout(10) << "verify_authorizer decrypted service_id=" << service_id
+ << " secret_id=" << ticket.secret_id << dendl;
+
+ if (ticket.secret_id == (uint64_t)-1) {
EntityName name;
name.entity_type = service_id;
if (!keys.get_secret(name, service_secret)) {
- dout(0) << "verify_authorizer could not get general service secret for service_id=" << service_id << " secret_id=" << secret_id << dendl;
+ dout(0) << "verify_authorizer could not get general service secret for service_id=" << service_id
+ << " secret_id=" << ticket.secret_id << dendl;
return false;
}
} else {
- if (!keys.get_service_secret(service_id, secret_id, service_secret)) {
- dout(0) << "verify_authorizer could not get service secret for service_id=" << service_id << " secret_id=" << secret_id << dendl;
+ if (!keys.get_service_secret(service_id, ticket.secret_id, service_secret)) {
+ dout(0) << "verify_authorizer could not get service secret for service_id=" << service_id
+ << " secret_id=" << ticket.secret_id << dendl;
return false;
}
}
- if (decode_decrypt(ticket_info, service_secret, indata) < 0) {
+ if (decode_decrypt_enc_bl(ticket_info, service_secret, ticket.blob) < 0) {
dout(0) << "verify_authorizer could not decrypt ticket info" << dendl;
return false;
}
if (ticket_info.ticket.global_id != global_id) {
- dout(0) << "verify_authorizer global_id mismatch: declared id=" << global_id << " ticket_id=" << ticket_info.ticket.global_id << dendl;
+ dout(0) << "verify_authorizer global_id mismatch: declared id=" << global_id
+ << " ticket_id=" << ticket_info.ticket.global_id << dendl;
return false;
}
dout(10) << "verify_authorizer global_id=" << global_id << dendl;
+ // CephXAuthorize
CephXAuthorize auth_msg;
if (decode_decrypt(auth_msg, ticket_info.session_key, indata) < 0) {
dout(0) << "verify_authorizercould not decrypt authorize request" << dendl;
__u64 server_challenge;
void encode(bufferlist& bl) const {
+ __u8 struct_v = 1;
+ ::encode(struct_v, bl);
::encode(server_challenge, bl);
}
void decode(bufferlist::iterator& bl) {
+ __u8 struct_v;
+ ::decode(struct_v, bl);
::decode(server_challenge, bl);
}
};
bufferlist blob;
void encode(bufferlist& bl) const {
+ __u8 struct_v = 1;
+ ::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);
}
CephXTicketBlob old_ticket;
void encode(bufferlist& bl) const {
+ __u8 struct_v = 1;
+ ::encode(struct_v, bl);
::encode(client_challenge, bl);
::encode(key, bl);
::encode(old_ticket, bl);
}
void decode(bufferlist::iterator& bl) {
+ __u8 struct_v;
+ ::decode(struct_v, bl);
::decode(client_challenge, bl);
::decode(key, bl);
::decode(old_ticket, bl);
};
-extern bool cephx_build_service_ticket(CephXSessionAuthInfo& ticket_info, bufferlist& reply);
+extern bool cephx_build_service_ticket_blob(CephXSessionAuthInfo& ticket_info, CephXTicketBlob& blob);
extern void cephx_build_service_ticket_request(uint32_t keys,
bufferlist& request);
uint32_t keys;
void encode(bufferlist& bl) const {
+ __u8 struct_v = 1;
+ ::encode(struct_v, bl);
::encode(keys, bl);
}
void decode(bufferlist::iterator& bl) {
+ __u8 struct_v;
+ ::decode(struct_v, bl);
::decode(keys, bl);
}
};
struct CephXAuthorizeReply {
__u64 nonce_plus_one;
void encode(bufferlist& bl) const {
+ __u8 struct_v = 1;
+ ::encode(struct_v, bl);
::encode(nonce_plus_one, bl);
}
void decode(bufferlist::iterator& bl) {
+ __u8 struct_v;
+ ::decode(struct_v, bl);
::decode(nonce_plus_one, bl);
}
};
utime_t validity;
void encode(bufferlist& bl) const {
+ __u8 struct_v = 1;
+ ::encode(struct_v, bl);
::encode(session_key, bl);
::encode(validity, bl);
}
void decode(bufferlist::iterator& bl) {
+ __u8 struct_v;
+ ::decode(struct_v, bl);
::decode(session_key, bl);
::decode(validity, bl);
}
CryptoKey session_key;
void encode(bufferlist& bl) const {
+ __u8 struct_v = 1;
+ ::encode(struct_v, bl);
::encode(ticket, bl);
::encode(session_key, bl);
}
void decode(bufferlist::iterator& bl) {
+ __u8 struct_v;
+ ::decode(struct_v, bl);
::decode(ticket, bl);
::decode(session_key, bl);
}
struct CephXAuthorize {
__u64 nonce;
void encode(bufferlist& bl) const {
+ __u8 struct_v = 1;
+ ::encode(struct_v, bl);
::encode(nonce, bl);
}
void decode(bufferlist::iterator& bl) {
+ __u8 struct_v;
+ ::decode(struct_v, bl);
::decode(nonce, bl);
}
};
}
bufferlist::iterator iter2 = bl.begin();
+ __u8 struct_v;
+ ::decode(struct_v, iter2);
::decode(magic, iter2);
if (magic != AUTH_ENC_MAGIC) {
generic_dout(0) << "bad magic in decode_decrypt, " << magic << " != " << AUTH_ENC_MAGIC << dendl;
return 0;
}
+template <typename T>
+int encode_encrypt_enc_bl(const T& t, CryptoKey& key, bufferlist& out) {
+ bufferlist bl;
+ __u8 struct_v = 1;
+ ::encode(struct_v, bl);
+ uint64_t magic = AUTH_ENC_MAGIC;
+ ::encode(magic, bl);
+ ::encode(t, bl);
+
+ int ret = key.encrypt(bl, out);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
template <typename T>
int decode_decrypt(T& t, CryptoKey key, bufferlist::iterator& iter) {
bufferlist bl_enc;
::decode(bl_enc, iter);
-
return decode_decrypt_enc_bl(t, key, bl_enc);
}
template <typename T>
int encode_encrypt(const T& t, CryptoKey& key, bufferlist& out) {
- uint64_t magic = AUTH_ENC_MAGIC;
- bufferlist bl;
- ::encode(magic, bl);
- ::encode(t, bl);
-
bufferlist bl_enc;
- int ret = key.encrypt(bl, bl_enc);
+ int ret = encode_encrypt_enc_bl(t, key, bl_enc);
if (ret < 0)
return ret;
-
::encode(bl_enc, out);
return 0;
}
bufferlist::iterator iter = authorizer_data.begin();
try {
+ __u8 struct_v = 1;
+ ::decode(struct_v, iter);
::decode(entity_name, iter);
::decode(global_id, iter);
} catch (buffer::error *err) {
struct AuthNoneAuthorizer : public AuthAuthorizer {
AuthNoneAuthorizer() : AuthAuthorizer(CEPH_AUTH_NONE) { }
bool build_authorizer(uint64_t global_id) {
+ __u8 struct_v = 1;
+ ::encode(struct_v, bl);
::encode(*g_conf.entity_name, bl);
::encode(global_id, bl);
return 0;
set<__u32> supported;
try {
+ __u8 struct_v = 1;
+ ::decode(struct_v, indata);
::decode(supported, indata);
::decode(entity_name, indata);
::decode(s->global_id, indata);
MAuth *m = new MAuth;
m->protocol = 0;
+ __u8 struct_v = 1;
+ ::encode(struct_v, m->auth_payload);
::encode(auth_supported, m->auth_payload);
::encode(entity_name, m->auth_payload);
::encode(global_id, m->auth_payload);
}
- bufferlist ticket_data;
- ret = cephx_build_service_ticket(info, ticket_data);
+ CephXTicketBlob blob;
+ ret = cephx_build_service_ticket_blob(info, blob);
if (ret < 0)
return false;
+ bufferlist ticket_data;
+ ::encode(blob, ticket_data);
dout(0) << "built service ticket" << dendl;
bufferlist::iterator iter = ticket_data.begin();