krb5: support for canonical name in PAC

If the UPN_DNS_INFO buffer in the Windows PAC contains a canonical principal
name, use it in lieu of the ticket client name to determine the GSS-API
initiator name.
This commit is contained in:
Luke Howard
2021-09-23 13:39:36 +10:00
parent b3bb3ac49d
commit 0ab3b7b2dd
11 changed files with 493 additions and 7 deletions

View File

@@ -1823,3 +1823,99 @@ cleanup:
}
return ret;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
_krb5_ret_data_at_offset(krb5_storage *sp,
size_t offset,
size_t length,
krb5_data *data)
{
krb5_error_code ret;
off_t cur, size;
krb5_data_zero(data);
cur = sp->seek(sp, 0, SEEK_CUR);
if (cur < 0)
return HEIM_ERR_NOT_SEEKABLE;
size = sp->seek(sp, 0, SEEK_END);
if (offset + length > size) {
ret = ERANGE;
goto cleanup;
}
ret = krb5_data_alloc(data, length);
if (ret)
goto cleanup;
if (length) {
sp->seek(sp, offset, SEEK_SET);
size = sp->fetch(sp, data->data, length);
heim_assert(size == length, "incomplete buffer fetched");
}
cleanup:
sp->seek(sp, cur, SEEK_SET);
return ret;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
_krb5_ret_utf8_from_ucs2le_at_offset(krb5_storage *sp,
size_t offset,
size_t length,
char **utf8)
{
krb5_error_code ret;
krb5_data data;
size_t ucs2len = length / 2;
uint16_t *ucs2 = NULL;
size_t u8len;
unsigned int flags = WIND_RW_LE;
*utf8 = NULL;
krb5_data_zero(&data);
ret = _krb5_ret_data_at_offset(sp, offset, length, &data);
if (ret)
goto out;
ucs2 = malloc(sizeof(ucs2[0]) * ucs2len);
if (ucs2 == NULL) {
ret = ENOMEM;
goto out;
}
ret = wind_ucs2read(data.data, data.length, &flags, ucs2, &ucs2len);
if (ret)
goto out;
ret = wind_ucs2utf8_length(ucs2, ucs2len, &u8len);
if (ret)
goto out;
u8len += 1; /* Add space for NUL */
*utf8 = malloc(u8len);
if (*utf8 == NULL) {
ret = ENOMEM;
goto out;
}
ret = wind_ucs2utf8(ucs2, ucs2len, *utf8, &u8len);
if (ret)
goto out;
out:
if (ret && *utf8) {
free(*utf8);
*utf8 = NULL;
}
free(ucs2);
krb5_data_free(&data);
return ret;
}