Commit 0a990e70 authored by Sage Weil's avatar Sage Weil

ceph: clean up service ticket decoding

Previously we would decode state directly into our current ticket_handler.
This is problematic if for some reason we fail to decode, because we end
up with half new state and half old state.

We are probably already in bad shape if we get an update we can't decode,
but we may as well be tidy anyway.  Decode into new_* temporaries and
update the ticket_handler only on success.
Signed-off-by: default avatarSage Weil <sage@newdream.net>
parent 5b3dbb44
...@@ -156,7 +156,11 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, ...@@ -156,7 +156,11 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
struct timespec validity; struct timespec validity;
struct ceph_crypto_key old_key; struct ceph_crypto_key old_key;
void *tp, *tpend; void *tp, *tpend;
struct ceph_timespec new_validity;
struct ceph_crypto_key new_session_key;
struct ceph_buffer *new_ticket_blob; struct ceph_buffer *new_ticket_blob;
unsigned long new_expires, new_renew_after;
u64 new_secret_id;
ceph_decode_need(&p, end, sizeof(u32) + 1, bad); ceph_decode_need(&p, end, sizeof(u32) + 1, bad);
...@@ -189,16 +193,16 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, ...@@ -189,16 +193,16 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
goto bad; goto bad;
memcpy(&old_key, &th->session_key, sizeof(old_key)); memcpy(&old_key, &th->session_key, sizeof(old_key));
ret = ceph_crypto_key_decode(&th->session_key, &dp, dend); ret = ceph_crypto_key_decode(&new_session_key, &dp, dend);
if (ret) if (ret)
goto out; goto out;
ceph_decode_copy(&dp, &th->validity, sizeof(th->validity)); ceph_decode_copy(&dp, &new_validity, sizeof(new_validity));
ceph_decode_timespec(&validity, &th->validity); ceph_decode_timespec(&validity, &new_validity);
th->expires = get_seconds() + validity.tv_sec; new_expires = get_seconds() + validity.tv_sec;
th->renew_after = th->expires - (validity.tv_sec / 4); new_renew_after = new_expires - (validity.tv_sec / 4);
dout(" expires=%lu renew_after=%lu\n", th->expires, dout(" expires=%lu renew_after=%lu\n", new_expires,
th->renew_after); new_renew_after);
/* ticket blob for service */ /* ticket blob for service */
ceph_decode_8_safe(&p, end, is_enc, bad); ceph_decode_8_safe(&p, end, is_enc, bad);
...@@ -223,13 +227,21 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, ...@@ -223,13 +227,21 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
dout(" ticket blob is %d bytes\n", dlen); dout(" ticket blob is %d bytes\n", dlen);
ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad); ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad);
struct_v = ceph_decode_8(&tp); struct_v = ceph_decode_8(&tp);
th->secret_id = ceph_decode_64(&tp); new_secret_id = ceph_decode_64(&tp);
ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend); ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend);
if (ret) if (ret)
goto out; goto out;
/* all is well, update our ticket */
ceph_crypto_key_destroy(&th->session_key);
if (th->ticket_blob) if (th->ticket_blob)
ceph_buffer_put(th->ticket_blob); ceph_buffer_put(th->ticket_blob);
th->session_key = new_session_key;
th->ticket_blob = new_ticket_blob; th->ticket_blob = new_ticket_blob;
th->validity = new_validity;
th->secret_id = new_secret_id;
th->expires = new_expires;
th->renew_after = new_renew_after;
dout(" got ticket service %d (%s) secret_id %lld len %d\n", dout(" got ticket service %d (%s) secret_id %lld len %d\n",
type, ceph_entity_type_name(type), th->secret_id, type, ceph_entity_type_name(type), th->secret_id,
(int)th->ticket_blob->vec.iov_len); (int)th->ticket_blob->vec.iov_len);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment