source: branches/samba-3.5.x/source4/heimdal/lib/krb5/ticket.c

Last change on this file was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

File size: 20.3 KB
Line 
1/*
2 * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "krb5_locl.h"
35
36krb5_error_code KRB5_LIB_FUNCTION
37krb5_free_ticket(krb5_context context,
38 krb5_ticket *ticket)
39{
40 free_EncTicketPart(&ticket->ticket);
41 krb5_free_principal(context, ticket->client);
42 krb5_free_principal(context, ticket->server);
43 free(ticket);
44 return 0;
45}
46
47krb5_error_code KRB5_LIB_FUNCTION
48krb5_copy_ticket(krb5_context context,
49 const krb5_ticket *from,
50 krb5_ticket **to)
51{
52 krb5_error_code ret;
53 krb5_ticket *tmp;
54
55 *to = NULL;
56 tmp = malloc(sizeof(*tmp));
57 if(tmp == NULL) {
58 krb5_set_error_message(context, ENOMEM,
59 N_("malloc: out of memory", ""));
60 return ENOMEM;
61 }
62 if((ret = copy_EncTicketPart(&from->ticket, &tmp->ticket))){
63 free(tmp);
64 return ret;
65 }
66 ret = krb5_copy_principal(context, from->client, &tmp->client);
67 if(ret){
68 free_EncTicketPart(&tmp->ticket);
69 free(tmp);
70 return ret;
71 }
72 ret = krb5_copy_principal(context, from->server, &tmp->server);
73 if(ret){
74 krb5_free_principal(context, tmp->client);
75 free_EncTicketPart(&tmp->ticket);
76 free(tmp);
77 return ret;
78 }
79 *to = tmp;
80 return 0;
81}
82
83krb5_error_code KRB5_LIB_FUNCTION
84krb5_ticket_get_client(krb5_context context,
85 const krb5_ticket *ticket,
86 krb5_principal *client)
87{
88 return krb5_copy_principal(context, ticket->client, client);
89}
90
91krb5_error_code KRB5_LIB_FUNCTION
92krb5_ticket_get_server(krb5_context context,
93 const krb5_ticket *ticket,
94 krb5_principal *server)
95{
96 return krb5_copy_principal(context, ticket->server, server);
97}
98
99time_t KRB5_LIB_FUNCTION
100krb5_ticket_get_endtime(krb5_context context,
101 const krb5_ticket *ticket)
102{
103 return ticket->ticket.endtime;
104}
105
106/**
107 * Get the flags from the Kerberos ticket
108 *
109 * @param context Kerberos context
110 * @param ticket Kerberos ticket
111 *
112 * @return ticket flags
113 *
114 * @ingroup krb5_ticket
115 */
116unsigned long
117krb5_ticket_get_flags(krb5_context context,
118 const krb5_ticket *ticket)
119{
120 return TicketFlags2int(ticket->ticket.flags);
121}
122
123static int
124find_type_in_ad(krb5_context context,
125 int type,
126 krb5_data *data,
127 krb5_boolean *found,
128 krb5_boolean failp,
129 krb5_keyblock *sessionkey,
130 const AuthorizationData *ad,
131 int level)
132{
133 krb5_error_code ret = 0;
134 int i;
135
136 if (level > 9) {
137 ret = ENOENT; /* XXX */
138 krb5_set_error_message(context, ret,
139 N_("Authorization data nested deeper "
140 "then %d levels, stop searching", ""),
141 level);
142 goto out;
143 }
144
145 /*
146 * Only copy out the element the first time we get to it, we need
147 * to run over the whole authorization data fields to check if
148 * there are any container clases we need to care about.
149 */
150 for (i = 0; i < ad->len; i++) {
151 if (!*found && ad->val[i].ad_type == type) {
152 ret = der_copy_octet_string(&ad->val[i].ad_data, data);
153 if (ret) {
154 krb5_set_error_message(context, ret,
155 N_("malloc: out of memory", ""));
156 goto out;
157 }
158 *found = TRUE;
159 continue;
160 }
161 switch (ad->val[i].ad_type) {
162 case KRB5_AUTHDATA_IF_RELEVANT: {
163 AuthorizationData child;
164 ret = decode_AuthorizationData(ad->val[i].ad_data.data,
165 ad->val[i].ad_data.length,
166 &child,
167 NULL);
168 if (ret) {
169 krb5_set_error_message(context, ret,
170 N_("Failed to decode "
171 "IF_RELEVANT with %d", ""),
172 (int)ret);
173 goto out;
174 }
175 ret = find_type_in_ad(context, type, data, found, FALSE,
176 sessionkey, &child, level + 1);
177 free_AuthorizationData(&child);
178 if (ret)
179 goto out;
180 break;
181 }
182#if 0 /* XXX test */
183 case KRB5_AUTHDATA_KDC_ISSUED: {
184 AD_KDCIssued child;
185
186 ret = decode_AD_KDCIssued(ad->val[i].ad_data.data,
187 ad->val[i].ad_data.length,
188 &child,
189 NULL);
190 if (ret) {
191 krb5_set_error_message(context, ret,
192 N_("Failed to decode "
193 "AD_KDCIssued with %d", ""),
194 ret);
195 goto out;
196 }
197 if (failp) {
198 krb5_boolean valid;
199 krb5_data buf;
200 size_t len;
201
202 ASN1_MALLOC_ENCODE(AuthorizationData, buf.data, buf.length,
203 &child.elements, &len, ret);
204 if (ret) {
205 free_AD_KDCIssued(&child);
206 krb5_clear_error_message(context);
207 goto out;
208 }
209 if(buf.length != len)
210 krb5_abortx(context, "internal error in ASN.1 encoder");
211
212 ret = krb5_c_verify_checksum(context, sessionkey, 19, &buf,
213 &child.ad_checksum, &valid);
214 krb5_data_free(&buf);
215 if (ret) {
216 free_AD_KDCIssued(&child);
217 goto out;
218 }
219 if (!valid) {
220 krb5_clear_error_message(context);
221 ret = ENOENT;
222 free_AD_KDCIssued(&child);
223 goto out;
224 }
225 }
226 ret = find_type_in_ad(context, type, data, found, failp, sessionkey,
227 &child.elements, level + 1);
228 free_AD_KDCIssued(&child);
229 if (ret)
230 goto out;
231 break;
232 }
233#endif
234 case KRB5_AUTHDATA_AND_OR:
235 if (!failp)
236 break;
237 ret = ENOENT; /* XXX */
238 krb5_set_error_message(context, ret,
239 N_("Authorization data contains "
240 "AND-OR element that is unknown to the "
241 "application", ""));
242 goto out;
243 default:
244 if (!failp)
245 break;
246 ret = ENOENT; /* XXX */
247 krb5_set_error_message(context, ret,
248 N_("Authorization data contains "
249 "unknown type (%d) ", ""),
250 ad->val[i].ad_type);
251 goto out;
252 }
253 }
254out:
255 if (ret) {
256 if (*found) {
257 krb5_data_free(data);
258 *found = 0;
259 }
260 }
261 return ret;
262}
263
264/*
265 * Extract the authorization data type of `type' from the
266 * 'ticket'. Store the field in `data'. This function is to use for
267 * kerberos applications.
268 */
269
270krb5_error_code KRB5_LIB_FUNCTION
271krb5_ticket_get_authorization_data_type(krb5_context context,
272 krb5_ticket *ticket,
273 int type,
274 krb5_data *data)
275{
276 AuthorizationData *ad;
277 krb5_error_code ret;
278 krb5_boolean found = FALSE;
279
280 krb5_data_zero(data);
281
282 ad = ticket->ticket.authorization_data;
283 if (ticket->ticket.authorization_data == NULL) {
284 krb5_set_error_message(context, ENOENT,
285 N_("Ticket have not authorization data", ""));
286 return ENOENT; /* XXX */
287 }
288
289 ret = find_type_in_ad(context, type, data, &found, TRUE,
290 &ticket->ticket.key, ad, 0);
291 if (ret)
292 return ret;
293 if (!found) {
294 krb5_set_error_message(context, ENOENT,
295 N_("Ticket have not "
296 "authorization data of type %d", ""),
297 type);
298 return ENOENT; /* XXX */
299 }
300 return 0;
301}
302
303static krb5_error_code
304check_server_referral(krb5_context context,
305 krb5_kdc_rep *rep,
306 unsigned flags,
307 krb5_const_principal requested,
308 krb5_const_principal returned,
309 krb5_keyblock * key)
310{
311 krb5_error_code ret;
312 PA_ServerReferralData ref;
313 krb5_crypto session;
314 EncryptedData ed;
315 size_t len;
316 krb5_data data;
317 PA_DATA *pa;
318 int i = 0, cmp;
319
320 if (rep->kdc_rep.padata == NULL)
321 goto noreferral;
322
323 pa = krb5_find_padata(rep->kdc_rep.padata->val,
324 rep->kdc_rep.padata->len,
325 KRB5_PADATA_SERVER_REFERRAL, &i);
326 if (pa == NULL)
327 goto noreferral;
328
329 memset(&ed, 0, sizeof(ed));
330 memset(&ref, 0, sizeof(ref));
331
332 ret = decode_EncryptedData(pa->padata_value.data,
333 pa->padata_value.length,
334 &ed, &len);
335 if (ret)
336 return ret;
337 if (len != pa->padata_value.length) {
338 free_EncryptedData(&ed);
339 krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
340 N_("Referral EncryptedData wrong for realm %s",
341 "realm"), requested->realm);
342 return KRB5KRB_AP_ERR_MODIFIED;
343 }
344
345 ret = krb5_crypto_init(context, key, 0, &session);
346 if (ret) {
347 free_EncryptedData(&ed);
348 return ret;
349 }
350
351 ret = krb5_decrypt_EncryptedData(context, session,
352 KRB5_KU_PA_SERVER_REFERRAL,
353 &ed, &data);
354 free_EncryptedData(&ed);
355 krb5_crypto_destroy(context, session);
356 if (ret)
357 return ret;
358
359 ret = decode_PA_ServerReferralData(data.data, data.length, &ref, &len);
360 if (ret) {
361 krb5_data_free(&data);
362 return ret;
363 }
364 krb5_data_free(&data);
365
366 if (strcmp(requested->realm, returned->realm) != 0) {
367 free_PA_ServerReferralData(&ref);
368 krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
369 N_("server ref realm mismatch, "
370 "requested realm %s got back %s", ""),
371 requested->realm, returned->realm);
372 return KRB5KRB_AP_ERR_MODIFIED;
373 }
374
375 if (returned->name.name_string.len == 2 &&
376 strcmp(returned->name.name_string.val[0], KRB5_TGS_NAME) == 0)
377 {
378 const char *realm = returned->name.name_string.val[1];
379
380 if (ref.referred_realm == NULL
381 || strcmp(*ref.referred_realm, realm) != 0)
382 {
383 free_PA_ServerReferralData(&ref);
384 krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
385 N_("tgt returned with wrong ref", ""));
386 return KRB5KRB_AP_ERR_MODIFIED;
387 }
388 } else if (krb5_principal_compare(context, returned, requested) == 0) {
389 free_PA_ServerReferralData(&ref);
390 krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
391 N_("req princ no same as returned", ""));
392 return KRB5KRB_AP_ERR_MODIFIED;
393 }
394
395 if (ref.requested_principal_name) {
396 cmp = _krb5_principal_compare_PrincipalName(context,
397 requested,
398 ref.requested_principal_name);
399 if (!cmp) {
400 free_PA_ServerReferralData(&ref);
401 krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
402 N_("referred principal not same "
403 "as requested", ""));
404 return KRB5KRB_AP_ERR_MODIFIED;
405 }
406 } else if (flags & EXTRACT_TICKET_AS_REQ) {
407 free_PA_ServerReferralData(&ref);
408 krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
409 N_("Requested principal missing on AS-REQ", ""));
410 return KRB5KRB_AP_ERR_MODIFIED;
411 }
412
413 free_PA_ServerReferralData(&ref);
414
415 return ret;
416noreferral:
417 if (krb5_principal_compare(context, requested, returned) == FALSE) {
418 krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
419 N_("Not same server principal returned "
420 "as requested", ""));
421 return KRB5KRB_AP_ERR_MODIFIED;
422 }
423 return 0;
424}
425
426
427/*
428 * Verify referral data
429 */
430
431
432static krb5_error_code
433check_client_referral(krb5_context context,
434 krb5_kdc_rep *rep,
435 krb5_const_principal requested,
436 krb5_const_principal mapped,
437 krb5_keyblock const * key)
438{
439 krb5_error_code ret;
440 PA_ClientCanonicalized canon;
441 krb5_crypto crypto;
442 krb5_data data;
443 PA_DATA *pa;
444 size_t len;
445 int i = 0;
446
447 if (rep->kdc_rep.padata == NULL)
448 goto noreferral;
449
450 pa = krb5_find_padata(rep->kdc_rep.padata->val,
451 rep->kdc_rep.padata->len,
452 KRB5_PADATA_CLIENT_CANONICALIZED, &i);
453 if (pa == NULL)
454 goto noreferral;
455
456 ret = decode_PA_ClientCanonicalized(pa->padata_value.data,
457 pa->padata_value.length,
458 &canon, &len);
459 if (ret) {
460 krb5_set_error_message(context, ret,
461 N_("Failed to decode ClientCanonicalized "
462 "from realm %s", ""), requested->realm);
463 return ret;
464 }
465
466 ASN1_MALLOC_ENCODE(PA_ClientCanonicalizedNames, data.data, data.length,
467 &canon.names, &len, ret);
468 if (ret) {
469 free_PA_ClientCanonicalized(&canon);
470 return ret;
471 }
472 if (data.length != len)
473 krb5_abortx(context, "internal asn.1 error");
474
475 ret = krb5_crypto_init(context, key, 0, &crypto);
476 if (ret) {
477 free(data.data);
478 free_PA_ClientCanonicalized(&canon);
479 return ret;
480 }
481
482 ret = krb5_verify_checksum(context, crypto, KRB5_KU_CANONICALIZED_NAMES,
483 data.data, data.length,
484 &canon.canon_checksum);
485 krb5_crypto_destroy(context, crypto);
486 free(data.data);
487 if (ret) {
488 krb5_set_error_message(context, ret,
489 N_("Failed to verify client canonicalized "
490 "data from realm %s", ""),
491 requested->realm);
492 free_PA_ClientCanonicalized(&canon);
493 return ret;
494 }
495
496 if (!_krb5_principal_compare_PrincipalName(context,
497 requested,
498 &canon.names.requested_name))
499 {
500 free_PA_ClientCanonicalized(&canon);
501 krb5_set_error_message(context, KRB5_PRINC_NOMATCH,
502 N_("Requested name doesn't match"
503 " in client referral", ""));
504 return KRB5_PRINC_NOMATCH;
505 }
506 if (!_krb5_principal_compare_PrincipalName(context,
507 mapped,
508 &canon.names.mapped_name))
509 {
510 free_PA_ClientCanonicalized(&canon);
511 krb5_set_error_message(context, KRB5_PRINC_NOMATCH,
512 N_("Mapped name doesn't match"
513 " in client referral", ""));
514 return KRB5_PRINC_NOMATCH;
515 }
516
517 return 0;
518
519noreferral:
520 if (krb5_principal_compare(context, requested, mapped) == FALSE) {
521 krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
522 N_("Not same client principal returned "
523 "as requested", ""));
524 return KRB5KRB_AP_ERR_MODIFIED;
525 }
526 return 0;
527}
528
529
530static krb5_error_code
531decrypt_tkt (krb5_context context,
532 krb5_keyblock *key,
533 krb5_key_usage usage,
534 krb5_const_pointer decrypt_arg,
535 krb5_kdc_rep *dec_rep)
536{
537 krb5_error_code ret;
538 krb5_data data;
539 size_t size;
540 krb5_crypto crypto;
541
542 ret = krb5_crypto_init(context, key, 0, &crypto);
543 if (ret)
544 return ret;
545
546 ret = krb5_decrypt_EncryptedData (context,
547 crypto,
548 usage,
549 &dec_rep->kdc_rep.enc_part,
550 &data);
551 krb5_crypto_destroy(context, crypto);
552
553 if (ret)
554 return ret;
555
556 ret = decode_EncASRepPart(data.data,
557 data.length,
558 &dec_rep->enc_part,
559 &size);
560 if (ret)
561 ret = decode_EncTGSRepPart(data.data,
562 data.length,
563 &dec_rep->enc_part,
564 &size);
565 krb5_data_free (&data);
566 if (ret) {
567 krb5_set_error_message(context, ret,
568 N_("Failed to decode encpart in ticket", ""));
569 return ret;
570 }
571 return 0;
572}
573
574int
575_krb5_extract_ticket(krb5_context context,
576 krb5_kdc_rep *rep,
577 krb5_creds *creds,
578 krb5_keyblock *key,
579 krb5_const_pointer keyseed,
580 krb5_key_usage key_usage,
581 krb5_addresses *addrs,
582 unsigned nonce,
583 unsigned flags,
584 krb5_decrypt_proc decrypt_proc,
585 krb5_const_pointer decryptarg)
586{
587 krb5_error_code ret;
588 krb5_principal tmp_principal;
589 size_t len;
590 time_t tmp_time;
591 krb5_timestamp sec_now;
592
593 /* decrypt */
594
595 if (decrypt_proc == NULL)
596 decrypt_proc = decrypt_tkt;
597
598 ret = (*decrypt_proc)(context, key, key_usage, decryptarg, rep);
599 if (ret)
600 goto out;
601
602 /* save session key */
603
604 creds->session.keyvalue.length = 0;
605 creds->session.keyvalue.data = NULL;
606 creds->session.keytype = rep->enc_part.key.keytype;
607 ret = krb5_data_copy (&creds->session.keyvalue,
608 rep->enc_part.key.keyvalue.data,
609 rep->enc_part.key.keyvalue.length);
610 if (ret) {
611 krb5_clear_error_message(context);
612 goto out;
613 }
614
615 /*
616 * HACK:
617 * this is really a ugly hack, to support using the Netbios Domain Name
618 * as realm against windows KDC's, they always return the full realm
619 * based on the DNS Name.
620 */
621 flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH;
622 flags |= EXTRACT_TICKET_ALLOW_CNAME_MISMATCH;
623
624 /* compare client and save */
625 ret = _krb5_principalname2krb5_principal (context,
626 &tmp_principal,
627 rep->kdc_rep.cname,
628 rep->kdc_rep.crealm);
629 if (ret)
630 goto out;
631
632 /* check client referral and save principal */
633 /* anonymous here ? */
634 if((flags & EXTRACT_TICKET_ALLOW_CNAME_MISMATCH) == 0) {
635 ret = check_client_referral(context, rep,
636 creds->client,
637 tmp_principal,
638 &creds->session);
639 if (ret) {
640 krb5_free_principal (context, tmp_principal);
641 goto out;
642 }
643 }
644 krb5_free_principal (context, creds->client);
645 creds->client = tmp_principal;
646
647 /* check server referral and save principal */
648 ret = _krb5_principalname2krb5_principal (context,
649 &tmp_principal,
650 rep->kdc_rep.ticket.sname,
651 rep->kdc_rep.ticket.realm);
652 if (ret)
653 goto out;
654 if((flags & EXTRACT_TICKET_ALLOW_SERVER_MISMATCH) == 0){
655 ret = check_server_referral(context,
656 rep,
657 flags,
658 creds->server,
659 tmp_principal,
660 &creds->session);
661 if (ret) {
662 krb5_free_principal (context, tmp_principal);
663 goto out;
664 }
665 }
666 krb5_free_principal(context, creds->server);
667 creds->server = tmp_principal;
668
669 /* verify names */
670 if(flags & EXTRACT_TICKET_MATCH_REALM){
671 const char *srealm = krb5_principal_get_realm(context, creds->server);
672 const char *crealm = krb5_principal_get_realm(context, creds->client);
673
674 if (strcmp(rep->enc_part.srealm, srealm) != 0 ||
675 strcmp(rep->enc_part.srealm, crealm) != 0)
676 {
677 ret = KRB5KRB_AP_ERR_MODIFIED;
678 krb5_clear_error_message(context);
679 goto out;
680 }
681 }
682
683 /* compare nonces */
684
685 if (nonce != rep->enc_part.nonce) {
686 ret = KRB5KRB_AP_ERR_MODIFIED;
687 krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
688 goto out;
689 }
690
691 /* set kdc-offset */
692
693 krb5_timeofday (context, &sec_now);
694 if (rep->enc_part.flags.initial
695 && context->kdc_sec_offset == 0
696 && krb5_config_get_bool (context, NULL,
697 "libdefaults",
698 "kdc_timesync",
699 NULL)) {
700 context->kdc_sec_offset = rep->enc_part.authtime - sec_now;
701 krb5_timeofday (context, &sec_now);
702 }
703
704 /* check all times */
705
706 if (rep->enc_part.starttime) {
707 tmp_time = *rep->enc_part.starttime;
708 } else
709 tmp_time = rep->enc_part.authtime;
710
711 if (creds->times.starttime == 0
712 && abs(tmp_time - sec_now) > context->max_skew) {
713 ret = KRB5KRB_AP_ERR_SKEW;
714 krb5_set_error_message (context, ret,
715 N_("time skew (%d) larger than max (%d)", ""),
716 abs(tmp_time - sec_now),
717 (int)context->max_skew);
718 goto out;
719 }
720
721 if (creds->times.starttime != 0
722 && tmp_time != creds->times.starttime) {
723 krb5_clear_error_message (context);
724 ret = KRB5KRB_AP_ERR_MODIFIED;
725 goto out;
726 }
727
728 creds->times.starttime = tmp_time;
729
730 if (rep->enc_part.renew_till) {
731 tmp_time = *rep->enc_part.renew_till;
732 } else
733 tmp_time = 0;
734
735 if (creds->times.renew_till != 0
736 && tmp_time > creds->times.renew_till) {
737 krb5_clear_error_message (context);
738 ret = KRB5KRB_AP_ERR_MODIFIED;
739 goto out;
740 }
741
742 creds->times.renew_till = tmp_time;
743
744 creds->times.authtime = rep->enc_part.authtime;
745
746 if (creds->times.endtime != 0
747 && rep->enc_part.endtime > creds->times.endtime) {
748 krb5_clear_error_message (context);
749 ret = KRB5KRB_AP_ERR_MODIFIED;
750 goto out;
751 }
752
753 creds->times.endtime = rep->enc_part.endtime;
754
755 if(rep->enc_part.caddr)
756 krb5_copy_addresses (context, rep->enc_part.caddr, &creds->addresses);
757 else if(addrs)
758 krb5_copy_addresses (context, addrs, &creds->addresses);
759 else {
760 creds->addresses.len = 0;
761 creds->addresses.val = NULL;
762 }
763 creds->flags.b = rep->enc_part.flags;
764
765 creds->authdata.len = 0;
766 creds->authdata.val = NULL;
767
768 /* extract ticket */
769 ASN1_MALLOC_ENCODE(Ticket, creds->ticket.data, creds->ticket.length,
770 &rep->kdc_rep.ticket, &len, ret);
771 if(ret)
772 goto out;
773 if (creds->ticket.length != len)
774 krb5_abortx(context, "internal error in ASN.1 encoder");
775 creds->second_ticket.length = 0;
776 creds->second_ticket.data = NULL;
777
778
779out:
780 memset (rep->enc_part.key.keyvalue.data, 0,
781 rep->enc_part.key.keyvalue.length);
782 return ret;
783}
Note: See TracBrowser for help on using the repository browser.