krb5: Add support for AD-KDC-ISSUED
This commit is contained in:

committed by
Nico Williams

parent
87f8c0d2b5
commit
1cede09a0b
@@ -462,8 +462,9 @@ PrincipalNameAttrSrc ::= CHOICE {
|
|||||||
enc-ticket-part [1] EncTicketPart -- minus session key
|
enc-ticket-part [1] EncTicketPart -- minus session key
|
||||||
}
|
}
|
||||||
PrincipalNameAttrs ::= SEQUENCE {
|
PrincipalNameAttrs ::= SEQUENCE {
|
||||||
|
-- True if this name was authenticated via an AP-REQ or a KDC-REP
|
||||||
authenticated [0] BOOLEAN,
|
authenticated [0] BOOLEAN,
|
||||||
-- These are compiled from the Ticket and Authenticator:
|
-- These are compiled from the Ticket, KDC-REP, and/or Authenticator
|
||||||
source [1] PrincipalNameAttrSrc OPTIONAL,
|
source [1] PrincipalNameAttrSrc OPTIONAL,
|
||||||
authenticator-ad [2] AuthorizationData OPTIONAL,
|
authenticator-ad [2] AuthorizationData OPTIONAL,
|
||||||
-- For the server on the client side we should keep track of the
|
-- For the server on the client side we should keep track of the
|
||||||
@@ -472,7 +473,10 @@ PrincipalNameAttrs ::= SEQUENCE {
|
|||||||
-- We don't learn much more about the server from the KDC.
|
-- We don't learn much more about the server from the KDC.
|
||||||
peer-realm [3] Realm OPTIONAL,
|
peer-realm [3] Realm OPTIONAL,
|
||||||
transited [4] TransitedEncoding OPTIONAL,
|
transited [4] TransitedEncoding OPTIONAL,
|
||||||
pac-verified [5] BOOLEAN
|
-- True if the PAC was verified
|
||||||
|
pac-verified [5] BOOLEAN,
|
||||||
|
-- True if any AD-KDC-ISSUEDs in the Ticket were validated
|
||||||
|
kdc-issued-verified [6] BOOLEAN
|
||||||
-- TODO: Add requested attributes, for gss_set_name_attribute(), which
|
-- TODO: Add requested attributes, for gss_set_name_attribute(), which
|
||||||
-- should cause corresponding authz-data elements to be added to
|
-- should cause corresponding authz-data elements to be added to
|
||||||
-- any TGS-REQ or to the AP-REQ's Authenticator as appropriate.
|
-- any TGS-REQ or to the AP-REQ's Authenticator as appropriate.
|
||||||
|
@@ -1037,6 +1037,12 @@ krb5_rd_req_ctx(krb5_context context,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = krb5_ticket_get_authorization_data_type(context, o->ticket,
|
||||||
|
KRB5_AUTHDATA_KDC_ISSUED,
|
||||||
|
NULL);
|
||||||
|
if (ret == 0)
|
||||||
|
o->ticket->client->nameattrs->kdc_issued_verified = 1;
|
||||||
|
|
||||||
/* If there is a PAC, verify its server signature */
|
/* If there is a PAC, verify its server signature */
|
||||||
if (inctx == NULL || inctx->check_pac) {
|
if (inctx == NULL || inctx->check_pac) {
|
||||||
krb5_pac pac;
|
krb5_pac pac;
|
||||||
|
@@ -204,13 +204,38 @@ krb5_ticket_get_flags(krb5_context context,
|
|||||||
return TicketFlags2int(ticket->ticket.flags);
|
return TicketFlags2int(ticket->ticket.flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find an authz-data element in the given `ad'. If `failp', then validate any
|
||||||
|
* containing AD-KDC-ISSUED's keyed checksum with the `sessionkey' (if given).
|
||||||
|
*
|
||||||
|
* All AD-KDC-ISSUED will be validated (if requested) even when `type' is
|
||||||
|
* `KRB5_AUTHDATA_KDC_ISSUED'.
|
||||||
|
*
|
||||||
|
* Only the first matching element will be output (via `data').
|
||||||
|
*
|
||||||
|
* Note that all AD-KDC-ISSUEDs found while traversing the authz-data will be
|
||||||
|
* validated, though only the first one will be returned.
|
||||||
|
*
|
||||||
|
* XXX We really need a better interface though. First, forget AD-AND-OR --
|
||||||
|
* just remove it. Second, probably forget AD-KDC-ISSUED, but still, between
|
||||||
|
* that, the PAC, and the CAMMAC, we need an interface that can:
|
||||||
|
*
|
||||||
|
* a) take the derived keys instead of the service key or the session key,
|
||||||
|
* b) can indicate whether the element was marked critical,
|
||||||
|
* c) can indicate whether the element was authenticated to the KDC,
|
||||||
|
* d) can iterate over all the instances found (if more than one is found).
|
||||||
|
*
|
||||||
|
* Also, we need to know here if the authz-data is from a Ticket or from an
|
||||||
|
* Authenticator -- if the latter then we must refuse to find AD-KDC-ISSUED /
|
||||||
|
* PAC / CAMMAC or anything of the sort, ever.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
find_type_in_ad(krb5_context context,
|
find_type_in_ad(krb5_context context,
|
||||||
int type,
|
int type,
|
||||||
krb5_data *data,
|
krb5_data *data, /* optional */
|
||||||
krb5_boolean *found,
|
krb5_boolean *found,
|
||||||
krb5_boolean failp,
|
krb5_boolean failp, /* validate AD-KDC-ISSUED */
|
||||||
krb5_keyblock *sessionkey,
|
krb5_keyblock *sessionkey, /* ticket session key */
|
||||||
const AuthorizationData *ad,
|
const AuthorizationData *ad,
|
||||||
int level)
|
int level)
|
||||||
{
|
{
|
||||||
@@ -233,14 +258,19 @@ find_type_in_ad(krb5_context context,
|
|||||||
*/
|
*/
|
||||||
for (i = 0; i < ad->len; i++) {
|
for (i = 0; i < ad->len; i++) {
|
||||||
if (!*found && ad->val[i].ad_type == type) {
|
if (!*found && ad->val[i].ad_type == type) {
|
||||||
ret = der_copy_octet_string(&ad->val[i].ad_data, data);
|
if (data) {
|
||||||
if (ret) {
|
ret = der_copy_octet_string(&ad->val[i].ad_data, data);
|
||||||
krb5_set_error_message(context, ret,
|
if (ret) {
|
||||||
N_("malloc: out of memory", ""));
|
krb5_set_error_message(context, ret,
|
||||||
goto out;
|
N_("malloc: out of memory", ""));
|
||||||
}
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
*found = TRUE;
|
*found = TRUE;
|
||||||
continue;
|
if (type != KRB5_AUTHDATA_KDC_ISSUED ||
|
||||||
|
!failp || !sessionkey || !sessionkey->keyvalue.length)
|
||||||
|
continue;
|
||||||
|
/* else go on to validate the AD-KDC-ISSUED's keyed checksum */
|
||||||
}
|
}
|
||||||
switch (ad->val[i].ad_type) {
|
switch (ad->val[i].ad_type) {
|
||||||
case KRB5_AUTHDATA_IF_RELEVANT: {
|
case KRB5_AUTHDATA_IF_RELEVANT: {
|
||||||
@@ -263,7 +293,6 @@ find_type_in_ad(krb5_context context,
|
|||||||
goto out;
|
goto out;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#if 0 /* XXX test */
|
|
||||||
case KRB5_AUTHDATA_KDC_ISSUED: {
|
case KRB5_AUTHDATA_KDC_ISSUED: {
|
||||||
AD_KDCIssued child;
|
AD_KDCIssued child;
|
||||||
|
|
||||||
@@ -278,7 +307,7 @@ find_type_in_ad(krb5_context context,
|
|||||||
ret);
|
ret);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (failp) {
|
if (failp && sessionkey && sessionkey->keyvalue.length) {
|
||||||
krb5_boolean valid;
|
krb5_boolean valid;
|
||||||
krb5_data buf;
|
krb5_data buf;
|
||||||
size_t len;
|
size_t len;
|
||||||
@@ -306,7 +335,12 @@ find_type_in_ad(krb5_context context,
|
|||||||
free_AD_KDCIssued(&child);
|
free_AD_KDCIssued(&child);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
} else if (failp) {
|
||||||
|
krb5_clear_error_message(context);
|
||||||
|
ret = ENOENT;
|
||||||
|
free_AD_KDCIssued(&child);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
ret = find_type_in_ad(context, type, data, found, failp, sessionkey,
|
ret = find_type_in_ad(context, type, data, found, failp, sessionkey,
|
||||||
&child.elements, level + 1);
|
&child.elements, level + 1);
|
||||||
free_AD_KDCIssued(&child);
|
free_AD_KDCIssued(&child);
|
||||||
@@ -314,7 +348,6 @@ find_type_in_ad(krb5_context context,
|
|||||||
goto out;
|
goto out;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
case KRB5_AUTHDATA_AND_OR:
|
case KRB5_AUTHDATA_AND_OR:
|
||||||
if (!failp)
|
if (!failp)
|
||||||
break;
|
break;
|
||||||
@@ -338,7 +371,8 @@ find_type_in_ad(krb5_context context,
|
|||||||
out:
|
out:
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (*found) {
|
if (*found) {
|
||||||
krb5_data_free(data);
|
if (data)
|
||||||
|
krb5_data_free(data);
|
||||||
*found = 0;
|
*found = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -355,7 +389,8 @@ _krb5_get_ad(krb5_context context,
|
|||||||
krb5_boolean found = FALSE;
|
krb5_boolean found = FALSE;
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
|
|
||||||
krb5_data_zero(data);
|
if (data)
|
||||||
|
krb5_data_zero(data);
|
||||||
|
|
||||||
if (ad == NULL) {
|
if (ad == NULL) {
|
||||||
krb5_set_error_message(context, ENOENT,
|
krb5_set_error_message(context, ENOENT,
|
||||||
@@ -399,7 +434,8 @@ krb5_ticket_get_authorization_data_type(krb5_context context,
|
|||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
krb5_boolean found = FALSE;
|
krb5_boolean found = FALSE;
|
||||||
|
|
||||||
krb5_data_zero(data);
|
if (data)
|
||||||
|
krb5_data_zero(data);
|
||||||
|
|
||||||
ad = ticket->ticket.authorization_data;
|
ad = ticket->ticket.authorization_data;
|
||||||
if (ticket->ticket.authorization_data == NULL) {
|
if (ticket->ticket.authorization_data == NULL) {
|
||||||
|
Reference in New Issue
Block a user