Commit 5083cbcde0fd0596acd087cb2f4c338ae33b11ab

Authored by Ilya Dryomov
Committed by Greg Kroah-Hartman
1 parent b15481d2e9

libceph: add process_one_ticket() helper

commit 597cda357716a3cf8d994cb11927af917c8d71fa upstream.

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).

Signed-off-by: Ilya Dryomov <ilya.dryomov@inktank.com>
Reviewed-by: Sage Weil <sage@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Showing 1 changed file with 124 additions and 104 deletions Side-by-side Diff

... ... @@ -129,17 +129,131 @@
129 129 kfree(th);
130 130 }
131 131  
  132 +static 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 +
  239 +out:
  240 + return ret;
  241 +
  242 +bad:
  243 + ret = -EINVAL;
  244 + goto out;
  245 +}
  246 +
132 247 static int ceph_x_proc_ticket_reply(struct ceph_auth_client *ac,
133 248 struct ceph_crypto_key *secret,
134 249 void *buf, void *end)
135 250 {
136   - struct ceph_x_info *xi = ac->private;
137   - int num;
138 251 void *p = buf;
139   - int ret;
140 252 char *dbuf;
141 253 char *ticket_buf;
142 254 u8 reply_struct_v;
  255 + u32 num;
  256 + int ret;
143 257  
144 258 dbuf = kmalloc(TEMP_TICKET_BUF_LEN, GFP_NOFS);
145 259 if (!dbuf)
146 260  
147 261  
148 262  
149 263  
... ... @@ -150,112 +264,18 @@
150 264 if (!ticket_buf)
151 265 goto out_dbuf;
152 266  
153   - ceph_decode_need(&p, end, 1 + sizeof(u32), bad);
154   - reply_struct_v = ceph_decode_8(&p);
  267 + ceph_decode_8_safe(&p, end, reply_struct_v, bad);
155 268 if (reply_struct_v != 1)
156   - goto bad;
157   - num = ceph_decode_32(&p);
  269 + return -EINVAL;
  270 +
  271 + ceph_decode_32_safe(&p, end, num, bad);
158 272 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 273  
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   -
205   - memcpy(&old_key, &th->session_key, sizeof(old_key));
206   - ret = ceph_crypto_key_decode(&new_session_key, &dp, dend);
  274 + while (num--) {
  275 + ret = process_one_ticket(ac, secret, &p, end,
  276 + dbuf, ticket_buf);
207 277 if (ret)
208 278 goto out;
209   -
210   - ceph_decode_copy(&dp, &new_validity, sizeof(new_validity));
211   - ceph_decode_timespec(&validity, &new_validity);
212   - new_expires = get_seconds() + validity.tv_sec;
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)
243   - 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 281 ret = 0;