2 * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
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
34 #include "krb5_locl.h"
36 #include "krb5-v4compat.h"
38 #ifndef HEIMDAL_SMALLER
44 #define RCHECK(r,func,label) \
45 do { (r) = func ; if (r) goto label; } while(0);
48 /* include this here, to avoid dependencies on libkrb */
50 static const int _tkt_lifetimes
[TKTLIFENUMFIXED
] = {
51 38400, 41055, 43894, 46929, 50174, 53643, 57352, 61318,
52 65558, 70091, 74937, 80119, 85658, 91581, 97914, 104684,
53 111922, 119661, 127935, 136781, 146239, 156350, 167161, 178720,
54 191077, 204289, 218415, 233517, 249664, 266926, 285383, 305116,
55 326213, 348769, 372885, 398668, 426234, 455705, 487215, 520904,
56 556921, 595430, 636601, 680618, 727680, 777995, 831789, 889303,
57 950794, 1016537, 1086825, 1161973, 1242318, 1328218, 1420057, 1518247,
58 1623226, 1735464, 1855462, 1983758, 2120925, 2267576, 2424367, 2592000
62 _krb5_krb_time_to_life(time_t start
, time_t end
)
65 time_t life
= end
- start
;
67 if (life
> MAXTKTLIFETIME
|| life
<= 0)
70 if (krb_no_long_lifetimes
)
71 return (life
+ 5*60 - 1)/(5*60);
75 return TKTLIFENOEXPIRE
;
76 if (life
< _tkt_lifetimes
[0])
77 return (life
+ 5*60 - 1)/(5*60);
78 for (i
=0; i
<TKTLIFENUMFIXED
; i
++)
79 if (life
<= _tkt_lifetimes
[i
])
80 return i
+ TKTLIFEMINFIXED
;
85 time_t KRB5_LIB_FUNCTION
86 _krb5_krb_life_to_time(int start
, int life_
)
88 unsigned char life
= (unsigned char) life_
;
91 if (krb_no_long_lifetimes
)
92 return start
+ life
*5*60;
95 if (life
== TKTLIFENOEXPIRE
)
97 if (life
< TKTLIFEMINFIXED
)
98 return start
+ life
*5*60;
99 if (life
> TKTLIFEMAXFIXED
)
100 return start
+ MAXTKTLIFETIME
;
101 return start
+ _tkt_lifetimes
[life
- TKTLIFEMINFIXED
];
105 * Get the name of the krb4 credentials cache, will use `tkfile' as
106 * the name if that is passed in. `cc' must be free()ed by caller,
109 static krb5_error_code
110 get_krb4_cc_name(const char *tkfile
, char **cc
)
117 path
= getenv("KRBTKFILE");
122 if (asprintf(cc
, "%s%u", TKT_ROOT
, (unsigned)getuid()) < 0)
125 *cc
= strdup(tkfile
);
133 * Write a Kerberos 4 ticket file
136 #define KRB5_TF_LCK_RETRY_COUNT 50
137 #define KRB5_TF_LCK_RETRY 1
139 static krb5_error_code
140 write_v4_cc(krb5_context context
, const char *tkfile
,
141 krb5_storage
*sp
, int append
)
149 ret
= get_krb4_cc_name(tkfile
, &path
);
151 krb5_set_error_message(context
, ret
,
152 N_("Failed getting the krb4 credentials "
157 fd
= open(path
, O_WRONLY
|O_CREAT
, 0600);
160 krb5_set_error_message(context
, ret
,
161 N_("Failed opening krb4 credential cache "
162 "%s: %s", "path, error"),
163 path
, strerror(ret
));
169 if (fstat(fd
, &sb
) != 0 || !S_ISREG(sb
.st_mode
)) {
170 krb5_set_error_message(context
, ret
,
171 N_("krb4 credential cache %s is not a file", ""),
175 return KRB5_FCC_PERM
;
178 for (i
= 0; i
< KRB5_TF_LCK_RETRY_COUNT
; i
++) {
179 if (flock(fd
, LOCK_EX
| LOCK_NB
) < 0) {
180 sleep(KRB5_TF_LCK_RETRY
);
184 if (i
== KRB5_TF_LCK_RETRY_COUNT
) {
185 krb5_set_error_message(context
, KRB5_FCC_PERM
,
186 N_("Failed to lock credentail cache %s", ""),
190 return KRB5_FCC_PERM
;
194 ret
= ftruncate(fd
, 0);
197 krb5_set_error_message(context
, KRB5_FCC_PERM
,
198 N_("Failed to truncate krb4 cc %s", ""),
202 return KRB5_FCC_PERM
;
205 ret
= lseek(fd
, 0L, SEEK_END
);
214 krb5_storage_to_data(sp
, &data
);
216 ret
= write(fd
, data
.data
, data
.length
);
217 if (ret
!= data
.length
)
222 krb5_data_free(&data
);
235 krb5_error_code KRB5_LIB_FUNCTION
236 _krb5_krb_tf_setup(krb5_context context
,
237 struct credentials
*v4creds
,
244 sp
= krb5_storage_emem();
248 krb5_storage_set_byteorder(sp
, KRB5_STORAGE_BYTEORDER_HOST
);
249 krb5_storage_set_eof_code(sp
, KRB5_CC_IO
);
251 krb5_clear_error_message(context
);
254 RCHECK(ret
, krb5_store_stringz(sp
, v4creds
->pname
), error
);
255 RCHECK(ret
, krb5_store_stringz(sp
, v4creds
->pinst
), error
);
259 RCHECK(ret
, krb5_store_stringz(sp
, v4creds
->service
), error
);
260 RCHECK(ret
, krb5_store_stringz(sp
, v4creds
->instance
), error
);
261 RCHECK(ret
, krb5_store_stringz(sp
, v4creds
->realm
), error
);
262 ret
= krb5_storage_write(sp
, v4creds
->session
, 8);
267 RCHECK(ret
, krb5_store_int32(sp
, v4creds
->lifetime
), error
);
268 RCHECK(ret
, krb5_store_int32(sp
, v4creds
->kvno
), error
);
269 RCHECK(ret
, krb5_store_int32(sp
, v4creds
->ticket_st
.length
), error
);
271 ret
= krb5_storage_write(sp
, v4creds
->ticket_st
.dat
,
272 v4creds
->ticket_st
.length
);
273 if (ret
!= v4creds
->ticket_st
.length
) {
277 RCHECK(ret
, krb5_store_int32(sp
, v4creds
->issue_date
), error
);
279 ret
= write_v4_cc(context
, tkfile
, sp
, append
);
282 krb5_storage_free(sp
);
291 krb5_error_code KRB5_LIB_FUNCTION
292 _krb5_krb_dest_tkt(krb5_context context
, const char *tkfile
)
297 ret
= get_krb4_cc_name(tkfile
, &path
);
299 krb5_set_error_message(context
, ret
,
300 N_("Failed getting the krb4 credentials "
305 if (unlink(path
) < 0) {
307 krb5_set_error_message(context
, ret
,
308 N_("Failed removing the cache %s "
309 "with error %s", "path, error"),
310 path
, strerror(ret
));
321 static krb5_error_code
322 decrypt_etext(krb5_context context
, const krb5_keyblock
*key
,
323 const krb5_data
*cdata
, krb5_data
*data
)
328 ret
= krb5_crypto_init(context
, key
, ETYPE_DES_PCBC_NONE
, &crypto
);
332 ret
= krb5_decrypt(context
, crypto
, 0, cdata
->data
, cdata
->length
, data
);
333 krb5_crypto_destroy(context
, crypto
);
343 static const char eightzeros
[8] = "\x00\x00\x00\x00\x00\x00\x00\x00";
345 static krb5_error_code
346 storage_to_etext(krb5_context context
,
348 const krb5_keyblock
*key
,
356 /* multiple of eight bytes, don't round up */
358 size
= krb5_storage_seek(sp
, 0, SEEK_END
);
360 return KRB4ET_RD_AP_UNDEC
;
361 size
= ((size
+7) & ~7) - size
;
363 ret
= krb5_storage_write(sp
, eightzeros
, size
);
365 return KRB4ET_RD_AP_UNDEC
;
367 ret
= krb5_storage_to_data(sp
, &data
);
371 ret
= krb5_crypto_init(context
, key
, ETYPE_DES_PCBC_NONE
, &crypto
);
373 krb5_data_free(&data
);
377 ret
= krb5_encrypt(context
, crypto
, 0, data
.data
, data
.length
, enc_data
);
379 krb5_data_free(&data
);
380 krb5_crypto_destroy(context
, crypto
);
389 static krb5_error_code
390 put_nir(krb5_storage
*sp
, const char *name
,
391 const char *instance
, const char *realm
)
395 RCHECK(ret
, krb5_store_stringz(sp
, name
), error
);
396 RCHECK(ret
, krb5_store_stringz(sp
, instance
), error
);
398 RCHECK(ret
, krb5_store_stringz(sp
, realm
), error
);
408 krb5_error_code KRB5_LIB_FUNCTION
409 _krb5_krb_create_ticket(krb5_context context
,
412 const char *pinstance
,
415 const krb5_keyblock
*session
,
419 const char *sinstance
,
420 const krb5_keyblock
*key
,
426 krb5_data_zero(enc_data
);
428 sp
= krb5_storage_emem();
430 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
433 krb5_storage_set_byteorder(sp
, KRB5_STORAGE_BYTEORDER_BE
);
435 RCHECK(ret
, krb5_store_int8(sp
, flags
), error
);
436 RCHECK(ret
, put_nir(sp
, pname
, pinstance
, prealm
), error
);
437 RCHECK(ret
, krb5_store_int32(sp
, ntohl(paddress
)), error
);
440 ret
= krb5_storage_write(sp
,
441 session
->keyvalue
.data
,
442 session
->keyvalue
.length
);
443 if (ret
!= session
->keyvalue
.length
) {
444 ret
= KRB4ET_INTK_PROT
;
448 RCHECK(ret
, krb5_store_int8(sp
, life
), error
);
449 RCHECK(ret
, krb5_store_int32(sp
, life_sec
), error
);
450 RCHECK(ret
, put_nir(sp
, sname
, sinstance
, NULL
), error
);
452 ret
= storage_to_etext(context
, sp
, key
, enc_data
);
455 krb5_storage_free(sp
);
457 krb5_set_error_message(context
, ret
,
458 N_("Failed to encode kerberos 4 ticket", ""));
467 krb5_error_code KRB5_LIB_FUNCTION
468 _krb5_krb_create_ciph(krb5_context context
,
469 const krb5_keyblock
*session
,
471 const char *instance
,
475 const krb5_data
*ticket
,
477 const krb5_keyblock
*key
,
483 krb5_data_zero(enc_data
);
485 sp
= krb5_storage_emem();
487 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
490 krb5_storage_set_byteorder(sp
, KRB5_STORAGE_BYTEORDER_BE
);
493 ret
= krb5_storage_write(sp
,
494 session
->keyvalue
.data
,
495 session
->keyvalue
.length
);
496 if (ret
!= session
->keyvalue
.length
) {
497 ret
= KRB4ET_INTK_PROT
;
501 RCHECK(ret
, put_nir(sp
, service
, instance
, realm
), error
);
502 RCHECK(ret
, krb5_store_int8(sp
, life
), error
);
503 RCHECK(ret
, krb5_store_int8(sp
, kvno
), error
);
504 RCHECK(ret
, krb5_store_int8(sp
, ticket
->length
), error
);
505 ret
= krb5_storage_write(sp
, ticket
->data
, ticket
->length
);
506 if (ret
!= ticket
->length
) {
507 ret
= KRB4ET_INTK_PROT
;
510 RCHECK(ret
, krb5_store_int32(sp
, kdc_time
), error
);
512 ret
= storage_to_etext(context
, sp
, key
, enc_data
);
515 krb5_storage_free(sp
);
517 krb5_set_error_message(context
, ret
,
518 N_("Failed to encode kerberos 4 ticket", ""));
527 krb5_error_code KRB5_LIB_FUNCTION
528 _krb5_krb_create_auth_reply(krb5_context context
,
536 const krb5_data
*cipher
,
542 krb5_data_zero(data
);
544 sp
= krb5_storage_emem();
546 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
549 krb5_storage_set_byteorder(sp
, KRB5_STORAGE_BYTEORDER_BE
);
551 RCHECK(ret
, krb5_store_int8(sp
, KRB_PROT_VERSION
), error
);
552 RCHECK(ret
, krb5_store_int8(sp
, AUTH_MSG_KDC_REPLY
), error
);
553 RCHECK(ret
, put_nir(sp
, pname
, pinst
, prealm
), error
);
554 RCHECK(ret
, krb5_store_int32(sp
, time_ws
), error
);
555 RCHECK(ret
, krb5_store_int8(sp
, n
), error
);
556 RCHECK(ret
, krb5_store_int32(sp
, x_date
), error
);
557 RCHECK(ret
, krb5_store_int8(sp
, kvno
), error
);
558 RCHECK(ret
, krb5_store_int16(sp
, cipher
->length
), error
);
559 ret
= krb5_storage_write(sp
, cipher
->data
, cipher
->length
);
560 if (ret
!= cipher
->length
) {
561 ret
= KRB4ET_INTK_PROT
;
565 ret
= krb5_storage_to_data(sp
, data
);
568 krb5_storage_free(sp
);
570 krb5_set_error_message(context
, ret
,
571 N_("Failed to encode kerberos 4 ticket", ""));
580 krb5_error_code KRB5_LIB_FUNCTION
581 _krb5_krb_cr_err_reply(krb5_context context
,
587 const char *e_string
,
593 krb5_data_zero(data
);
595 if (name
== NULL
) name
= "";
596 if (inst
== NULL
) inst
= "";
597 if (realm
== NULL
) realm
= "";
598 if (e_string
== NULL
) e_string
= "";
600 sp
= krb5_storage_emem();
602 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
605 krb5_storage_set_byteorder(sp
, KRB5_STORAGE_BYTEORDER_BE
);
607 RCHECK(ret
, krb5_store_int8(sp
, KRB_PROT_VERSION
), error
);
608 RCHECK(ret
, krb5_store_int8(sp
, AUTH_MSG_ERR_REPLY
), error
);
609 RCHECK(ret
, put_nir(sp
, name
, inst
, realm
), error
);
610 RCHECK(ret
, krb5_store_int32(sp
, time_ws
), error
);
611 /* If it is a Kerberos 4 error-code, remove the et BASE */
612 if (e
>= ERROR_TABLE_BASE_krb
&& e
<= ERROR_TABLE_BASE_krb
+ 255)
613 e
-= ERROR_TABLE_BASE_krb
;
614 RCHECK(ret
, krb5_store_int32(sp
, e
), error
);
615 RCHECK(ret
, krb5_store_stringz(sp
, e_string
), error
);
617 ret
= krb5_storage_to_data(sp
, data
);
620 krb5_storage_free(sp
);
622 krb5_set_error_message(context
, ret
, "Failed to encode kerberos 4 error");
627 static krb5_error_code
628 get_v4_stringz(krb5_storage
*sp
, char **str
, size_t max_len
)
632 ret
= krb5_ret_stringz(sp
, str
);
635 if (strlen(*str
) > max_len
) {
638 return KRB4ET_INTK_PROT
;
647 krb5_error_code KRB5_LIB_FUNCTION
648 _krb5_krb_decomp_ticket(krb5_context context
,
649 const krb5_data
*enc_ticket
,
650 const krb5_keyblock
*key
,
651 const char *local_realm
,
654 struct _krb5_krb_auth_data
*ad
)
658 krb5_storage
*sp
= NULL
;
660 unsigned char des_key
[8];
662 memset(ad
, 0, sizeof(*ad
));
663 krb5_data_zero(&ticket
);
668 RCHECK(ret
, decrypt_etext(context
, key
, enc_ticket
, &ticket
), error
);
670 sp
= krb5_storage_from_data(&ticket
);
672 krb5_data_free(&ticket
);
673 krb5_set_error_message(context
, ENOMEM
, "alloc: out of memory");
677 krb5_storage_set_eof_code(sp
, KRB4ET_INTK_PROT
);
679 RCHECK(ret
, krb5_ret_int8(sp
, &ad
->k_flags
), error
);
680 RCHECK(ret
, get_v4_stringz(sp
, &ad
->pname
, ANAME_SZ
), error
);
681 RCHECK(ret
, get_v4_stringz(sp
, &ad
->pinst
, INST_SZ
), error
);
682 RCHECK(ret
, get_v4_stringz(sp
, &ad
->prealm
, REALM_SZ
), error
);
683 RCHECK(ret
, krb5_ret_uint32(sp
, &ad
->address
), error
);
685 size
= krb5_storage_read(sp
, des_key
, sizeof(des_key
));
686 if (size
!= sizeof(des_key
)) {
687 ret
= KRB4ET_INTK_PROT
;
691 RCHECK(ret
, krb5_ret_uint8(sp
, &ad
->life
), error
);
694 krb5_storage_set_byteorder(sp
, KRB5_STORAGE_BYTEORDER_LE
);
696 krb5_storage_set_byteorder(sp
, KRB5_STORAGE_BYTEORDER_BE
);
698 RCHECK(ret
, krb5_ret_uint32(sp
, &ad
->time_sec
), error
);
700 RCHECK(ret
, get_v4_stringz(sp
, sname
, ANAME_SZ
), error
);
701 RCHECK(ret
, get_v4_stringz(sp
, sinstance
, INST_SZ
), error
);
703 ret
= krb5_keyblock_init(context
, ETYPE_DES_PCBC_NONE
,
704 des_key
, sizeof(des_key
), &ad
->session
);
708 if (strlen(ad
->prealm
) == 0) {
710 ad
->prealm
= strdup(local_realm
);
711 if (ad
->prealm
== NULL
) {
718 memset(des_key
, 0, sizeof(des_key
));
720 krb5_storage_free(sp
);
721 krb5_data_free(&ticket
);
731 _krb5_krb_free_auth_data(context
, ad
);
732 krb5_set_error_message(context
, ret
, "Failed to decode v4 ticket");
741 krb5_error_code KRB5_LIB_FUNCTION
742 _krb5_krb_rd_req(krb5_context context
,
745 const char *instance
,
746 const char *local_realm
,
748 const krb5_keyblock
*key
,
749 struct _krb5_krb_auth_data
*ad
)
753 krb5_data ticket
, eaut
, aut
;
759 uint8_t ticket_length
;
764 char *sinstance
= NULL
;
765 char *r_realm
= NULL
;
767 char *r_instance
= NULL
;
769 uint32_t r_time_sec
; /* Coarse time from authenticator */
770 unsigned long delta_t
; /* Time in authenticator - local time */
771 long tkt_age
; /* Age of ticket */
775 krb5_data_zero(&ticket
);
776 krb5_data_zero(&eaut
);
777 krb5_data_zero(&aut
);
779 sp
= krb5_storage_from_data(authent
);
781 krb5_set_error_message(context
, ENOMEM
, N_("malloc: out of memory", ""));
785 krb5_storage_set_eof_code(sp
, KRB4ET_INTK_PROT
);
787 ret
= krb5_ret_int8(sp
, &pvno
);
789 krb5_set_error_message(context
, ret
, N_("Failed reading v4 pvno", ""));
793 if (pvno
!= KRB_PROT_VERSION
) {
794 ret
= KRB4ET_RD_AP_VERSION
;
795 krb5_set_error_message(context
, ret
, N_("Failed v4 pvno not 4", ""));
799 ret
= krb5_ret_int8(sp
, &type
);
801 krb5_set_error_message(context
, ret
, N_("Failed readin v4 type", ""));
805 little_endian
= type
& 1;
808 if(type
!= AUTH_MSG_APPL_REQUEST
&& type
!= AUTH_MSG_APPL_REQUEST_MUTUAL
) {
809 ret
= KRB4ET_RD_AP_MSG_TYPE
;
810 krb5_set_error_message(context
, ret
,
811 N_("Not a valid v4 request type", ""));
815 RCHECK(ret
, krb5_ret_int8(sp
, &s_kvno
), error
);
816 RCHECK(ret
, get_v4_stringz(sp
, &realm
, REALM_SZ
), error
);
817 RCHECK(ret
, krb5_ret_uint8(sp
, &ticket_length
), error
);
818 RCHECK(ret
, krb5_ret_uint8(sp
, &eaut_length
), error
);
819 RCHECK(ret
, krb5_data_alloc(&ticket
, ticket_length
), error
);
821 size
= krb5_storage_read(sp
, ticket
.data
, ticket
.length
);
822 if (size
!= ticket
.length
) {
823 ret
= KRB4ET_INTK_PROT
;
824 krb5_set_error_message(context
, ret
, N_("Failed reading v4 ticket", ""));
828 /* Decrypt and take apart ticket */
829 ret
= _krb5_krb_decomp_ticket(context
, &ticket
, key
, local_realm
,
830 &sname
, &sinstance
, ad
);
834 RCHECK(ret
, krb5_data_alloc(&eaut
, eaut_length
), error
);
836 size
= krb5_storage_read(sp
, eaut
.data
, eaut
.length
);
837 if (size
!= eaut
.length
) {
838 ret
= KRB4ET_INTK_PROT
;
839 krb5_set_error_message(context
, ret
,
840 N_("Failed reading v4 authenticator", ""));
844 krb5_storage_free(sp
);
847 ret
= decrypt_etext(context
, &ad
->session
, &eaut
, &aut
);
851 sp
= krb5_storage_from_data(&aut
);
854 krb5_set_error_message(context
, ret
, N_("malloc: out of memory", ""));
859 krb5_storage_set_byteorder(sp
, KRB5_STORAGE_BYTEORDER_LE
);
861 krb5_storage_set_byteorder(sp
, KRB5_STORAGE_BYTEORDER_BE
);
863 RCHECK(ret
, get_v4_stringz(sp
, &r_name
, ANAME_SZ
), error
);
864 RCHECK(ret
, get_v4_stringz(sp
, &r_instance
, INST_SZ
), error
);
865 RCHECK(ret
, get_v4_stringz(sp
, &r_realm
, REALM_SZ
), error
);
867 RCHECK(ret
, krb5_ret_uint32(sp
, &ad
->checksum
), error
);
868 RCHECK(ret
, krb5_ret_uint8(sp
, &time_5ms
), error
);
869 RCHECK(ret
, krb5_ret_uint32(sp
, &r_time_sec
), error
);
871 if (strcmp(ad
->pname
, r_name
) != 0 ||
872 strcmp(ad
->pinst
, r_instance
) != 0 ||
873 strcmp(ad
->prealm
, r_realm
) != 0) {
874 ret
= KRB4ET_RD_AP_INCON
;
875 krb5_set_error_message(context
, ret
, N_("v4 principal mismatch", ""));
879 if (from_addr
&& ad
->address
&& from_addr
!= ad
->address
) {
880 ret
= KRB4ET_RD_AP_BADD
;
881 krb5_set_error_message(context
, ret
,
882 N_("v4 bad address in ticket", ""));
886 gettimeofday(&tv
, NULL
);
887 delta_t
= abs((int)(tv
.tv_sec
- r_time_sec
));
888 if (delta_t
> CLOCK_SKEW
) {
889 ret
= KRB4ET_RD_AP_TIME
;
890 krb5_set_error_message(context
, ret
, N_("v4 clock skew", ""));
894 /* Now check for expiration of ticket */
896 tkt_age
= tv
.tv_sec
- ad
->time_sec
;
898 if ((tkt_age
< 0) && (-tkt_age
> CLOCK_SKEW
)) {
899 ret
= KRB4ET_RD_AP_NYV
;
900 krb5_set_error_message(context
, ret
,
901 N_("v4 clock skew for expiration", ""));
905 if (tv
.tv_sec
> _krb5_krb_life_to_time(ad
->time_sec
, ad
->life
)) {
906 ret
= KRB4ET_RD_AP_EXP
;
907 krb5_set_error_message(context
, ret
, N_("v4 ticket expired", ""));
913 krb5_data_free(&ticket
);
914 krb5_data_free(&eaut
);
915 krb5_data_free(&aut
);
929 krb5_storage_free(sp
);
932 krb5_clear_error_message(context
);
941 void KRB5_LIB_FUNCTION
942 _krb5_krb_free_auth_data(krb5_context context
, struct _krb5_krb_auth_data
*ad
)
950 krb5_free_keyblock_contents(context
, &ad
->session
);
951 memset(ad
, 0, sizeof(*ad
));
954 #endif /* HEIMDAL_SMALLER */