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