]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.16.3/libceph-add-process_one_ticket-helper.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.16.3 / libceph-add-process_one_ticket-helper.patch
CommitLineData
9515b5a6
GKH
1From 597cda357716a3cf8d994cb11927af917c8d71fa Mon Sep 17 00:00:00 2001
2From: Ilya Dryomov <ilya.dryomov@inktank.com>
3Date: Mon, 8 Sep 2014 17:25:34 +0400
4Subject: libceph: add process_one_ticket() helper
5
6From: Ilya Dryomov <ilya.dryomov@inktank.com>
7
8commit 597cda357716a3cf8d994cb11927af917c8d71fa upstream.
9
10Add a helper for processing individual cephx auth tickets. Needed for
11the next commit, which deals with allocating ticket buffers. (Most of
12the diff here is whitespace - view with git diff -b).
13
14Signed-off-by: Ilya Dryomov <ilya.dryomov@inktank.com>
15Reviewed-by: Sage Weil <sage@redhat.com>
16Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
17
18---
19 net/ceph/auth_x.c | 228 +++++++++++++++++++++++++++++-------------------------
20 1 file changed, 124 insertions(+), 104 deletions(-)
21
22--- a/net/ceph/auth_x.c
23+++ b/net/ceph/auth_x.c
24@@ -129,17 +129,131 @@ static void remove_ticket_handler(struct
25 kfree(th);
26 }
27
28+static int process_one_ticket(struct ceph_auth_client *ac,
29+ struct ceph_crypto_key *secret,
30+ void **p, void *end,
31+ void *dbuf, void *ticket_buf)
32+{
33+ struct ceph_x_info *xi = ac->private;
34+ int type;
35+ u8 tkt_struct_v, blob_struct_v;
36+ struct ceph_x_ticket_handler *th;
37+ void *dp, *dend;
38+ int dlen;
39+ char is_enc;
40+ struct timespec validity;
41+ struct ceph_crypto_key old_key;
42+ void *tp, *tpend;
43+ struct ceph_timespec new_validity;
44+ struct ceph_crypto_key new_session_key;
45+ struct ceph_buffer *new_ticket_blob;
46+ unsigned long new_expires, new_renew_after;
47+ u64 new_secret_id;
48+ int ret;
49+
50+ ceph_decode_need(p, end, sizeof(u32) + 1, bad);
51+
52+ type = ceph_decode_32(p);
53+ dout(" ticket type %d %s\n", type, ceph_entity_type_name(type));
54+
55+ tkt_struct_v = ceph_decode_8(p);
56+ if (tkt_struct_v != 1)
57+ goto bad;
58+
59+ th = get_ticket_handler(ac, type);
60+ if (IS_ERR(th)) {
61+ ret = PTR_ERR(th);
62+ goto out;
63+ }
64+
65+ /* blob for me */
66+ dlen = ceph_x_decrypt(secret, p, end, dbuf,
67+ TEMP_TICKET_BUF_LEN);
68+ if (dlen <= 0) {
69+ ret = dlen;
70+ goto out;
71+ }
72+ dout(" decrypted %d bytes\n", dlen);
73+ dp = dbuf;
74+ dend = dp + dlen;
75+
76+ tkt_struct_v = ceph_decode_8(&dp);
77+ if (tkt_struct_v != 1)
78+ goto bad;
79+
80+ memcpy(&old_key, &th->session_key, sizeof(old_key));
81+ ret = ceph_crypto_key_decode(&new_session_key, &dp, dend);
82+ if (ret)
83+ goto out;
84+
85+ ceph_decode_copy(&dp, &new_validity, sizeof(new_validity));
86+ ceph_decode_timespec(&validity, &new_validity);
87+ new_expires = get_seconds() + validity.tv_sec;
88+ new_renew_after = new_expires - (validity.tv_sec / 4);
89+ dout(" expires=%lu renew_after=%lu\n", new_expires,
90+ new_renew_after);
91+
92+ /* ticket blob for service */
93+ ceph_decode_8_safe(p, end, is_enc, bad);
94+ tp = ticket_buf;
95+ if (is_enc) {
96+ /* encrypted */
97+ dout(" encrypted ticket\n");
98+ dlen = ceph_x_decrypt(&old_key, p, end, ticket_buf,
99+ TEMP_TICKET_BUF_LEN);
100+ if (dlen < 0) {
101+ ret = dlen;
102+ goto out;
103+ }
104+ dlen = ceph_decode_32(&tp);
105+ } else {
106+ /* unencrypted */
107+ ceph_decode_32_safe(p, end, dlen, bad);
108+ ceph_decode_need(p, end, dlen, bad);
109+ ceph_decode_copy(p, ticket_buf, dlen);
110+ }
111+ tpend = tp + dlen;
112+ dout(" ticket blob is %d bytes\n", dlen);
113+ ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad);
114+ blob_struct_v = ceph_decode_8(&tp);
115+ new_secret_id = ceph_decode_64(&tp);
116+ ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend);
117+ if (ret)
118+ goto out;
119+
120+ /* all is well, update our ticket */
121+ ceph_crypto_key_destroy(&th->session_key);
122+ if (th->ticket_blob)
123+ ceph_buffer_put(th->ticket_blob);
124+ th->session_key = new_session_key;
125+ th->ticket_blob = new_ticket_blob;
126+ th->validity = new_validity;
127+ th->secret_id = new_secret_id;
128+ th->expires = new_expires;
129+ th->renew_after = new_renew_after;
130+ dout(" got ticket service %d (%s) secret_id %lld len %d\n",
131+ type, ceph_entity_type_name(type), th->secret_id,
132+ (int)th->ticket_blob->vec.iov_len);
133+ xi->have_keys |= th->service;
134+
135+out:
136+ return ret;
137+
138+bad:
139+ ret = -EINVAL;
140+ goto out;
141+}
142+
143 static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
144 struct ceph_crypto_key *secret,
145 void *buf, void *end)
146 {
147- struct ceph_x_info *xi = ac->private;
148- int num;
149 void *p = buf;
150- int ret;
151 char *dbuf;
152 char *ticket_buf;
153 u8 reply_struct_v;
154+ u32 num;
155+ int ret;
156
157 dbuf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS);
158 if (!dbuf)
159@@ -150,112 +264,18 @@ static int ceph_x_proc_ticket_reply(stru
160 if (!ticket_buf)
161 goto out_dbuf;
162
163- ceph_decode_need(&p, end, 1 + sizeof(u32), bad);
164- reply_struct_v = ceph_decode_8(&p);
165+ ceph_decode_8_safe(&p, end, reply_struct_v, bad);
166 if (reply_struct_v != 1)
167- goto bad;
168- num = ceph_decode_32(&p);
169- dout("%d tickets\n", num);
170- while (num--) {
171- int type;
172- u8 tkt_struct_v, blob_struct_v;
173- struct ceph_x_ticket_handler *th;
174- void *dp, *dend;
175- int dlen;
176- char is_enc;
177- struct timespec validity;
178- struct ceph_crypto_key old_key;
179- void *tp, *tpend;
180- struct ceph_timespec new_validity;
181- struct ceph_crypto_key new_session_key;
182- struct ceph_buffer *new_ticket_blob;
183- unsigned long new_expires, new_renew_after;
184- u64 new_secret_id;
185-
186- ceph_decode_need(&p, end, sizeof(u32) + 1, bad);
187-
188- type = ceph_decode_32(&p);
189- dout(" ticket type %d %s\n", type, ceph_entity_type_name(type));
190-
191- tkt_struct_v = ceph_decode_8(&p);
192- if (tkt_struct_v != 1)
193- goto bad;
194-
195- th = get_ticket_handler(ac, type);
196- if (IS_ERR(th)) {
197- ret = PTR_ERR(th);
198- goto out;
199- }
200-
201- /* blob for me */
202- dlen = ceph_x_decrypt(secret, &p, end, dbuf,
203- TEMP_TICKET_BUF_LEN);
204- if (dlen <= 0) {
205- ret = dlen;
206- goto out;
207- }
208- dout(" decrypted %d bytes\n", dlen);
209- dend = dbuf + dlen;
210- dp = dbuf;
211-
212- tkt_struct_v = ceph_decode_8(&dp);
213- if (tkt_struct_v != 1)
214- goto bad;
215+ return -EINVAL;
216
217- memcpy(&old_key, &th->session_key, sizeof(old_key));
218- ret = ceph_crypto_key_decode(&new_session_key, &dp, dend);
219- if (ret)
220- goto out;
221+ ceph_decode_32_safe(&p, end, num, bad);
222+ dout("%d tickets\n", num);
223
224- ceph_decode_copy(&dp, &new_validity, sizeof(new_validity));
225- ceph_decode_timespec(&validity, &new_validity);
226- new_expires = get_seconds() + validity.tv_sec;
227- new_renew_after = new_expires - (validity.tv_sec / 4);
228- dout(" expires=%lu renew_after=%lu\n", new_expires,
229- new_renew_after);
230-
231- /* ticket blob for service */
232- ceph_decode_8_safe(&p, end, is_enc, bad);
233- tp = ticket_buf;
234- if (is_enc) {
235- /* encrypted */
236- dout(" encrypted ticket\n");
237- dlen = ceph_x_decrypt(&old_key, &p, end, ticket_buf,
238- TEMP_TICKET_BUF_LEN);
239- if (dlen < 0) {
240- ret = dlen;
241- goto out;
242- }
243- dlen = ceph_decode_32(&tp);
244- } else {
245- /* unencrypted */
246- ceph_decode_32_safe(&p, end, dlen, bad);
247- ceph_decode_need(&p, end, dlen, bad);
248- ceph_decode_copy(&p, ticket_buf, dlen);
249- }
250- tpend = tp + dlen;
251- dout(" ticket blob is %d bytes\n", dlen);
252- ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad);
253- blob_struct_v = ceph_decode_8(&tp);
254- new_secret_id = ceph_decode_64(&tp);
255- ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend);
256+ while (num--) {
257+ ret = process_one_ticket(ac, secret, &p, end,
258+ dbuf, ticket_buf);
259 if (ret)
260 goto out;
261-
262- /* all is well, update our ticket */
263- ceph_crypto_key_destroy(&th->session_key);
264- if (th->ticket_blob)
265- ceph_buffer_put(th->ticket_blob);
266- th->session_key = new_session_key;
267- th->ticket_blob = new_ticket_blob;
268- th->validity = new_validity;
269- th->secret_id = new_secret_id;
270- th->expires = new_expires;
271- th->renew_after = new_renew_after;
272- dout(" got ticket service %d (%s) secret_id %lld len %d\n",
273- type, ceph_entity_type_name(type), th->secret_id,
274- (int)th->ticket_blob->vec.iov_len);
275- xi->have_keys |= th->service;
276 }
277
278 ret = 0;