aboutsummaryrefslogtreecommitdiffstats
path: root/net/ceph
diff options
context:
space:
mode:
authorIlya Dryomov <ilya.dryomov@inktank.com>2014-09-08 09:25:34 -0400
committerIlya Dryomov <ilya.dryomov@inktank.com>2014-09-10 12:08:35 -0400
commit597cda357716a3cf8d994cb11927af917c8d71fa (patch)
treefaa59552d7eed73a1760aff65d03ef933df3be25 /net/ceph
parent73c3d4812b4c755efeca0140f606f83772a39ce4 (diff)
libceph: add process_one_ticket() helper
Add a helper for processing individual cephx auth tickets. Needed for the next commit, which 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> Reviewed-by: Sage Weil <sage@redhat.com>
Diffstat (limited to 'net/ceph')
-rw-r--r--net/ceph/auth_x.c228
1 files 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,
129 kfree(th); 129 kfree(th);
130} 130}
131 131
132static int process_one_ticket(struct ceph_auth_client *ac,
133 struct ceph_crypto_key *secret,
134 void **p, void *end,
135 void *dbuf, void *ticket_buf)
136{
137 struct ceph_x_info *xi = ac->private;
138 int type;
139 u8 tkt_struct_v, blob_struct_v;
140 struct ceph_x_ticket_handler *th;
141 void *dp, *dend;
142 int dlen;
143 char is_enc;
144 struct timespec validity;
145 struct ceph_crypto_key old_key;
146 void *tp, *tpend;
147 struct ceph_timespec new_validity;
148 struct ceph_crypto_key new_session_key;
149 struct ceph_buffer *new_ticket_blob;
150 unsigned long new_expires, new_renew_after;
151 u64 new_secret_id;
152 int ret;
153
154 ceph_decode_need(p, end, sizeof(u32) + 1, bad);
155
156 type = ceph_decode_32(p);
157 dout(" ticket type %d %s\n", type, ceph_entity_type_name(type));
158
159 tkt_struct_v = ceph_decode_8(p);
160 if (tkt_struct_v != 1)
161 goto bad;
162
163 th = get_ticket_handler(ac, type);
164 if (IS_ERR(th)) {
165 ret = PTR_ERR(th);
166 goto out;
167 }
168
169 /* blob for me */
170 dlen = ceph_x_decrypt(secret, p, end, dbuf,
171 TEMP_TICKET_BUF_LEN);
172 if (dlen <= 0) {
173 ret = dlen;
174 goto out;
175 }
176 dout(" decrypted %d bytes\n", dlen);
177 dp = dbuf;
178 dend = dp + dlen;
179
180 tkt_struct_v = ceph_decode_8(&dp);
181 if (tkt_struct_v != 1)
182 goto bad;
183
184 memcpy(&old_key, &th->session_key, sizeof(old_key));
185 ret = ceph_crypto_key_decode(&new_session_key, &dp, dend);
186 if (ret)
187 goto out;
188
189 ceph_decode_copy(&dp, &new_validity, sizeof(new_validity));
190 ceph_decode_timespec(&validity, &new_validity);
191 new_expires = get_seconds() + validity.tv_sec;
192 new_renew_after = new_expires - (validity.tv_sec / 4);
193 dout(" expires=%lu renew_after=%lu\n", new_expires,
194 new_renew_after);
195
196 /* ticket blob for service */
197 ceph_decode_8_safe(p, end, is_enc, bad);
198 tp = ticket_buf;
199 if (is_enc) {
200 /* encrypted */
201 dout(" encrypted ticket\n");
202 dlen = ceph_x_decrypt(&old_key, p, end, ticket_buf,
203 TEMP_TICKET_BUF_LEN);
204 if (dlen < 0) {
205 ret = dlen;
206 goto out;
207 }
208 dlen = ceph_decode_32(&tp);
209 } else {
210 /* unencrypted */
211 ceph_decode_32_safe(p, end, dlen, bad);
212 ceph_decode_need(p, end, dlen, bad);
213 ceph_decode_copy(p, ticket_buf, dlen);
214 }
215 tpend = tp + dlen;
216 dout(" ticket blob is %d bytes\n", dlen);
217 ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad);
218 blob_struct_v = ceph_decode_8(&tp);
219 new_secret_id = ceph_decode_64(&tp);
220 ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend);
221 if (ret)
222 goto out;
223
224 /* all is well, update our ticket */
225 ceph_crypto_key_destroy(&th->session_key);
226 if (th->ticket_blob)
227 ceph_buffer_put(th->ticket_blob);
228 th->session_key = new_session_key;
229 th->ticket_blob = new_ticket_blob;
230 th->validity = new_validity;
231 th->secret_id = new_secret_id;
232 th->expires = new_expires;
233 th->renew_after = new_renew_after;
234 dout(" got ticket service %d (%s) secret_id %lld len %d\n",
235 type, ceph_entity_type_name(type), th->secret_id,
236 (int)th->ticket_blob->vec.iov_len);
237 xi->have_keys |= th->service;
238
239out:
240 return ret;
241
242bad:
243 ret = -EINVAL;
244 goto out;
245}
246
132static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac, 247static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
133 struct ceph_crypto_key *secret, 248 struct ceph_crypto_key *secret,
134 void *buf, void *end) 249 void *buf, void *end)
135{ 250{
136 struct ceph_x_info *xi = ac->private;
137 int num;
138 void *p = buf; 251 void *p = buf;
139 int ret;
140 char *dbuf; 252 char *dbuf;
141 char *ticket_buf; 253 char *ticket_buf;
142 u8 reply_struct_v; 254 u8 reply_struct_v;
255 u32 num;
256 int ret;
143 257
144 dbuf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS); 258 dbuf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS);
145 if (!dbuf) 259 if (!dbuf)
@@ -150,112 +264,18 @@ static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
150 if (!ticket_buf) 264 if (!ticket_buf)
151 goto out_dbuf; 265 goto out_dbuf;
152 266
153 ceph_decode_need(&p, end, 1 + sizeof(u32), bad); 267 ceph_decode_8_safe(&p, end, reply_struct_v, bad);
154 reply_struct_v = ceph_decode_8(&p);
155 if (reply_struct_v != 1) 268 if (reply_struct_v != 1)
156 goto bad; 269 return -EINVAL;
157 num = ceph_decode_32(&p);
158 dout("%d tickets\n", num);
159 while (num--) {
160 int type;
161 u8 tkt_struct_v, blob_struct_v;
162 struct ceph_x_ticket_handler *th;
163 void *dp, *dend;
164 int dlen;
165 char is_enc;
166 struct timespec validity;
167 struct ceph_crypto_key old_key;
168 void *tp, *tpend;
169 struct ceph_timespec new_validity;
170 struct ceph_crypto_key new_session_key;
171 struct ceph_buffer *new_ticket_blob;
172 unsigned long new_expires, new_renew_after;
173 u64 new_secret_id;
174
175 ceph_decode_need(&p, end, sizeof(u32) + 1, bad);
176
177 type = ceph_decode_32(&p);
178 dout(" ticket type %d %s\n", type, ceph_entity_type_name(type));
179
180 tkt_struct_v = ceph_decode_8(&p);
181 if (tkt_struct_v != 1)
182 goto bad;
183
184 th = get_ticket_handler(ac, type);
185 if (IS_ERR(th)) {
186 ret = PTR_ERR(th);
187 goto out;
188 }
189
190 /* blob for me */
191 dlen = ceph_x_decrypt(secret, &p, end, dbuf,
192 TEMP_TICKET_BUF_LEN);
193 if (dlen <= 0) {
194 ret = dlen;
195 goto out;
196 }
197 dout(" decrypted %d bytes\n", dlen);
198 dend = dbuf + dlen;
199 dp = dbuf;
200
201 tkt_struct_v = ceph_decode_8(&dp);
202 if (tkt_struct_v != 1)
203 goto bad;
204 270
205 memcpy(&old_key, &th->session_key, sizeof(old_key)); 271 ceph_decode_32_safe(&p, end, num, bad);
206 ret = ceph_crypto_key_decode(&new_session_key, &dp, dend); 272 dout("%d tickets\n", num);
207 if (ret)
208 goto out;
209 273
210 ceph_decode_copy(&dp, &new_validity, sizeof(new_validity)); 274 while (num--) {
211 ceph_decode_timespec(&validity, &new_validity); 275 ret = process_one_ticket(ac, secret, &p, end,
212 new_expires = get_seconds() + validity.tv_sec; 276 dbuf, ticket_buf);
213 new_renew_after = new_expires - (validity.tv_sec / 4);
214 dout(" expires=%lu renew_after=%lu\n", new_expires,
215 new_renew_after);
216
217 /* ticket blob for service */
218 ceph_decode_8_safe(&p, end, is_enc, bad);
219 tp = ticket_buf;
220 if (is_enc) {
221 /* encrypted */
222 dout(" encrypted ticket\n");
223 dlen = ceph_x_decrypt(&old_key, &p, end, ticket_buf,
224 TEMP_TICKET_BUF_LEN);
225 if (dlen < 0) {
226 ret = dlen;
227 goto out;
228 }
229 dlen = ceph_decode_32(&tp);
230 } else {
231 /* unencrypted */
232 ceph_decode_32_safe(&p, end, dlen, bad);
233 ceph_decode_need(&p, end, dlen, bad);
234 ceph_decode_copy(&p, ticket_buf, dlen);
235 }
236 tpend = tp + dlen;
237 dout(" ticket blob is %d bytes\n", dlen);
238 ceph_decode_need(&tp, tpend, 1 + sizeof(u64), bad);
239 blob_struct_v = ceph_decode_8(&tp);
240 new_secret_id = ceph_decode_64(&tp);
241 ret = ceph_decode_buffer(&new_ticket_blob, &tp, tpend);
242 if (ret) 277 if (ret)
243 goto out; 278 goto out;
244
245 /* all is well, update our ticket */
246 ceph_crypto_key_destroy(&th->session_key);
247 if (th->ticket_blob)
248 ceph_buffer_put(th->ticket_blob);
249 th->session_key = new_session_key;
250 th->ticket_blob = new_ticket_blob;
251 th->validity = new_validity;
252 th->secret_id = new_secret_id;
253 th->expires = new_expires;
254 th->renew_after = new_renew_after;
255 dout(" got ticket service %d (%s) secret_id %lld len %d\n",
256 type, ceph_entity_type_name(type), th->secret_id,
257 (int)th->ticket_blob->vec.iov_len);
258 xi->have_keys |= th->service;
259 } 279 }
260 280
261 ret = 0; 281 ret = 0;