aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/auth_x.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph/auth_x.c')
-rw-r--r--fs/ceph/auth_x.c54
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
32static int ceph_x_encrypt_buflen(int ilen)
33{
34 return sizeof(struct ceph_x_encrypt_header) + ilen + 16 +
35 sizeof(u32);
36}
37
31static int ceph_x_encrypt(struct ceph_crypto_key *secret, 38static 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
301out_buf: 325out_buf: