diff options
Diffstat (limited to 'fs/ceph/auth_x.c')
-rw-r--r-- | fs/ceph/auth_x.c | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/fs/ceph/auth_x.c b/fs/ceph/auth_x.c index f0318427b6da..d9001a4dc8cc 100644 --- a/fs/ceph/auth_x.c +++ b/fs/ceph/auth_x.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/err.h> | 4 | #include <linux/err.h> |
5 | #include <linux/module.h> | 5 | #include <linux/module.h> |
6 | #include <linux/random.h> | 6 | #include <linux/random.h> |
7 | #include <linux/slab.h> | ||
7 | 8 | ||
8 | #include "auth_x.h" | 9 | #include "auth_x.h" |
9 | #include "auth_x_protocol.h" | 10 | #include "auth_x_protocol.h" |
@@ -28,6 +29,12 @@ static int ceph_x_is_authenticated(struct ceph_auth_client *ac) | |||
28 | return (ac->want_keys & xi->have_keys) == ac->want_keys; | 29 | return (ac->want_keys & xi->have_keys) == ac->want_keys; |
29 | } | 30 | } |
30 | 31 | ||
32 | static int ceph_x_encrypt_buflen(int ilen) | ||
33 | { | ||
34 | return sizeof(struct ceph_x_encrypt_header) + ilen + 16 + | ||
35 | sizeof(u32); | ||
36 | } | ||
37 | |||
31 | static int ceph_x_encrypt(struct ceph_crypto_key *secret, | 38 | static int ceph_x_encrypt(struct ceph_crypto_key *secret, |
32 | void *ibuf, int ilen, void *obuf, size_t olen) | 39 | void *ibuf, int ilen, void *obuf, size_t olen) |
33 | { | 40 | { |
@@ -150,6 +157,11 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, | |||
150 | struct timespec validity; | 157 | struct timespec validity; |
151 | struct ceph_crypto_key old_key; | 158 | struct ceph_crypto_key old_key; |
152 | void *tp, *tpend; | 159 | void *tp, *tpend; |
160 | struct ceph_timespec new_validity; | ||
161 | struct ceph_crypto_key new_session_key; | ||
162 | struct ceph_buffer *new_ticket_blob; | ||
163 | unsigned long new_expires, new_renew_after; | ||
164 | u64 new_secret_id; | ||
153 | 165 | ||
154 | ceph_decode_need(&p, end, sizeof(u32) + 1, bad); | 166 | ceph_decode_need(&p, end, sizeof(u32) + 1, bad); |
155 | 167 | ||
@@ -182,16 +194,16 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, | |||
182 | goto bad; | 194 | goto bad; |
183 | 195 | ||
184 | memcpy(&old_key, &th->session_key, sizeof(old_key)); | 196 | memcpy(&old_key, &th->session_key, sizeof(old_key)); |
185 | ret = ceph_crypto_key_decode(&th->session_key, &dp, dend); | 197 | ret = ceph_crypto_key_decode(&new_session_key, &dp, dend); |
186 | if (ret) | 198 | if (ret) |
187 | goto out; | 199 | goto out; |
188 | 200 | ||
189 | ceph_decode_copy(&dp, &th->validity, sizeof(th->validity)); | 201 | ceph_decode_copy(&dp, &new_validity, sizeof(new_validity)); |
190 | ceph_decode_timespec(&validity, &th->validity); | 202 | ceph_decode_timespec(&validity, &new_validity); |
191 | th->expires = get_seconds() + validity.tv_sec; | 203 | new_expires = get_seconds() + validity.tv_sec; |
192 | th->renew_after = th->expires - (validity.tv_sec / 4); | 204 | new_renew_after = new_expires - (validity.tv_sec / 4); |
193 | dout(" expires=%lu renew_after=%lu\n", th->expires, | 205 | dout(" expires=%lu renew_after=%lu\n", new_expires, |
194 | th->renew_after); | 206 | new_renew_after); |
195 | 207 | ||
196 | /* ticket blob for service */ | 208 | /* ticket blob for service */ |
197 | ceph_decode_8_safe(&p, end, is_enc, bad); | 209 | ceph_decode_8_safe(&p, end, is_enc, bad); |
@@ -216,10 +228,21 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, | |||
216 | dout(" ticket blob is %d bytes\n", dlen); | 228 | dout(" ticket blob is %d bytes\n", dlen); |
217 | ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad); | 229 | ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad); |
218 | struct_v = ceph_decode_8(&tp); | 230 | struct_v = ceph_decode_8(&tp); |
219 | th->secret_id = ceph_decode_64(&tp); | 231 | new_secret_id = ceph_decode_64(&tp); |
220 | ret = ceph_decode_buffer(&th->ticket_blob, &tp, tpend); | 232 | ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend); |
221 | if (ret) | 233 | if (ret) |
222 | goto out; | 234 | goto out; |
235 | |||
236 | /* all is well, update our ticket */ | ||
237 | ceph_crypto_key_destroy(&th->session_key); | ||
238 | if (th->ticket_blob) | ||
239 | ceph_buffer_put(th->ticket_blob); | ||
240 | th->session_key = new_session_key; | ||
241 | th->ticket_blob = new_ticket_blob; | ||
242 | th->validity = new_validity; | ||
243 | th->secret_id = new_secret_id; | ||
244 | th->expires = new_expires; | ||
245 | th->renew_after = new_renew_after; | ||
223 | dout(" got ticket service %d (%s) secret_id %lld len %d\n", | 246 | dout(" got ticket service %d (%s) secret_id %lld len %d\n", |
224 | type, ceph_entity_type_name(type), th->secret_id, | 247 | type, ceph_entity_type_name(type), th->secret_id, |
225 | (int)th->ticket_blob->vec.iov_len); | 248 | (int)th->ticket_blob->vec.iov_len); |
@@ -242,7 +265,7 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac, | |||
242 | struct ceph_x_ticket_handler *th, | 265 | struct ceph_x_ticket_handler *th, |
243 | struct ceph_x_authorizer *au) | 266 | struct ceph_x_authorizer *au) |
244 | { | 267 | { |
245 | int len; | 268 | int maxlen; |
246 | struct ceph_x_authorize_a *msg_a; | 269 | struct ceph_x_authorize_a *msg_a; |
247 | struct ceph_x_authorize_b msg_b; | 270 | struct ceph_x_authorize_b msg_b; |
248 | void *p, *end; | 271 | void *p, *end; |
@@ -253,15 +276,15 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac, | |||
253 | dout("build_authorizer for %s %p\n", | 276 | dout("build_authorizer for %s %p\n", |
254 | ceph_entity_type_name(th->service), au); | 277 | ceph_entity_type_name(th->service), au); |
255 | 278 | ||
256 | len = sizeof(*msg_a) + sizeof(msg_b) + sizeof(u32) + | 279 | maxlen = sizeof(*msg_a) + sizeof(msg_b) + |
257 | ticket_blob_len + 16; | 280 | ceph_x_encrypt_buflen(ticket_blob_len); |
258 | dout(" need len %d\n", len); | 281 | dout(" need len %d\n", maxlen); |
259 | if (au->buf && au->buf->alloc_len < len) { | 282 | if (au->buf && au->buf->alloc_len < maxlen) { |
260 | ceph_buffer_put(au->buf); | 283 | ceph_buffer_put(au->buf); |
261 | au->buf = NULL; | 284 | au->buf = NULL; |
262 | } | 285 | } |
263 | if (!au->buf) { | 286 | if (!au->buf) { |
264 | au->buf = ceph_buffer_new(len, GFP_NOFS); | 287 | au->buf = ceph_buffer_new(maxlen, GFP_NOFS); |
265 | if (!au->buf) | 288 | if (!au->buf) |
266 | return -ENOMEM; | 289 | return -ENOMEM; |
267 | } | 290 | } |
@@ -296,6 +319,7 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac, | |||
296 | au->buf->vec.iov_len = p - au->buf->vec.iov_base; | 319 | au->buf->vec.iov_len = p - au->buf->vec.iov_base; |
297 | dout(" built authorizer nonce %llx len %d\n", au->nonce, | 320 | dout(" built authorizer nonce %llx len %d\n", au->nonce, |
298 | (int)au->buf->vec.iov_len); | 321 | (int)au->buf->vec.iov_len); |
322 | BUG_ON(au->buf->vec.iov_len > maxlen); | ||
299 | return 0; | 323 | return 0; |
300 | 324 | ||
301 | out_buf: | 325 | out_buf: |