Message ID | 1410335671-4581-3-git-send-email-ilya.dryomov@inktank.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Reviewed-by: On Wed, 10 Sep 2014, Ilya Dryomov wrote: > Add a helper for processing individual cephx auth tickets. Needed for > the next commit, that deals with allocating ticket buffers. (Most of > the diff here is whitespace - view with git diff -b). > > Cc: stable@vger.kernel.org > Signed-off-by: Ilya Dryomov <ilya.dryomov@inktank.com> > --- > net/ceph/auth_x.c | 228 +++++++++++++++++++++++++++++------------------------ > 1 file changed, 124 insertions(+), 104 deletions(-) > > diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c > index 96238ba95f2b..0eb146dce1aa 100644 > --- a/net/ceph/auth_x.c > +++ b/net/ceph/auth_x.c > @@ -129,17 +129,131 @@ static void remove_ticket_handler(struct ceph_auth_client *ac, > kfree(th); > } > > +static int process_one_ticket(struct ceph_auth_client *ac, > + struct ceph_crypto_key *secret, > + void **p, void *end, > + void *dbuf, void *ticket_buf) > +{ > + struct ceph_x_info *xi = ac->private; > + int type; > + u8 tkt_struct_v, blob_struct_v; > + struct ceph_x_ticket_handler *th; > + void *dp, *dend; > + int dlen; > + char is_enc; > + struct timespec validity; > + struct ceph_crypto_key old_key; > + void *tp, *tpend; > + struct ceph_timespec new_validity; > + struct ceph_crypto_key new_session_key; > + struct ceph_buffer *new_ticket_blob; > + unsigned long new_expires, new_renew_after; > + u64 new_secret_id; > + int ret; > + > + ceph_decode_need(p, end, sizeof(u32) + 1, bad); > + > + type = ceph_decode_32(p); > + dout(" ticket type %d %s\n", type, ceph_entity_type_name(type)); > + > + tkt_struct_v = ceph_decode_8(p); > + if (tkt_struct_v != 1) > + goto bad; > + > + th = get_ticket_handler(ac, type); > + if (IS_ERR(th)) { > + ret = PTR_ERR(th); > + goto out; > + } > + > + /* blob for me */ > + dlen = ceph_x_decrypt(secret, p, end, dbuf, > + TEMP_TICKET_BUF_LEN); > + if (dlen <= 0) { > + ret = dlen; > + goto out; > + } > + dout(" decrypted %d bytes\n", dlen); > + dp = dbuf; > + dend = dp + dlen; > + > + tkt_struct_v = ceph_decode_8(&dp); > + if (tkt_struct_v != 1) > + goto bad; > + > + memcpy(&old_key, &th->session_key, sizeof(old_key)); > + ret = ceph_crypto_key_decode(&new_session_key, &dp, dend); > + if (ret) > + goto out; > + > + ceph_decode_copy(&dp, &new_validity, sizeof(new_validity)); > + ceph_decode_timespec(&validity, &new_validity); > + new_expires = get_seconds() + validity.tv_sec; > + new_renew_after = new_expires - (validity.tv_sec / 4); > + dout(" expires=%lu renew_after=%lu\n", new_expires, > + new_renew_after); > + > + /* ticket blob for service */ > + ceph_decode_8_safe(p, end, is_enc, bad); > + tp = ticket_buf; > + if (is_enc) { > + /* encrypted */ > + dout(" encrypted ticket\n"); > + dlen = ceph_x_decrypt(&old_key, p, end, ticket_buf, > + TEMP_TICKET_BUF_LEN); > + if (dlen < 0) { > + ret = dlen; > + goto out; > + } > + dlen = ceph_decode_32(&tp); > + } else { > + /* unencrypted */ > + ceph_decode_32_safe(p, end, dlen, bad); > + ceph_decode_need(p, end, dlen, bad); > + ceph_decode_copy(p, ticket_buf, dlen); > + } > + tpend = tp + dlen; > + dout(" ticket blob is %d bytes\n", dlen); > + ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad); > + blob_struct_v = ceph_decode_8(&tp); > + new_secret_id = ceph_decode_64(&tp); > + ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend); > + if (ret) > + goto out; > + > + /* all is well, update our ticket */ > + ceph_crypto_key_destroy(&th->session_key); > + if (th->ticket_blob) > + ceph_buffer_put(th->ticket_blob); > + th->session_key = new_session_key; > + 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", > + type, ceph_entity_type_name(type), th->secret_id, > + (int)th->ticket_blob->vec.iov_len); > + xi->have_keys |= th->service; > + > +out: > + return ret; > + > +bad: > + ret = -EINVAL; > + goto out; > +} > + > static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, > struct ceph_crypto_key *secret, > void *buf, void *end) > { > - struct ceph_x_info *xi = ac->private; > - int num; > void *p = buf; > - int ret; > char *dbuf; > char *ticket_buf; > u8 reply_struct_v; > + u32 num; > + int ret; > > dbuf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS); > if (!dbuf) > @@ -150,112 +264,18 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, > if (!ticket_buf) > goto out_dbuf; > > - ceph_decode_need(&p, end, 1 + sizeof(u32), bad); > - reply_struct_v = ceph_decode_8(&p); > + ceph_decode_8_safe(&p, end, reply_struct_v, bad); > if (reply_struct_v != 1) > - goto bad; > - num = ceph_decode_32(&p); > - dout("%d tickets\n", num); > - while (num--) { > - int type; > - u8 tkt_struct_v, blob_struct_v; > - struct ceph_x_ticket_handler *th; > - void *dp, *dend; > - int dlen; > - char is_enc; > - struct timespec validity; > - struct ceph_crypto_key old_key; > - void *tp, *tpend; > - struct ceph_timespec new_validity; > - struct ceph_crypto_key new_session_key; > - 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); > - > - type = ceph_decode_32(&p); > - dout(" ticket type %d %s\n", type, ceph_entity_type_name(type)); > - > - tkt_struct_v = ceph_decode_8(&p); > - if (tkt_struct_v != 1) > - goto bad; > - > - th = get_ticket_handler(ac, type); > - if (IS_ERR(th)) { > - ret = PTR_ERR(th); > - goto out; > - } > - > - /* blob for me */ > - dlen = ceph_x_decrypt(secret, &p, end, dbuf, > - TEMP_TICKET_BUF_LEN); > - if (dlen <= 0) { > - ret = dlen; > - goto out; > - } > - dout(" decrypted %d bytes\n", dlen); > - dend = dbuf + dlen; > - dp = dbuf; > - > - tkt_struct_v = ceph_decode_8(&dp); > - if (tkt_struct_v != 1) > - goto bad; > + return -EINVAL; > > - memcpy(&old_key, &th->session_key, sizeof(old_key)); > - ret = ceph_crypto_key_decode(&new_session_key, &dp, dend); > - if (ret) > - goto out; > + ceph_decode_32_safe(&p, end, num, bad); > + dout("%d tickets\n", num); > > - ceph_decode_copy(&dp, &new_validity, sizeof(new_validity)); > - ceph_decode_timespec(&validity, &new_validity); > - new_expires = get_seconds() + validity.tv_sec; > - new_renew_after = new_expires - (validity.tv_sec / 4); > - dout(" expires=%lu renew_after=%lu\n", new_expires, > - new_renew_after); > - > - /* ticket blob for service */ > - ceph_decode_8_safe(&p, end, is_enc, bad); > - tp = ticket_buf; > - if (is_enc) { > - /* encrypted */ > - dout(" encrypted ticket\n"); > - dlen = ceph_x_decrypt(&old_key, &p, end, ticket_buf, > - TEMP_TICKET_BUF_LEN); > - if (dlen < 0) { > - ret = dlen; > - goto out; > - } > - dlen = ceph_decode_32(&tp); > - } else { > - /* unencrypted */ > - ceph_decode_32_safe(&p, end, dlen, bad); > - ceph_decode_need(&p, end, dlen, bad); > - ceph_decode_copy(&p, ticket_buf, dlen); > - } > - tpend = tp + dlen; > - dout(" ticket blob is %d bytes\n", dlen); > - ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad); > - blob_struct_v = ceph_decode_8(&tp); > - new_secret_id = ceph_decode_64(&tp); > - ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend); > + while (num--) { > + ret = process_one_ticket(ac, secret, &p, end, > + dbuf, ticket_buf); > if (ret) > goto out; > - > - /* all is well, update our ticket */ > - ceph_crypto_key_destroy(&th->session_key); > - if (th->ticket_blob) > - ceph_buffer_put(th->ticket_blob); > - th->session_key = new_session_key; > - 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", > - type, ceph_entity_type_name(type), th->secret_id, > - (int)th->ticket_blob->vec.iov_len); > - xi->have_keys |= th->service; > } > > ret = 0; > -- > 1.7.10.4 > > -- > To unsubscribe from this list: send the line "unsubscribe ceph-devel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > > -- To unsubscribe from this list: send the line "unsubscribe ceph-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c index 96238ba95f2b..0eb146dce1aa 100644 --- a/net/ceph/auth_x.c +++ b/net/ceph/auth_x.c @@ -129,17 +129,131 @@ static void remove_ticket_handler(struct ceph_auth_client *ac, kfree(th); } +static int process_one_ticket(struct ceph_auth_client *ac, + struct ceph_crypto_key *secret, + void **p, void *end, + void *dbuf, void *ticket_buf) +{ + struct ceph_x_info *xi = ac->private; + int type; + u8 tkt_struct_v, blob_struct_v; + struct ceph_x_ticket_handler *th; + void *dp, *dend; + int dlen; + char is_enc; + struct timespec validity; + struct ceph_crypto_key old_key; + void *tp, *tpend; + struct ceph_timespec new_validity; + struct ceph_crypto_key new_session_key; + struct ceph_buffer *new_ticket_blob; + unsigned long new_expires, new_renew_after; + u64 new_secret_id; + int ret; + + ceph_decode_need(p, end, sizeof(u32) + 1, bad); + + type = ceph_decode_32(p); + dout(" ticket type %d %s\n", type, ceph_entity_type_name(type)); + + tkt_struct_v = ceph_decode_8(p); + if (tkt_struct_v != 1) + goto bad; + + th = get_ticket_handler(ac, type); + if (IS_ERR(th)) { + ret = PTR_ERR(th); + goto out; + } + + /* blob for me */ + dlen = ceph_x_decrypt(secret, p, end, dbuf, + TEMP_TICKET_BUF_LEN); + if (dlen <= 0) { + ret = dlen; + goto out; + } + dout(" decrypted %d bytes\n", dlen); + dp = dbuf; + dend = dp + dlen; + + tkt_struct_v = ceph_decode_8(&dp); + if (tkt_struct_v != 1) + goto bad; + + memcpy(&old_key, &th->session_key, sizeof(old_key)); + ret = ceph_crypto_key_decode(&new_session_key, &dp, dend); + if (ret) + goto out; + + ceph_decode_copy(&dp, &new_validity, sizeof(new_validity)); + ceph_decode_timespec(&validity, &new_validity); + new_expires = get_seconds() + validity.tv_sec; + new_renew_after = new_expires - (validity.tv_sec / 4); + dout(" expires=%lu renew_after=%lu\n", new_expires, + new_renew_after); + + /* ticket blob for service */ + ceph_decode_8_safe(p, end, is_enc, bad); + tp = ticket_buf; + if (is_enc) { + /* encrypted */ + dout(" encrypted ticket\n"); + dlen = ceph_x_decrypt(&old_key, p, end, ticket_buf, + TEMP_TICKET_BUF_LEN); + if (dlen < 0) { + ret = dlen; + goto out; + } + dlen = ceph_decode_32(&tp); + } else { + /* unencrypted */ + ceph_decode_32_safe(p, end, dlen, bad); + ceph_decode_need(p, end, dlen, bad); + ceph_decode_copy(p, ticket_buf, dlen); + } + tpend = tp + dlen; + dout(" ticket blob is %d bytes\n", dlen); + ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad); + blob_struct_v = ceph_decode_8(&tp); + new_secret_id = ceph_decode_64(&tp); + ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend); + if (ret) + goto out; + + /* all is well, update our ticket */ + ceph_crypto_key_destroy(&th->session_key); + if (th->ticket_blob) + ceph_buffer_put(th->ticket_blob); + th->session_key = new_session_key; + 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", + type, ceph_entity_type_name(type), th->secret_id, + (int)th->ticket_blob->vec.iov_len); + xi->have_keys |= th->service; + +out: + return ret; + +bad: + ret = -EINVAL; + goto out; +} + static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, struct ceph_crypto_key *secret, void *buf, void *end) { - struct ceph_x_info *xi = ac->private; - int num; void *p = buf; - int ret; char *dbuf; char *ticket_buf; u8 reply_struct_v; + u32 num; + int ret; dbuf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS); if (!dbuf) @@ -150,112 +264,18 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, if (!ticket_buf) goto out_dbuf; - ceph_decode_need(&p, end, 1 + sizeof(u32), bad); - reply_struct_v = ceph_decode_8(&p); + ceph_decode_8_safe(&p, end, reply_struct_v, bad); if (reply_struct_v != 1) - goto bad; - num = ceph_decode_32(&p); - dout("%d tickets\n", num); - while (num--) { - int type; - u8 tkt_struct_v, blob_struct_v; - struct ceph_x_ticket_handler *th; - void *dp, *dend; - int dlen; - char is_enc; - struct timespec validity; - struct ceph_crypto_key old_key; - void *tp, *tpend; - struct ceph_timespec new_validity; - struct ceph_crypto_key new_session_key; - 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); - - type = ceph_decode_32(&p); - dout(" ticket type %d %s\n", type, ceph_entity_type_name(type)); - - tkt_struct_v = ceph_decode_8(&p); - if (tkt_struct_v != 1) - goto bad; - - th = get_ticket_handler(ac, type); - if (IS_ERR(th)) { - ret = PTR_ERR(th); - goto out; - } - - /* blob for me */ - dlen = ceph_x_decrypt(secret, &p, end, dbuf, - TEMP_TICKET_BUF_LEN); - if (dlen <= 0) { - ret = dlen; - goto out; - } - dout(" decrypted %d bytes\n", dlen); - dend = dbuf + dlen; - dp = dbuf; - - tkt_struct_v = ceph_decode_8(&dp); - if (tkt_struct_v != 1) - goto bad; + return -EINVAL; - memcpy(&old_key, &th->session_key, sizeof(old_key)); - ret = ceph_crypto_key_decode(&new_session_key, &dp, dend); - if (ret) - goto out; + ceph_decode_32_safe(&p, end, num, bad); + dout("%d tickets\n", num); - ceph_decode_copy(&dp, &new_validity, sizeof(new_validity)); - ceph_decode_timespec(&validity, &new_validity); - new_expires = get_seconds() + validity.tv_sec; - new_renew_after = new_expires - (validity.tv_sec / 4); - dout(" expires=%lu renew_after=%lu\n", new_expires, - new_renew_after); - - /* ticket blob for service */ - ceph_decode_8_safe(&p, end, is_enc, bad); - tp = ticket_buf; - if (is_enc) { - /* encrypted */ - dout(" encrypted ticket\n"); - dlen = ceph_x_decrypt(&old_key, &p, end, ticket_buf, - TEMP_TICKET_BUF_LEN); - if (dlen < 0) { - ret = dlen; - goto out; - } - dlen = ceph_decode_32(&tp); - } else { - /* unencrypted */ - ceph_decode_32_safe(&p, end, dlen, bad); - ceph_decode_need(&p, end, dlen, bad); - ceph_decode_copy(&p, ticket_buf, dlen); - } - tpend = tp + dlen; - dout(" ticket blob is %d bytes\n", dlen); - ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad); - blob_struct_v = ceph_decode_8(&tp); - new_secret_id = ceph_decode_64(&tp); - ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend); + while (num--) { + ret = process_one_ticket(ac, secret, &p, end, + dbuf, ticket_buf); if (ret) goto out; - - /* all is well, update our ticket */ - ceph_crypto_key_destroy(&th->session_key); - if (th->ticket_blob) - ceph_buffer_put(th->ticket_blob); - th->session_key = new_session_key; - 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", - type, ceph_entity_type_name(type), th->secret_id, - (int)th->ticket_blob->vec.iov_len); - xi->have_keys |= th->service; } ret = 0;
Add a helper for processing individual cephx auth tickets. Needed for the next commit, that deals with allocating ticket buffers. (Most of the diff here is whitespace - view with git diff -b). Cc: stable@vger.kernel.org Signed-off-by: Ilya Dryomov <ilya.dryomov@inktank.com> --- net/ceph/auth_x.c | 228 +++++++++++++++++++++++++++++------------------------ 1 file changed, 124 insertions(+), 104 deletions(-)