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
38 #define MAX_TIME ((time_t)((1U << 31) - 1))
47 if(**t
== 0) **t
= MAX_TIME
; /* fix for old clients */
51 realloc_method_data(METHOD_DATA
*md
)
54 pa
= realloc(md
->val
, (md
->len
+ 1) * sizeof(*md
->val
));
63 set_salt_padata (METHOD_DATA
*md
, Salt
*salt
)
66 realloc_method_data(md
);
67 md
->val
[md
->len
- 1].padata_type
= salt
->type
;
68 copy_octet_string(&salt
->salt
,
69 &md
->val
[md
->len
- 1].padata_value
);
74 find_padata(KDC_REQ
*req
, int *start
, int type
)
76 while(*start
< req
->padata
->len
){
78 if(req
->padata
->val
[*start
- 1].padata_type
== type
)
79 return &req
->padata
->val
[*start
- 1];
85 * return the first appropriate key of `princ' in `ret_key'. Look for
86 * all the etypes in (`etypes', `len'), stopping as soon as we find
87 * one, but preferring one that has default salt
90 static krb5_error_code
91 find_etype(hdb_entry
*princ
, krb5_enctype
*etypes
, unsigned len
,
92 Key
**ret_key
, krb5_enctype
*ret_etype
)
95 krb5_error_code ret
= KRB5KDC_ERR_ETYPE_NOSUPP
;
97 for(i
= 0; ret
!= 0 && i
< len
; i
++) {
100 if (krb5_enctype_valid(context
, etypes
[i
]) != 0)
103 while (hdb_next_enctype2key(context
, princ
, etypes
[i
], &key
) == 0) {
104 if (key
->key
.keyvalue
.length
== 0) {
105 ret
= KRB5KDC_ERR_NULL_KEY
;
109 *ret_etype
= etypes
[i
];
111 if (key
->salt
== NULL
)
118 static krb5_error_code
119 find_keys(hdb_entry
*client
,
122 krb5_enctype
*cetype
,
124 krb5_enctype
*setype
,
125 krb5_enctype
*etypes
,
128 char unparse_name
[] = "krb5_unparse_name failed";
133 /* find client key */
134 ret
= find_etype(client
, etypes
, num_etypes
, ckey
, cetype
);
136 if (krb5_unparse_name(context
, client
->principal
, &name
) != 0)
138 kdc_log(0, "Client (%s) has no support for etypes", name
);
139 if (name
!= unparse_name
)
146 /* find server key */
147 ret
= find_etype(server
, etypes
, num_etypes
, skey
, setype
);
149 if (krb5_unparse_name(context
, server
->principal
, &name
) != 0)
151 kdc_log(0, "Server (%s) has no support for etypes", name
);
152 if (name
!= unparse_name
)
160 static krb5_error_code
161 make_anonymous_principalname (PrincipalName
*pn
)
163 pn
->name_type
= KRB5_NT_PRINCIPAL
;
164 pn
->name_string
.len
= 1;
165 pn
->name_string
.val
= malloc(sizeof(*pn
->name_string
.val
));
166 if (pn
->name_string
.val
== NULL
)
168 pn
->name_string
.val
[0] = strdup("anonymous");
169 if (pn
->name_string
.val
[0] == NULL
) {
170 free(pn
->name_string
.val
);
171 pn
->name_string
.val
= NULL
;
177 static krb5_error_code
178 encode_reply(KDC_REP
*rep
, EncTicketPart
*et
, EncKDCRepPart
*ek
,
180 int skvno
, EncryptionKey
*skey
,
181 int ckvno
, EncryptionKey
*ckey
,
191 ASN1_MALLOC_ENCODE(EncTicketPart
, buf
, buf_size
, et
, &len
, ret
);
193 kdc_log(0, "Failed to encode ticket: %s",
194 krb5_get_err_text(context
, ret
));
197 if(buf_size
!= len
) {
199 kdc_log(0, "Internal error in ASN.1 encoder");
200 *e_text
= "KDC internal error";
201 return KRB5KRB_ERR_GENERIC
;
204 ret
= krb5_crypto_init(context
, skey
, etype
, &crypto
);
207 kdc_log(0, "krb5_crypto_init failed: %s",
208 krb5_get_err_text(context
, ret
));
212 ret
= krb5_encrypt_EncryptedData(context
,
218 &rep
->ticket
.enc_part
);
220 krb5_crypto_destroy(context
, crypto
);
222 kdc_log(0, "Failed to encrypt data: %s",
223 krb5_get_err_text(context
, ret
));
227 if(rep
->msg_type
== krb_as_rep
&& !encode_as_rep_as_tgs_rep
)
228 ASN1_MALLOC_ENCODE(EncASRepPart
, buf
, buf_size
, ek
, &len
, ret
);
230 ASN1_MALLOC_ENCODE(EncTGSRepPart
, buf
, buf_size
, ek
, &len
, ret
);
232 kdc_log(0, "Failed to encode KDC-REP: %s",
233 krb5_get_err_text(context
, ret
));
236 if(buf_size
!= len
) {
238 kdc_log(0, "Internal error in ASN.1 encoder");
239 *e_text
= "KDC internal error";
240 return KRB5KRB_ERR_GENERIC
;
242 ret
= krb5_crypto_init(context
, ckey
, 0, &crypto
);
245 kdc_log(0, "krb5_crypto_init failed: %s",
246 krb5_get_err_text(context
, ret
));
249 if(rep
->msg_type
== krb_as_rep
) {
250 krb5_encrypt_EncryptedData(context
,
252 KRB5_KU_AS_REP_ENC_PART
,
258 ASN1_MALLOC_ENCODE(AS_REP
, buf
, buf_size
, rep
, &len
, ret
);
260 krb5_encrypt_EncryptedData(context
,
262 KRB5_KU_TGS_REP_ENC_PART_SESSION
,
268 ASN1_MALLOC_ENCODE(TGS_REP
, buf
, buf_size
, rep
, &len
, ret
);
270 krb5_crypto_destroy(context
, crypto
);
272 kdc_log(0, "Failed to encode KDC-REP: %s",
273 krb5_get_err_text(context
, ret
));
276 if(buf_size
!= len
) {
278 kdc_log(0, "Internal error in ASN.1 encoder");
279 *e_text
= "KDC internal error";
280 return KRB5KRB_ERR_GENERIC
;
283 reply
->length
= buf_size
;
287 static krb5_error_code
288 make_etype_info_entry(ETYPE_INFO_ENTRY
*ent
, Key
*key
)
290 ent
->etype
= key
->key
.keytype
;
292 ALLOC(ent
->salttype
);
294 if(key
->salt
->type
== hdb_pw_salt
)
295 *ent
->salttype
= 0; /* or 1? or NULL? */
296 else if(key
->salt
->type
== hdb_afs3_salt
)
299 kdc_log(0, "unknown salt-type: %d",
301 return KRB5KRB_ERR_GENERIC
;
303 /* according to `the specs', we can't send a salt if
304 we have AFS3 salted key, but that requires that you
305 *know* what cell you are using (e.g by assuming
306 that the cell is the same as the realm in lower
309 *ent
->salttype
= key
->salt
->type
;
311 krb5_copy_data(context
, &key
->salt
->salt
,
314 /* we return no salt type at all, as that should indicate
315 * the default salt type and make everybody happy. some
316 * systems (like w2k) dislike being told the salt type
319 ent
->salttype
= NULL
;
325 static krb5_error_code
326 get_pa_etype_info(METHOD_DATA
*md
, hdb_entry
*client
,
327 ENCTYPE
*etypes
, unsigned int etypes_len
)
329 krb5_error_code ret
= 0;
337 pa
.len
= client
->keys
.len
;
338 if(pa
.len
> UINT_MAX
/sizeof(*pa
.val
))
340 pa
.val
= malloc(pa
.len
* sizeof(*pa
.val
));
343 memset(pa
.val
, 0, pa
.len
* sizeof(*pa
.val
));
345 for(j
= 0; j
< etypes_len
; j
++) {
346 for (i
= 0; i
< n
; i
++)
347 if (pa
.val
[i
].etype
== etypes
[j
])
349 for(i
= 0; i
< client
->keys
.len
; i
++) {
350 if(client
->keys
.val
[i
].key
.keytype
== etypes
[j
]) {
351 if (krb5_enctype_valid(context
, etypes
[j
]) != 0)
353 if((ret
= make_etype_info_entry(&pa
.val
[n
++],
354 &client
->keys
.val
[i
])) != 0) {
355 free_ETYPE_INFO(&pa
);
362 for(i
= 0; i
< client
->keys
.len
; i
++) {
363 for(j
= 0; j
< etypes_len
; j
++) {
364 if(client
->keys
.val
[i
].key
.keytype
== etypes
[j
])
367 if (krb5_enctype_valid(context
, client
->keys
.val
[i
].key
.keytype
) != 0)
369 if((ret
= make_etype_info_entry(&pa
.val
[n
++],
370 &client
->keys
.val
[i
])) != 0) {
371 free_ETYPE_INFO(&pa
);
379 ret
= krb5_unparse_name(context
, client
->principal
, &name
);
381 name
= "<unparse_name failed>";
382 kdc_log(0, "internal error in get_pa_etype_info(%s): %d != %d",
389 ASN1_MALLOC_ENCODE(ETYPE_INFO
, buf
, len
, &pa
, &len
, ret
);
390 free_ETYPE_INFO(&pa
);
393 ret
= realloc_method_data(md
);
398 md
->val
[md
->len
- 1].padata_type
= KRB5_PADATA_ETYPE_INFO
;
399 md
->val
[md
->len
- 1].padata_value
.length
= len
;
400 md
->val
[md
->len
- 1].padata_value
.data
= buf
;
408 extern int _krb5_AES_string_to_default_iterator
;
410 static krb5_error_code
411 make_etype_info2_entry(ETYPE_INFO2_ENTRY
*ent
, Key
*key
)
413 ent
->etype
= key
->key
.keytype
;
416 if (ent
->salt
== NULL
)
418 *ent
->salt
= malloc(key
->salt
->salt
.length
+ 1);
419 if (*ent
->salt
== NULL
) {
424 memcpy(*ent
->salt
, key
->salt
->salt
.data
, key
->salt
->salt
.length
);
425 (*ent
->salt
)[key
->salt
->salt
.length
] = '\0';
429 ent
->s2kparams
= NULL
;
431 switch (key
->key
.keytype
) {
434 ALLOC(ent
->s2kparams
);
435 if (ent
->s2kparams
== NULL
)
437 ent
->s2kparams
->length
= 4;
438 ent
->s2kparams
->data
= malloc(ent
->s2kparams
->length
);
439 if (ent
->s2kparams
->data
== NULL
) {
440 free(ent
->s2kparams
);
441 ent
->s2kparams
= NULL
;
444 _krb5_put_int(ent
->s2kparams
->data
,
445 _krb5_AES_string_to_default_iterator
,
446 ent
->s2kparams
->length
);
455 * Return 1 if the client have only older enctypes, this is for
456 * determining if the server should send ETYPE_INFO2 or not.
460 only_older_enctype_p(const KDC_REQ
*req
)
464 for(i
= 0; i
< req
->req_body
.etype
.len
; i
++) {
465 switch (req
->req_body
.etype
.val
[i
]) {
466 case ETYPE_DES_CBC_CRC
:
467 case ETYPE_DES_CBC_MD4
:
468 case ETYPE_DES_CBC_MD5
:
469 case ETYPE_DES3_CBC_SHA1
:
470 case ETYPE_ARCFOUR_HMAC_MD5
:
471 case ETYPE_ARCFOUR_HMAC_MD5_56
:
484 static krb5_error_code
485 get_pa_etype_info2(METHOD_DATA
*md
, hdb_entry
*client
,
486 ENCTYPE
*etypes
, unsigned int etypes_len
)
488 krb5_error_code ret
= 0;
495 pa
.len
= client
->keys
.len
;
496 if(pa
.len
> UINT_MAX
/sizeof(*pa
.val
))
498 pa
.val
= malloc(pa
.len
* sizeof(*pa
.val
));
501 memset(pa
.val
, 0, pa
.len
* sizeof(*pa
.val
));
503 for(j
= 0; j
< etypes_len
; j
++) {
504 for (i
= 0; i
< n
; i
++)
505 if (pa
.val
[i
].etype
== etypes
[j
])
507 for(i
= 0; i
< client
->keys
.len
; i
++) {
508 if(client
->keys
.val
[i
].key
.keytype
== etypes
[j
]) {
509 if (krb5_enctype_valid(context
, etypes
[j
]) != 0)
511 if((ret
= make_etype_info2_entry(&pa
.val
[n
++],
512 &client
->keys
.val
[i
])) != 0) {
513 free_ETYPE_INFO2(&pa
);
520 for(i
= 0; i
< client
->keys
.len
; i
++) {
521 for(j
= 0; j
< etypes_len
; j
++) {
522 if(client
->keys
.val
[i
].key
.keytype
== etypes
[j
])
525 if (krb5_enctype_valid(context
, client
->keys
.val
[i
].key
.keytype
) != 0)
527 if((ret
= make_etype_info2_entry(&pa
.val
[n
++],
528 &client
->keys
.val
[i
])) != 0) {
529 free_ETYPE_INFO2(&pa
);
537 ret
= krb5_unparse_name(context
, client
->principal
, &name
);
539 name
= "<unparse_name failed>";
540 kdc_log(0, "internal error in get_pa_etype_info2(%s): %d != %d",
547 ASN1_MALLOC_ENCODE(ETYPE_INFO2
, buf
, len
, &pa
, &len
, ret
);
548 free_ETYPE_INFO2(&pa
);
551 ret
= realloc_method_data(md
);
556 md
->val
[md
->len
- 1].padata_type
= KRB5_PADATA_ETYPE_INFO2
;
557 md
->val
[md
->len
- 1].padata_value
.length
= len
;
558 md
->val
[md
->len
- 1].padata_value
.data
= buf
;
563 * verify the flags on `client' and `server', returning 0
564 * if they are OK and generating an error messages and returning
565 * and error code otherwise.
569 check_flags(hdb_entry
*client
, const char *client_name
,
570 hdb_entry
*server
, const char *server_name
,
571 krb5_boolean is_as_req
)
575 if (client
->flags
.invalid
) {
576 kdc_log(0, "Client (%s) has invalid bit set", client_name
);
577 return KRB5KDC_ERR_POLICY
;
580 if(!client
->flags
.client
){
581 kdc_log(0, "Principal may not act as client -- %s",
583 return KRB5KDC_ERR_POLICY
;
586 if (client
->valid_start
&& *client
->valid_start
> kdc_time
) {
587 kdc_log(0, "Client not yet valid -- %s", client_name
);
588 return KRB5KDC_ERR_CLIENT_NOTYET
;
591 if (client
->valid_end
&& *client
->valid_end
< kdc_time
) {
592 kdc_log(0, "Client expired -- %s", client_name
);
593 return KRB5KDC_ERR_NAME_EXP
;
596 if (client
->pw_end
&& *client
->pw_end
< kdc_time
597 && !server
->flags
.change_pw
) {
598 kdc_log(0, "Client's key has expired -- %s", client_name
);
599 return KRB5KDC_ERR_KEY_EXPIRED
;
605 if (server
!= NULL
) {
606 if (server
->flags
.invalid
) {
607 kdc_log(0, "Server has invalid flag set -- %s", server_name
);
608 return KRB5KDC_ERR_POLICY
;
611 if(!server
->flags
.server
){
612 kdc_log(0, "Principal may not act as server -- %s",
614 return KRB5KDC_ERR_POLICY
;
617 if(!is_as_req
&& server
->flags
.initial
) {
618 kdc_log(0, "AS-REQ is required for server -- %s", server_name
);
619 return KRB5KDC_ERR_POLICY
;
622 if (server
->valid_start
&& *server
->valid_start
> kdc_time
) {
623 kdc_log(0, "Server not yet valid -- %s", server_name
);
624 return KRB5KDC_ERR_SERVICE_NOTYET
;
627 if (server
->valid_end
&& *server
->valid_end
< kdc_time
) {
628 kdc_log(0, "Server expired -- %s", server_name
);
629 return KRB5KDC_ERR_SERVICE_EXP
;
632 if (server
->pw_end
&& *server
->pw_end
< kdc_time
) {
633 kdc_log(0, "Server's key has expired -- %s", server_name
);
634 return KRB5KDC_ERR_KEY_EXPIRED
;
641 * Return TRUE if `from' is part of `addresses' taking into consideration
642 * the configuration variables that tells us how strict we should be about
647 check_addresses(HostAddresses
*addresses
, const struct sockaddr
*from
)
653 if(check_ticket_addresses
== 0)
656 if(addresses
== NULL
)
657 return allow_null_ticket_addresses
;
659 ret
= krb5_sockaddr2address (context
, from
, &addr
);
663 result
= krb5_address_search(context
, &addr
, addresses
);
664 krb5_free_address (context
, &addr
);
672 struct sockaddr
*from_addr
)
674 KDC_REQ_BODY
*b
= &req
->req_body
;
676 KDCOptions f
= b
->kdc_options
;
677 hdb_entry
*client
= NULL
, *server
= NULL
;
678 krb5_enctype cetype
, setype
;
681 krb5_principal client_princ
= NULL
, server_princ
= NULL
;
682 char *client_name
= NULL
, *server_name
= NULL
;
683 krb5_error_code ret
= 0;
684 const char *e_text
= NULL
;
687 EncryptionKey
*reply_key
;
689 pk_client_params
*pkp
= NULL
;
692 memset(&rep
, 0, sizeof(rep
));
694 if(b
->sname
== NULL
){
695 ret
= KRB5KRB_ERR_GENERIC
;
696 e_text
= "No server in request";
698 _krb5_principalname2krb5_principal (&server_princ
,
699 *(b
->sname
), b
->realm
);
700 ret
= krb5_unparse_name(context
, server_princ
, &server_name
);
703 kdc_log(0, "AS-REQ malformed server name from %s", from
);
707 if(b
->cname
== NULL
){
708 ret
= KRB5KRB_ERR_GENERIC
;
709 e_text
= "No client in request";
711 _krb5_principalname2krb5_principal (&client_princ
,
712 *(b
->cname
), b
->realm
);
713 ret
= krb5_unparse_name(context
, client_princ
, &client_name
);
716 kdc_log(0, "AS-REQ malformed client name from %s", from
);
720 kdc_log(0, "AS-REQ %s from %s for %s",
721 client_name
, from
, server_name
);
723 ret
= db_fetch(client_princ
, &client
);
725 kdc_log(0, "UNKNOWN -- %s: %s", client_name
,
726 krb5_get_err_text(context
, ret
));
727 ret
= KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN
;
731 ret
= db_fetch(server_princ
, &server
);
733 kdc_log(0, "UNKNOWN -- %s: %s", server_name
,
734 krb5_get_err_text(context
, ret
));
735 ret
= KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
;
739 ret
= check_flags(client
, client_name
, server
, server_name
, TRUE
);
743 memset(&et
, 0, sizeof(et
));
744 memset(&ek
, 0, sizeof(ek
));
752 kdc_log(5, "Looking for PKINIT pa-data -- %s", client_name
);
754 e_text
= "No PKINIT PA found";
757 if ((pa
= find_padata(req
, &i
, KRB5_PADATA_PK_AS_REQ
)))
761 if((pa
= find_padata(req
, &i
, KRB5_PADATA_PK_AS_REQ_19
)))
766 if((pa
= find_padata(req
, &i
, KRB5_PADATA_PK_AS_REQ_WIN
)))
770 char *client_cert
= NULL
;
772 ret
= pk_rd_padata(context
, req
, pa
, &pkp
);
774 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
775 kdc_log(5, "Failed to decode PKINIT PA-DATA -- %s",
779 if (ret
== 0 && pkp
== NULL
)
782 ret
= pk_check_client(context
,
788 e_text
= "PKINIT certificate not allowed to "
789 "impersonate principal";
790 pk_free_client_param(context
, pkp
);
795 et
.flags
.pre_authent
= 1;
796 kdc_log(2, "PKINIT pre-authentication succeeded -- %s using %s",
797 client_name
, client_cert
);
804 kdc_log(5, "Looking for ENC-TS pa-data -- %s", client_name
);
807 e_text
= "No ENC-TS found";
808 while((pa
= find_padata(req
, &i
, KRB5_PADATA_ENC_TIMESTAMP
))){
812 EncryptedData enc_data
;
817 ret
= decode_EncryptedData(pa
->padata_value
.data
,
818 pa
->padata_value
.length
,
822 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
823 kdc_log(5, "Failed to decode PA-DATA -- %s",
828 ret
= hdb_enctype2key(context
, client
, enc_data
.etype
, &pa_key
);
831 e_text
= "No key matches pa-data";
832 ret
= KRB5KDC_ERR_PREAUTH_FAILED
;
833 if(krb5_enctype_to_string(context
, enc_data
.etype
, &estr
))
836 kdc_log(5, "No client key matching pa-data (%d) -- %s",
837 enc_data
.etype
, client_name
);
839 kdc_log(5, "No client key matching pa-data (%s) -- %s",
843 free_EncryptedData(&enc_data
);
848 ret
= krb5_crypto_init(context
, &pa_key
->key
, 0, &crypto
);
850 kdc_log(0, "krb5_crypto_init failed: %s",
851 krb5_get_err_text(context
, ret
));
852 free_EncryptedData(&enc_data
);
856 ret
= krb5_decrypt_EncryptedData (context
,
858 KRB5_KU_PA_ENC_TIMESTAMP
,
861 krb5_crypto_destroy(context
, crypto
);
863 if(hdb_next_enctype2key(context
, client
,
864 enc_data
.etype
, &pa_key
) == 0)
866 free_EncryptedData(&enc_data
);
867 e_text
= "Failed to decrypt PA-DATA";
868 kdc_log (5, "Failed to decrypt PA-DATA -- %s",
870 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
873 free_EncryptedData(&enc_data
);
874 ret
= decode_PA_ENC_TS_ENC(ts_data
.data
,
878 krb5_data_free(&ts_data
);
880 e_text
= "Failed to decode PA-ENC-TS-ENC";
881 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
;
882 kdc_log (5, "Failed to decode PA-ENC-TS_ENC -- %s",
886 free_PA_ENC_TS_ENC(&p
);
887 if (abs(kdc_time
- p
.patimestamp
) > context
->max_skew
) {
888 ret
= KRB5KDC_ERR_PREAUTH_FAILED
;
889 e_text
= "Too large time skew";
890 kdc_log(0, "Too large time skew -- %s", client_name
);
893 et
.flags
.pre_authent
= 1;
894 kdc_log(2, "ENC-TS Pre-authentication succeeded -- %s",
901 if(found_pa
== 0 && require_preauth
)
903 /* We come here if we found a pa-enc-timestamp, but if there
904 was some problem with it, other than too large skew */
905 if(found_pa
&& et
.flags
.pre_authent
== 0){
906 kdc_log(0, "%s -- %s", e_text
, client_name
);
910 }else if (require_preauth
911 || client
->flags
.require_preauth
912 || server
->flags
.require_preauth
) {
913 METHOD_DATA method_data
;
921 method_data
.val
= NULL
;
923 ret
= realloc_method_data(&method_data
);
924 pa
= &method_data
.val
[method_data
.len
-1];
925 pa
->padata_type
= KRB5_PADATA_ENC_TIMESTAMP
;
926 pa
->padata_value
.length
= 0;
927 pa
->padata_value
.data
= NULL
;
930 ret
= realloc_method_data(&method_data
);
931 pa
= &method_data
.val
[method_data
.len
-1];
932 pa
->padata_type
= KRB5_PADATA_PK_AS_REQ
;
933 pa
->padata_value
.length
= 0;
934 pa
->padata_value
.data
= NULL
;
936 ret
= realloc_method_data(&method_data
);
937 pa
= &method_data
.val
[method_data
.len
-1];
938 pa
->padata_type
= KRB5_PADATA_PK_AS_REQ_19
;
939 pa
->padata_value
.length
= 0;
940 pa
->padata_value
.data
= NULL
;
944 if (only_older_enctype_p(req
))
945 ret
= get_pa_etype_info(&method_data
, client
,
946 b
->etype
.val
, b
->etype
.len
);
948 ret
= get_pa_etype_info2(&method_data
, client
,
949 b
->etype
.val
, b
->etype
.len
);
952 ASN1_MALLOC_ENCODE(METHOD_DATA
, buf
, len
, &method_data
, &len
, ret
);
953 free_METHOD_DATA(&method_data
);
955 foo_data
.length
= len
;
957 ret
= KRB5KDC_ERR_PREAUTH_REQUIRED
;
958 krb5_mk_error(context
,
960 "Need to use PA-ENC-TIMESTAMP/PA-PK-AS-REQ",
968 kdc_log(0, "No preauth found, returning PREAUTH-REQUIRED -- %s",
974 ret
= find_keys(client
, server
, &ckey
, &cetype
, &skey
, &setype
,
975 b
->etype
.val
, b
->etype
.len
);
977 kdc_log(0, "Server/client has no support for etypes");
985 ret
= krb5_enctype_to_string(context
, cetype
, &cet
);
987 ret
= krb5_enctype_to_string(context
, setype
, &set
);
989 kdc_log(5, "Using %s/%s", cet
, set
);
995 kdc_log(5, "Using e-types %d/%d", cetype
, setype
);
1000 unparse_flags(KDCOptions2int(f
), asn1_KDCOptions_units(),
1003 kdc_log(2, "Requested flags: %s", str
);
1007 if(f
.renew
|| f
.validate
|| f
.proxy
|| f
.forwarded
|| f
.enc_tkt_in_skey
1008 || (f
.request_anonymous
&& !allow_anonymous
)) {
1009 ret
= KRB5KDC_ERR_BADOPTION
;
1010 kdc_log(0, "Bad KDC options -- %s", client_name
);
1015 rep
.msg_type
= krb_as_rep
;
1016 copy_Realm(&b
->realm
, &rep
.crealm
);
1017 if (f
.request_anonymous
)
1018 make_anonymous_principalname (&rep
.cname
);
1020 copy_PrincipalName(b
->cname
, &rep
.cname
);
1021 rep
.ticket
.tkt_vno
= 5;
1022 copy_Realm(&b
->realm
, &rep
.ticket
.realm
);
1023 copy_PrincipalName(b
->sname
, &rep
.ticket
.sname
);
1025 et
.flags
.initial
= 1;
1026 if(client
->flags
.forwardable
&& server
->flags
.forwardable
)
1027 et
.flags
.forwardable
= f
.forwardable
;
1028 else if (f
.forwardable
) {
1029 ret
= KRB5KDC_ERR_POLICY
;
1030 kdc_log(0, "Ticket may not be forwardable -- %s", client_name
);
1033 if(client
->flags
.proxiable
&& server
->flags
.proxiable
)
1034 et
.flags
.proxiable
= f
.proxiable
;
1035 else if (f
.proxiable
) {
1036 ret
= KRB5KDC_ERR_POLICY
;
1037 kdc_log(0, "Ticket may not be proxiable -- %s", client_name
);
1040 if(client
->flags
.postdate
&& server
->flags
.postdate
)
1041 et
.flags
.may_postdate
= f
.allow_postdate
;
1042 else if (f
.allow_postdate
){
1043 ret
= KRB5KDC_ERR_POLICY
;
1044 kdc_log(0, "Ticket may not be postdatable -- %s", client_name
);
1048 /* check for valid set of addresses */
1049 if(!check_addresses(b
->addresses
, from_addr
)) {
1050 ret
= KRB5KRB_AP_ERR_BADADDR
;
1051 kdc_log(0, "Bad address list requested -- %s", client_name
);
1055 krb5_generate_random_keyblock(context
, setype
, &et
.key
);
1056 copy_PrincipalName(&rep
.cname
, &et
.cname
);
1057 copy_Realm(&b
->realm
, &et
.crealm
);
1063 start
= et
.authtime
= kdc_time
;
1065 if(f
.postdated
&& req
->req_body
.from
){
1066 ALLOC(et
.starttime
);
1067 start
= *et
.starttime
= *req
->req_body
.from
;
1068 et
.flags
.invalid
= 1;
1069 et
.flags
.postdated
= 1; /* XXX ??? */
1074 /* be careful not overflowing */
1076 if(client
->max_life
)
1077 t
= start
+ min(t
- start
, *client
->max_life
);
1078 if(server
->max_life
)
1079 t
= start
+ min(t
- start
, *server
->max_life
);
1081 t
= min(t
, start
+ realm
->max_life
);
1084 if(f
.renewable_ok
&& et
.endtime
< *b
->till
){
1086 if(b
->rtime
== NULL
){
1090 if(*b
->rtime
< *b
->till
)
1091 *b
->rtime
= *b
->till
;
1093 if(f
.renewable
&& b
->rtime
){
1097 if(client
->max_renew
)
1098 t
= start
+ min(t
- start
, *client
->max_renew
);
1099 if(server
->max_renew
)
1100 t
= start
+ min(t
- start
, *server
->max_renew
);
1102 t
= min(t
, start
+ realm
->max_renew
);
1104 ALLOC(et
.renew_till
);
1106 et
.flags
.renewable
= 1;
1110 if (f
.request_anonymous
)
1111 et
.flags
.anonymous
= 1;
1115 copy_HostAddresses(b
->addresses
, et
.caddr
);
1118 et
.transited
.tr_type
= DOMAIN_X500_COMPRESS
;
1119 krb5_data_zero(&et
.transited
.contents
);
1121 copy_EncryptionKey(&et
.key
, &ek
.key
);
1123 /* The MIT ASN.1 library (obviously) doesn't tell lengths encoded
1124 * as 0 and as 0x80 (meaning indefinite length) apart, and is thus
1125 * incapable of correctly decoding SEQUENCE OF's of zero length.
1127 * To fix this, always send at least one no-op last_req
1129 * If there's a pw_end or valid_end we will use that,
1130 * otherwise just a dummy lr.
1132 ek
.last_req
.val
= malloc(2 * sizeof(*ek
.last_req
.val
));
1133 ek
.last_req
.len
= 0;
1135 && (kdc_warn_pwexpire
== 0
1136 || kdc_time
+ kdc_warn_pwexpire
<= *client
->pw_end
)) {
1137 ek
.last_req
.val
[ek
.last_req
.len
].lr_type
= LR_PW_EXPTIME
;
1138 ek
.last_req
.val
[ek
.last_req
.len
].lr_value
= *client
->pw_end
;
1141 if (client
->valid_end
) {
1142 ek
.last_req
.val
[ek
.last_req
.len
].lr_type
= LR_ACCT_EXPTIME
;
1143 ek
.last_req
.val
[ek
.last_req
.len
].lr_value
= *client
->valid_end
;
1146 if (ek
.last_req
.len
== 0) {
1147 ek
.last_req
.val
[ek
.last_req
.len
].lr_type
= LR_NONE
;
1148 ek
.last_req
.val
[ek
.last_req
.len
].lr_value
= 0;
1151 ek
.nonce
= b
->nonce
;
1152 if (client
->valid_end
|| client
->pw_end
) {
1153 ALLOC(ek
.key_expiration
);
1154 if (client
->valid_end
) {
1156 *ek
.key_expiration
= min(*client
->valid_end
, *client
->pw_end
);
1158 *ek
.key_expiration
= *client
->valid_end
;
1160 *ek
.key_expiration
= *client
->pw_end
;
1162 ek
.key_expiration
= NULL
;
1163 ek
.flags
= et
.flags
;
1164 ek
.authtime
= et
.authtime
;
1166 ALLOC(ek
.starttime
);
1167 *ek
.starttime
= *et
.starttime
;
1169 ek
.endtime
= et
.endtime
;
1170 if (et
.renew_till
) {
1171 ALLOC(ek
.renew_till
);
1172 *ek
.renew_till
= *et
.renew_till
;
1174 copy_Realm(&rep
.ticket
.realm
, &ek
.srealm
);
1175 copy_PrincipalName(&rep
.ticket
.sname
, &ek
.sname
);
1178 copy_HostAddresses(et
.caddr
, ek
.caddr
);
1182 rep
.padata
->len
= 0;
1183 rep
.padata
->val
= NULL
;
1185 reply_key
= &ckey
->key
;
1188 ret
= pk_mk_pa_reply(context
, pkp
, client
, req
,
1189 &reply_key
, rep
.padata
);
1195 set_salt_padata (rep
.padata
, ckey
->salt
);
1197 if (rep
.padata
->len
== 0) {
1202 ret
= encode_reply(&rep
, &et
, &ek
, setype
, server
->kvno
, &skey
->key
,
1203 client
->kvno
, reply_key
, &e_text
, reply
);
1204 free_EncTicketPart(&et
);
1205 free_EncKDCRepPart(&ek
);
1209 krb5_mk_error(context
,
1223 pk_free_client_param(context
, pkp
);
1226 krb5_free_principal(context
, client_princ
);
1229 krb5_free_principal(context
, server_princ
);
1239 static krb5_error_code
1240 check_tgs_flags(KDC_REQ_BODY
*b
, EncTicketPart
*tgt
, EncTicketPart
*et
)
1242 KDCOptions f
= b
->kdc_options
;
1245 if(!tgt
->flags
.invalid
|| tgt
->starttime
== NULL
){
1246 kdc_log(0, "Bad request to validate ticket");
1247 return KRB5KDC_ERR_BADOPTION
;
1249 if(*tgt
->starttime
> kdc_time
){
1250 kdc_log(0, "Early request to validate ticket");
1251 return KRB5KRB_AP_ERR_TKT_NYV
;
1254 et
->flags
.invalid
= 0;
1255 }else if(tgt
->flags
.invalid
){
1256 kdc_log(0, "Ticket-granting ticket has INVALID flag set");
1257 return KRB5KRB_AP_ERR_TKT_INVALID
;
1261 if(!tgt
->flags
.forwardable
){
1262 kdc_log(0, "Bad request for forwardable ticket");
1263 return KRB5KDC_ERR_BADOPTION
;
1265 et
->flags
.forwardable
= 1;
1268 if(!tgt
->flags
.forwardable
){
1269 kdc_log(0, "Request to forward non-forwardable ticket");
1270 return KRB5KDC_ERR_BADOPTION
;
1272 et
->flags
.forwarded
= 1;
1273 et
->caddr
= b
->addresses
;
1275 if(tgt
->flags
.forwarded
)
1276 et
->flags
.forwarded
= 1;
1279 if(!tgt
->flags
.proxiable
){
1280 kdc_log(0, "Bad request for proxiable ticket");
1281 return KRB5KDC_ERR_BADOPTION
;
1283 et
->flags
.proxiable
= 1;
1286 if(!tgt
->flags
.proxiable
){
1287 kdc_log(0, "Request to proxy non-proxiable ticket");
1288 return KRB5KDC_ERR_BADOPTION
;
1290 et
->flags
.proxy
= 1;
1291 et
->caddr
= b
->addresses
;
1293 if(tgt
->flags
.proxy
)
1294 et
->flags
.proxy
= 1;
1296 if(f
.allow_postdate
){
1297 if(!tgt
->flags
.may_postdate
){
1298 kdc_log(0, "Bad request for post-datable ticket");
1299 return KRB5KDC_ERR_BADOPTION
;
1301 et
->flags
.may_postdate
= 1;
1304 if(!tgt
->flags
.may_postdate
){
1305 kdc_log(0, "Bad request for postdated ticket");
1306 return KRB5KDC_ERR_BADOPTION
;
1309 *et
->starttime
= *b
->from
;
1310 et
->flags
.postdated
= 1;
1311 et
->flags
.invalid
= 1;
1312 }else if(b
->from
&& *b
->from
> kdc_time
+ context
->max_skew
){
1313 kdc_log(0, "Ticket cannot be postdated");
1314 return KRB5KDC_ERR_CANNOT_POSTDATE
;
1318 if(!tgt
->flags
.renewable
){
1319 kdc_log(0, "Bad request for renewable ticket");
1320 return KRB5KDC_ERR_BADOPTION
;
1322 et
->flags
.renewable
= 1;
1323 ALLOC(et
->renew_till
);
1324 fix_time(&b
->rtime
);
1325 *et
->renew_till
= *b
->rtime
;
1329 if(!tgt
->flags
.renewable
|| tgt
->renew_till
== NULL
){
1330 kdc_log(0, "Request to renew non-renewable ticket");
1331 return KRB5KDC_ERR_BADOPTION
;
1333 old_life
= tgt
->endtime
;
1335 old_life
-= *tgt
->starttime
;
1337 old_life
-= tgt
->authtime
;
1338 et
->endtime
= *et
->starttime
+ old_life
;
1339 if (et
->renew_till
!= NULL
)
1340 et
->endtime
= min(*et
->renew_till
, et
->endtime
);
1343 /* checks for excess flags */
1344 if(f
.request_anonymous
&& !allow_anonymous
){
1345 kdc_log(0, "Request for anonymous ticket");
1346 return KRB5KDC_ERR_BADOPTION
;
1351 static krb5_error_code
1352 fix_transited_encoding(krb5_boolean check_policy
,
1353 TransitedEncoding
*tr
,
1355 const char *client_realm
,
1356 const char *server_realm
,
1357 const char *tgt_realm
)
1359 krb5_error_code ret
= 0;
1360 char **realms
, **tmp
;
1364 if(tr
->tr_type
!= DOMAIN_X500_COMPRESS
) {
1365 kdc_log(0, "Unknown transited type: %u", tr
->tr_type
);
1366 return KRB5KDC_ERR_TRTYPE_NOSUPP
;
1369 ret
= krb5_domain_x500_decode(context
,
1376 krb5_warn(context
, ret
, "Decoding transited encoding");
1379 if(strcmp(client_realm
, tgt_realm
) && strcmp(server_realm
, tgt_realm
)) {
1380 /* not us, so add the previous realm to transited set */
1381 if (num_realms
< 0 || num_realms
+ 1 > UINT_MAX
/sizeof(*realms
)) {
1385 tmp
= realloc(realms
, (num_realms
+ 1) * sizeof(*realms
));
1391 realms
[num_realms
] = strdup(tgt_realm
);
1392 if(realms
[num_realms
] == NULL
){
1398 if(num_realms
== 0) {
1399 if(strcmp(client_realm
, server_realm
))
1400 kdc_log(0, "cross-realm %s -> %s", client_realm
, server_realm
);
1404 for(i
= 0; i
< num_realms
; i
++)
1405 l
+= strlen(realms
[i
]) + 2;
1409 for(i
= 0; i
< num_realms
; i
++) {
1411 strlcat(rs
, ", ", l
);
1412 strlcat(rs
, realms
[i
], l
);
1414 kdc_log(0, "cross-realm %s -> %s via [%s]", client_realm
, server_realm
, rs
);
1419 ret
= krb5_check_transited(context
, client_realm
,
1421 realms
, num_realms
, NULL
);
1423 krb5_warn(context
, ret
, "cross-realm %s -> %s",
1424 client_realm
, server_realm
);
1427 et
->flags
.transited_policy_checked
= 1;
1429 et
->transited
.tr_type
= DOMAIN_X500_COMPRESS
;
1430 ret
= krb5_domain_x500_encode(realms
, num_realms
, &et
->transited
.contents
);
1432 krb5_warn(context
, ret
, "Encoding transited encoding");
1434 for(i
= 0; i
< num_realms
; i
++)
1441 static krb5_error_code
1442 tgs_make_reply(KDC_REQ_BODY
*b
,
1444 EncTicketPart
*adtkt
,
1445 AuthorizationData
*auth_data
,
1448 krb5_principal client_principal
,
1450 krb5_enctype cetype
,
1451 const char **e_text
,
1457 KDCOptions f
= b
->kdc_options
;
1458 krb5_error_code ret
;
1461 EncryptionKey
*ekey
;
1467 for(i
= 0; i
< b
->etype
.len
; i
++){
1468 ret
= krb5_enctype_to_keytype(context
, b
->etype
.val
[i
], &kt
);
1471 if(adtkt
->key
.keytype
== kt
)
1474 if(i
== b
->etype
.len
)
1475 return KRB5KDC_ERR_ETYPE_NOSUPP
;
1476 etype
= b
->etype
.val
[i
];
1478 ret
= find_keys(NULL
, server
, NULL
, NULL
, &skey
, &etype
,
1479 b
->etype
.val
, b
->etype
.len
);
1481 kdc_log(0, "Server has no support for etypes");
1487 memset(&rep
, 0, sizeof(rep
));
1488 memset(&et
, 0, sizeof(et
));
1489 memset(&ek
, 0, sizeof(ek
));
1492 rep
.msg_type
= krb_tgs_rep
;
1494 et
.authtime
= tgt
->authtime
;
1496 et
.endtime
= min(tgt
->endtime
, *b
->till
);
1497 ALLOC(et
.starttime
);
1498 *et
.starttime
= kdc_time
;
1500 ret
= check_tgs_flags(b
, tgt
, &et
);
1504 /* We should check the transited encoding if:
1505 1) the request doesn't ask not to be checked
1506 2) globally enforcing a check
1507 3) principal requires checking
1508 4) we allow non-check per-principal, but principal isn't marked as allowing this
1509 5) we don't globally allow this
1512 #define GLOBAL_FORCE_TRANSITED_CHECK (trpolicy == TRPOLICY_ALWAYS_CHECK)
1513 #define GLOBAL_ALLOW_PER_PRINCIPAL (trpolicy == TRPOLICY_ALLOW_PER_PRINCIPAL)
1514 #define GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK (trpolicy == TRPOLICY_ALWAYS_HONOUR_REQUEST)
1515 /* these will consult the database in future release */
1516 #define PRINCIPAL_FORCE_TRANSITED_CHECK(P) 0
1517 #define PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(P) 0
1519 ret
= fix_transited_encoding(!f
.disable_transited_check
||
1520 GLOBAL_FORCE_TRANSITED_CHECK
||
1521 PRINCIPAL_FORCE_TRANSITED_CHECK(server
) ||
1522 !((GLOBAL_ALLOW_PER_PRINCIPAL
&&
1523 PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(server
)) ||
1524 GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK
),
1525 &tgt
->transited
, &et
,
1526 *krb5_princ_realm(context
, client_principal
),
1527 *krb5_princ_realm(context
, server
->principal
),
1528 *krb5_princ_realm(context
, krbtgt
->principal
));
1532 copy_Realm(krb5_princ_realm(context
, server
->principal
),
1534 _krb5_principal2principalname(&rep
.ticket
.sname
, server
->principal
);
1535 copy_Realm(&tgt
->crealm
, &rep
.crealm
);
1536 if (f
.request_anonymous
)
1537 make_anonymous_principalname (&tgt
->cname
);
1539 copy_PrincipalName(&tgt
->cname
, &rep
.cname
);
1540 rep
.ticket
.tkt_vno
= 5;
1542 ek
.caddr
= et
.caddr
;
1543 if(et
.caddr
== NULL
)
1544 et
.caddr
= tgt
->caddr
;
1548 life
= et
.endtime
- *et
.starttime
;
1549 if(client
&& client
->max_life
)
1550 life
= min(life
, *client
->max_life
);
1551 if(server
->max_life
)
1552 life
= min(life
, *server
->max_life
);
1553 et
.endtime
= *et
.starttime
+ life
;
1555 if(f
.renewable_ok
&& tgt
->flags
.renewable
&&
1556 et
.renew_till
== NULL
&& et
.endtime
< *b
->till
){
1557 et
.flags
.renewable
= 1;
1558 ALLOC(et
.renew_till
);
1559 *et
.renew_till
= *b
->till
;
1563 renew
= *et
.renew_till
- et
.authtime
;
1564 if(client
&& client
->max_renew
)
1565 renew
= min(renew
, *client
->max_renew
);
1566 if(server
->max_renew
)
1567 renew
= min(renew
, *server
->max_renew
);
1568 *et
.renew_till
= et
.authtime
+ renew
;
1572 *et
.renew_till
= min(*et
.renew_till
, *tgt
->renew_till
);
1573 *et
.starttime
= min(*et
.starttime
, *et
.renew_till
);
1574 et
.endtime
= min(et
.endtime
, *et
.renew_till
);
1577 *et
.starttime
= min(*et
.starttime
, et
.endtime
);
1579 if(*et
.starttime
== et
.endtime
){
1580 ret
= KRB5KDC_ERR_NEVER_VALID
;
1583 if(et
.renew_till
&& et
.endtime
== *et
.renew_till
){
1584 free(et
.renew_till
);
1585 et
.renew_till
= NULL
;
1586 et
.flags
.renewable
= 0;
1589 et
.flags
.pre_authent
= tgt
->flags
.pre_authent
;
1590 et
.flags
.hw_authent
= tgt
->flags
.hw_authent
;
1591 et
.flags
.anonymous
= tgt
->flags
.anonymous
;
1592 et
.flags
.ok_as_delegate
= server
->flags
.ok_as_delegate
;
1594 /* XXX Check enc-authorization-data */
1595 et
.authorization_data
= auth_data
;
1597 krb5_generate_random_keyblock(context
, etype
, &et
.key
);
1598 et
.crealm
= tgt
->crealm
;
1599 et
.cname
= tgt
->cname
;
1602 /* MIT must have at least one last_req */
1603 ek
.last_req
.len
= 1;
1604 ek
.last_req
.val
= calloc(1, sizeof(*ek
.last_req
.val
));
1605 ek
.nonce
= b
->nonce
;
1606 ek
.flags
= et
.flags
;
1607 ek
.authtime
= et
.authtime
;
1608 ek
.starttime
= et
.starttime
;
1609 ek
.endtime
= et
.endtime
;
1610 ek
.renew_till
= et
.renew_till
;
1611 ek
.srealm
= rep
.ticket
.realm
;
1612 ek
.sname
= rep
.ticket
.sname
;
1614 /* It is somewhat unclear where the etype in the following
1615 encryption should come from. What we have is a session
1616 key in the passed tgt, and a list of preferred etypes
1617 *for the new ticket*. Should we pick the best possible
1618 etype, given the keytype in the tgt, or should we look
1619 at the etype list here as well? What if the tgt
1620 session key is DES3 and we want a ticket with a (say)
1621 CAST session key. Should the DES3 etype be added to the
1622 etype list, even if we don't want a session key with
1624 ret
= encode_reply(&rep
, &et
, &ek
, etype
, adtkt
? 0 : server
->kvno
, ekey
,
1625 0, &tgt
->key
, e_text
, reply
);
1628 free_TransitedEncoding(&et
.transited
);
1632 free(et
.renew_till
);
1633 free_LastReq(&ek
.last_req
);
1634 memset(et
.key
.keyvalue
.data
, 0, et
.key
.keyvalue
.length
);
1635 free_EncryptionKey(&et
.key
);
1639 static krb5_error_code
1640 tgs_check_authenticator(krb5_auth_context ac
,
1642 const char **e_text
,
1645 krb5_authenticator auth
;
1649 krb5_error_code ret
;
1652 krb5_auth_con_getauthenticator(context
, ac
, &auth
);
1653 if(auth
->cksum
== NULL
){
1654 kdc_log(0, "No authenticator in request");
1655 ret
= KRB5KRB_AP_ERR_INAPP_CKSUM
;
1659 * according to RFC1510 it doesn't need to be keyed,
1660 * but according to the latest draft it needs to.
1664 !krb5_checksum_is_keyed(context
, auth
->cksum
->cksumtype
)
1667 !krb5_checksum_is_collision_proof(context
, auth
->cksum
->cksumtype
)) {
1668 kdc_log(0, "Bad checksum type in authenticator: %d",
1669 auth
->cksum
->cksumtype
);
1670 ret
= KRB5KRB_AP_ERR_INAPP_CKSUM
;
1674 /* XXX should not re-encode this */
1675 ASN1_MALLOC_ENCODE(KDC_REQ_BODY
, buf
, buf_size
, b
, &len
, ret
);
1677 kdc_log(0, "Failed to encode KDC-REQ-BODY: %s",
1678 krb5_get_err_text(context
, ret
));
1681 if(buf_size
!= len
) {
1683 kdc_log(0, "Internal error in ASN.1 encoder");
1684 *e_text
= "KDC internal error";
1685 ret
= KRB5KRB_ERR_GENERIC
;
1688 ret
= krb5_crypto_init(context
, key
, 0, &crypto
);
1691 kdc_log(0, "krb5_crypto_init failed: %s",
1692 krb5_get_err_text(context
, ret
));
1695 ret
= krb5_verify_checksum(context
,
1697 KRB5_KU_TGS_REQ_AUTH_CKSUM
,
1702 krb5_crypto_destroy(context
, crypto
);
1704 kdc_log(0, "Failed to verify checksum: %s",
1705 krb5_get_err_text(context
, ret
));
1708 free_Authenticator(auth
);
1714 * return the realm of a krbtgt-ticket or NULL
1718 get_krbtgt_realm(const PrincipalName
*p
)
1720 if(p
->name_string
.len
== 2
1721 && strcmp(p
->name_string
.val
[0], KRB5_TGS_NAME
) == 0)
1722 return p
->name_string
.val
[1];
1728 find_rpath(Realm crealm
, Realm srealm
)
1730 const char *new_realm
= krb5_config_get_string(context
,
1736 return (Realm
)new_realm
;
1741 need_referral(krb5_principal server
, krb5_realm
**realms
)
1743 if(server
->name
.name_type
!= KRB5_NT_SRV_INST
||
1744 server
->name
.name_string
.len
!= 2)
1747 return _krb5_get_host_realm_int(context
, server
->name
.name_string
.val
[1],
1748 FALSE
, realms
) == 0;
1751 static krb5_error_code
1752 tgs_rep2(KDC_REQ_BODY
*b
,
1756 const struct sockaddr
*from_addr
,
1761 krb5_error_code ret
;
1762 krb5_principal princ
;
1763 krb5_auth_context ac
= NULL
;
1764 krb5_ticket
*ticket
= NULL
;
1765 krb5_flags ap_req_options
;
1766 krb5_flags verify_ap_req_flags
;
1767 const char *e_text
= NULL
;
1770 hdb_entry
*krbtgt
= NULL
;
1773 krb5_enctype cetype
;
1774 krb5_principal cp
= NULL
;
1775 krb5_principal sp
= NULL
;
1776 AuthorizationData
*auth_data
= NULL
;
1781 memset(&ap_req
, 0, sizeof(ap_req
));
1782 ret
= krb5_decode_ap_req(context
, &tgs_req
->padata_value
, &ap_req
);
1784 kdc_log(0, "Failed to decode AP-REQ: %s",
1785 krb5_get_err_text(context
, ret
));
1789 if(!get_krbtgt_realm(&ap_req
.ticket
.sname
)){
1790 /* XXX check for ticket.sname == req.sname */
1791 kdc_log(0, "PA-DATA is not a ticket-granting ticket");
1792 ret
= KRB5KDC_ERR_POLICY
; /* ? */
1796 _krb5_principalname2krb5_principal(&princ
,
1797 ap_req
.ticket
.sname
,
1798 ap_req
.ticket
.realm
);
1800 ret
= db_fetch(princ
, &krbtgt
);
1804 ret
= krb5_unparse_name(context
, princ
, &p
);
1806 p
= "<unparse_name failed>";
1807 krb5_free_principal(context
, princ
);
1808 kdc_log(0, "Ticket-granting ticket not found in database: %s: %s",
1809 p
, krb5_get_err_text(context
, ret
));
1812 ret
= KRB5KRB_AP_ERR_NOT_US
;
1816 if(ap_req
.ticket
.enc_part
.kvno
&&
1817 *ap_req
.ticket
.enc_part
.kvno
!= krbtgt
->kvno
){
1820 ret
= krb5_unparse_name (context
, princ
, &p
);
1821 krb5_free_principal(context
, princ
);
1823 p
= "<unparse_name failed>";
1824 kdc_log(0, "Ticket kvno = %d, DB kvno = %d (%s)",
1825 *ap_req
.ticket
.enc_part
.kvno
,
1830 ret
= KRB5KRB_AP_ERR_BADKEYVER
;
1834 ret
= hdb_enctype2key(context
, krbtgt
, ap_req
.ticket
.enc_part
.etype
, &tkey
);
1837 krb5_enctype_to_string(context
, ap_req
.ticket
.enc_part
.etype
, &str
);
1838 kdc_log(0, "No server key found for %s", str
);
1840 ret
= KRB5KRB_AP_ERR_BADKEYVER
;
1844 if (b
->kdc_options
.validate
)
1845 verify_ap_req_flags
= KRB5_VERIFY_AP_REQ_IGNORE_INVALID
;
1847 verify_ap_req_flags
= 0;
1849 ret
= krb5_verify_ap_req2(context
,
1854 verify_ap_req_flags
,
1857 KRB5_KU_TGS_REQ_AUTH
);
1859 krb5_free_principal(context
, princ
);
1861 kdc_log(0, "Failed to verify AP-REQ: %s",
1862 krb5_get_err_text(context
, ret
));
1867 krb5_authenticator auth
;
1869 ret
= krb5_auth_con_getauthenticator(context
, ac
, &auth
);
1871 *csec
= malloc(sizeof(**csec
));
1872 if (*csec
== NULL
) {
1873 krb5_free_authenticator(context
, &auth
);
1874 kdc_log(0, "malloc failed");
1877 **csec
= auth
->ctime
;
1878 *cusec
= malloc(sizeof(**cusec
));
1879 if (*cusec
== NULL
) {
1880 krb5_free_authenticator(context
, &auth
);
1881 kdc_log(0, "malloc failed");
1884 **csec
= auth
->cusec
;
1885 krb5_free_authenticator(context
, &auth
);
1889 cetype
= ap_req
.authenticator
.etype
;
1891 tgt
= &ticket
->ticket
;
1893 ret
= tgs_check_authenticator(ac
, b
, &e_text
, &tgt
->key
);
1895 if (b
->enc_authorization_data
) {
1896 krb5_keyblock
*subkey
;
1898 ret
= krb5_auth_con_getremotesubkey(context
,
1902 krb5_auth_con_free(context
, ac
);
1903 kdc_log(0, "Failed to get remote subkey: %s",
1904 krb5_get_err_text(context
, ret
));
1908 ret
= krb5_auth_con_getkey(context
, ac
, &subkey
);
1910 krb5_auth_con_free(context
, ac
);
1911 kdc_log(0, "Failed to get session key: %s",
1912 krb5_get_err_text(context
, ret
));
1917 krb5_auth_con_free(context
, ac
);
1918 kdc_log(0, "Failed to get key for enc-authorization-data");
1919 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
; /* ? */
1922 ret
= krb5_crypto_init(context
, subkey
, 0, &crypto
);
1924 krb5_auth_con_free(context
, ac
);
1925 kdc_log(0, "krb5_crypto_init failed: %s",
1926 krb5_get_err_text(context
, ret
));
1929 ret
= krb5_decrypt_EncryptedData (context
,
1931 KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY
,
1932 b
->enc_authorization_data
,
1934 krb5_crypto_destroy(context
, crypto
);
1936 krb5_auth_con_free(context
, ac
);
1937 kdc_log(0, "Failed to decrypt enc-authorization-data");
1938 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
; /* ? */
1941 krb5_free_keyblock(context
, subkey
);
1943 ret
= decode_AuthorizationData(ad
.data
, ad
.length
, auth_data
, NULL
);
1945 krb5_auth_con_free(context
, ac
);
1948 kdc_log(0, "Failed to decode authorization data");
1949 ret
= KRB5KRB_AP_ERR_BAD_INTEGRITY
; /* ? */
1954 krb5_auth_con_free(context
, ac
);
1957 kdc_log(0, "Failed to verify authenticator: %s",
1958 krb5_get_err_text(context
, ret
));
1965 char *spn
= NULL
, *cpn
= NULL
;
1966 hdb_entry
*server
= NULL
, *client
= NULL
;
1968 EncTicketPart adtkt
;
1973 if(b
->kdc_options
.enc_tkt_in_skey
){
1979 if(b
->additional_tickets
== NULL
||
1980 b
->additional_tickets
->len
== 0){
1981 ret
= KRB5KDC_ERR_BADOPTION
; /* ? */
1982 kdc_log(0, "No second ticket present in request");
1985 t
= &b
->additional_tickets
->val
[0];
1986 if(!get_krbtgt_realm(&t
->sname
)){
1987 kdc_log(0, "Additional ticket is not a ticket-granting ticket");
1988 ret
= KRB5KDC_ERR_POLICY
;
1991 _krb5_principalname2krb5_principal(&p
, t
->sname
, t
->realm
);
1992 ret
= db_fetch(p
, &uu
);
1993 krb5_free_principal(context
, p
);
1995 if (ret
== HDB_ERR_NOENTRY
)
1996 ret
= KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
;
1999 ret
= hdb_enctype2key(context
, uu
, t
->enc_part
.etype
, &tkey
);
2001 ret
= KRB5KDC_ERR_ETYPE_NOSUPP
; /* XXX */
2004 ret
= krb5_decrypt_ticket(context
, t
, &tkey
->key
, &adtkt
, 0);
2012 _krb5_principalname2krb5_principal(&sp
, *s
, r
);
2013 ret
= krb5_unparse_name(context
, sp
, &spn
);
2016 _krb5_principalname2krb5_principal(&cp
, tgt
->cname
, tgt
->crealm
);
2017 ret
= krb5_unparse_name(context
, cp
, &cpn
);
2020 unparse_flags (KDCOptions2int(b
->kdc_options
),
2021 asn1_KDCOptions_units(),
2022 opt_str
, sizeof(opt_str
));
2024 kdc_log(0, "TGS-REQ %s from %s for %s [%s]",
2025 cpn
, from
, spn
, opt_str
);
2027 kdc_log(0, "TGS-REQ %s from %s for %s", cpn
, from
, spn
);
2029 ret
= db_fetch(sp
, &server
);
2032 Realm req_rlm
, new_rlm
;
2035 if ((req_rlm
= get_krbtgt_realm(&sp
->name
)) != NULL
) {
2037 new_rlm
= find_rpath(tgt
->crealm
, req_rlm
);
2039 kdc_log(5, "krbtgt for realm %s not found, trying %s",
2041 krb5_free_principal(context
, sp
);
2043 krb5_make_principal(context
, &sp
, r
,
2044 KRB5_TGS_NAME
, new_rlm
, NULL
);
2045 ret
= krb5_unparse_name(context
, sp
, &spn
);
2051 } else if(need_referral(sp
, &realms
)) {
2052 if (strcmp(realms
[0], sp
->realm
) != 0) {
2053 kdc_log(5, "returning a referral to realm %s for "
2054 "server %s that was not found",
2056 krb5_free_principal(context
, sp
);
2058 krb5_make_principal(context
, &sp
, r
, KRB5_TGS_NAME
,
2060 ret
= krb5_unparse_name(context
, sp
, &spn
);
2063 krb5_free_host_realm(context
, realms
);
2066 krb5_free_host_realm(context
, realms
);
2068 kdc_log(0, "Server not found in database: %s: %s", spn
,
2069 krb5_get_err_text(context
, ret
));
2070 if (ret
== HDB_ERR_NOENTRY
)
2071 ret
= KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
;
2075 ret
= db_fetch(cp
, &client
);
2077 kdc_log(1, "Client not found in database: %s: %s",
2078 cpn
, krb5_get_err_text(context
, ret
));
2080 /* XXX check client only if same realm as krbtgt-instance */
2082 kdc_log(0, "Client not found in database: %s: %s",
2083 cpn
, krb5_get_err_text(context
, ret
));
2084 if (ret
== HDB_ERR_NOENTRY
)
2085 ret
= KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN
;
2090 if(strcmp(krb5_principal_get_realm(context
, sp
),
2091 krb5_principal_get_comp_string(context
, krbtgt
->principal
, 1)) != 0) {
2093 ret
= krb5_unparse_name(context
, krbtgt
->principal
, &tpn
);
2094 kdc_log(0, "Request with wrong krbtgt: %s", (ret
== 0) ? tpn
: "<unknown>");
2097 ret
= KRB5KRB_AP_ERR_NOT_US
;
2102 ret
= check_flags(client
, cpn
, server
, spn
, FALSE
);
2106 if((b
->kdc_options
.validate
|| b
->kdc_options
.renew
) &&
2107 !krb5_principal_compare(context
,
2109 server
->principal
)){
2110 kdc_log(0, "Inconsistent request.");
2111 ret
= KRB5KDC_ERR_SERVER_NOMATCH
;
2115 /* check for valid set of addresses */
2116 if(!check_addresses(tgt
->caddr
, from_addr
)) {
2117 ret
= KRB5KRB_AP_ERR_BADADDR
;
2118 kdc_log(0, "Request from wrong address");
2122 ret
= tgs_make_reply(b
,
2124 b
->kdc_options
.enc_tkt_in_skey
? &adtkt
: NULL
,
2145 krb5_mk_error(context
,
2159 krb5_free_principal(context
, cp
);
2160 krb5_free_principal(context
, sp
);
2162 krb5_free_ticket(context
, ticket
);
2163 free_AP_REQ(&ap_req
);
2165 free_AuthorizationData(auth_data
);
2177 tgs_rep(KDC_REQ
*req
,
2180 struct sockaddr
*from_addr
)
2182 krb5_error_code ret
;
2184 PA_DATA
*tgs_req
= NULL
;
2185 time_t *csec
= NULL
;
2188 if(req
->padata
== NULL
){
2189 ret
= KRB5KDC_ERR_PREAUTH_REQUIRED
; /* XXX ??? */
2190 kdc_log(0, "TGS-REQ from %s without PA-DATA", from
);
2194 tgs_req
= find_padata(req
, &i
, KRB5_PADATA_TGS_REQ
);
2196 if(tgs_req
== NULL
){
2197 ret
= KRB5KDC_ERR_PADATA_TYPE_NOSUPP
;
2199 kdc_log(0, "TGS-REQ from %s without PA-TGS-REQ", from
);
2202 ret
= tgs_rep2(&req
->req_body
, tgs_req
, data
, from
, from_addr
,
2205 if(ret
&& data
->data
== NULL
){
2206 krb5_mk_error(context
,