#include "k5-int.h"
#include "int-proto.h"
#include "authdata.h"
+#include "k5-input.h"
#define MAX_BUFFERS 4096
-/* draft-brezak-win2k-krb-authz-00 */
-
/*
- * Add a buffer to the provided PAC and update header.
+ * Add a buffer containing data to pac's metadata and encoding. If zerofill is
+ * true, data->data must be NULL and the buffer will be zero-filled with length
+ * data->length.
*/
krb5_error_code
-k5_pac_add_buffer(krb5_context context,
- krb5_pac pac,
- krb5_ui_4 type,
- const krb5_data *data,
- krb5_boolean zerofill,
- krb5_data *out_data)
+k5_pac_add_buffer(krb5_context context, krb5_pac pac, uint32_t type,
+ const krb5_data *data, krb5_boolean zerofill,
+ krb5_data *data_out)
{
- PACTYPE *header;
+ struct k5_pac_buffer *nbufs;
size_t header_len, i, pad = 0;
- char *pac_data;
+ char *ndata, *bufdata;
assert((data->data == NULL) == zerofill);
- /* Check there isn't already a buffer of this type */
- if (k5_pac_locate_buffer(context, pac, type, NULL) == 0) {
+ /* Check for an existing buffer of this type. */
+ if (k5_pac_locate_buffer(context, pac, type, NULL) == 0)
return EEXIST;
- }
- header = (PACTYPE *)realloc(pac->pac,
- sizeof(PACTYPE) +
- (pac->pac->cBuffers * sizeof(PAC_INFO_BUFFER)));
- if (header == NULL) {
+ if (pac->nbuffers >= MAX_BUFFERS)
+ return ERANGE;
+ nbufs = realloc(pac->buffers, (pac->nbuffers + 1) * sizeof(*pac->buffers));
+ if (nbufs == NULL)
return ENOMEM;
- }
- pac->pac = header;
+ pac->buffers = nbufs;
- header_len = PACTYPE_LENGTH + (pac->pac->cBuffers * PAC_INFO_BUFFER_LENGTH);
+ header_len = PACTYPE_LENGTH + pac->nbuffers * PAC_INFO_BUFFER_LENGTH;
if (data->length % PAC_ALIGNMENT)
pad = PAC_ALIGNMENT - (data->length % PAC_ALIGNMENT);
-
- pac_data = realloc(pac->data.data,
- pac->data.length + PAC_INFO_BUFFER_LENGTH + data->length + pad);
- if (pac_data == NULL) {
+ ndata = realloc(pac->data.data,
+ pac->data.length + PAC_INFO_BUFFER_LENGTH +
+ data->length + pad);
+ if (ndata == NULL)
return ENOMEM;
- }
- pac->data.data = pac_data;
+ pac->data.data = ndata;
- /* Update offsets of existing buffers */
- for (i = 0; i < pac->pac->cBuffers; i++)
- pac->pac->Buffers[i].Offset += PAC_INFO_BUFFER_LENGTH;
+ /* Update the offsets of existing buffers. */
+ for (i = 0; i < pac->nbuffers; i++)
+ pac->buffers[i].offset += PAC_INFO_BUFFER_LENGTH;
- /* Make room for new PAC_INFO_BUFFER */
+ /* Make room for the new buffer's metadata. */
memmove(pac->data.data + header_len + PAC_INFO_BUFFER_LENGTH,
pac->data.data + header_len,
pac->data.length - header_len);
memset(pac->data.data + header_len, 0, PAC_INFO_BUFFER_LENGTH);
- /* Initialise new PAC_INFO_BUFFER */
- pac->pac->Buffers[i].ulType = type;
- pac->pac->Buffers[i].cbBufferSize = data->length;
- pac->pac->Buffers[i].Offset = pac->data.length + PAC_INFO_BUFFER_LENGTH;
- assert((pac->pac->Buffers[i].Offset % PAC_ALIGNMENT) == 0);
+ /* Initialize the new buffer. */
+ pac->buffers[i].type = type;
+ pac->buffers[i].size = data->length;
+ pac->buffers[i].offset = pac->data.length + PAC_INFO_BUFFER_LENGTH;
+ assert((pac->buffers[i].offset % PAC_ALIGNMENT) == 0);
- /* Copy in new PAC data and zero padding bytes */
+ /* Copy in new PAC data and zero padding bytes. */
+ bufdata = pac->data.data + pac->buffers[i].offset;
if (zerofill)
- memset(pac->data.data + pac->pac->Buffers[i].Offset, 0, data->length);
+ memset(bufdata, 0, data->length);
else
- memcpy(pac->data.data + pac->pac->Buffers[i].Offset, data->data, data->length);
+ memcpy(bufdata, data->data, data->length);
+ memset(bufdata + data->length, 0, pad);
- memset(pac->data.data + pac->pac->Buffers[i].Offset + data->length, 0, pad);
-
- pac->pac->cBuffers++;
+ pac->nbuffers++;
pac->data.length += PAC_INFO_BUFFER_LENGTH + data->length + pad;
- if (out_data != NULL) {
- out_data->data = pac->data.data + pac->pac->Buffers[i].Offset;
- out_data->length = data->length;
- }
+ if (data_out != NULL)
+ *data_out = make_data(bufdata, data->length);
pac->verified = FALSE;
}
krb5_error_code KRB5_CALLCONV
-krb5_pac_add_buffer(krb5_context context,
- krb5_pac pac,
- krb5_ui_4 type,
+krb5_pac_add_buffer(krb5_context context, krb5_pac pac, uint32_t type,
const krb5_data *data)
{
return k5_pac_add_buffer(context, pac, type, data, FALSE, NULL);
* Free a PAC
*/
void KRB5_CALLCONV
-krb5_pac_free(krb5_context context,
- krb5_pac pac)
+krb5_pac_free(krb5_context context, krb5_pac pac)
{
if (pac != NULL) {
zapfree(pac->data.data, pac->data.length);
- free(pac->pac);
+ free(pac->buffers);
zapfree(pac, sizeof(*pac));
}
}
krb5_error_code
-k5_pac_locate_buffer(krb5_context context,
- const krb5_pac pac,
- krb5_ui_4 type,
- krb5_data *data)
+k5_pac_locate_buffer(krb5_context context, const krb5_pac pac, uint32_t type,
+ krb5_data *data_out)
{
- PAC_INFO_BUFFER *buffer = NULL;
+ struct k5_pac_buffer *buffer = NULL;
size_t i;
if (pac == NULL)
return EINVAL;
- for (i = 0; i < pac->pac->cBuffers; i++) {
- if (pac->pac->Buffers[i].ulType == type) {
+ for (i = 0; i < pac->nbuffers; i++) {
+ if (pac->buffers[i].type == type) {
if (buffer == NULL)
- buffer = &pac->pac->Buffers[i];
+ buffer = &pac->buffers[i];
else
return EINVAL;
}
if (buffer == NULL)
return ENOENT;
- assert(buffer->Offset + buffer->cbBufferSize <= pac->data.length);
+ assert(buffer->offset < pac->data.length);
+ assert(buffer->size <= pac->data.length - buffer->offset);
- if (data != NULL) {
- data->length = buffer->cbBufferSize;
- data->data = pac->data.data + buffer->Offset;
- }
+ if (data_out != NULL)
+ *data_out = make_data(pac->data.data + buffer->offset, buffer->size);
return 0;
}
* Find a buffer and copy data into output
*/
krb5_error_code KRB5_CALLCONV
-krb5_pac_get_buffer(krb5_context context,
- krb5_pac pac,
- krb5_ui_4 type,
- krb5_data *data)
+krb5_pac_get_buffer(krb5_context context, krb5_pac pac, uint32_t type,
+ krb5_data *data_out)
{
krb5_data d;
krb5_error_code ret;
ret = k5_pac_locate_buffer(context, pac, type, &d);
- if (ret != 0)
+ if (ret)
return ret;
- data->data = k5memdup(d.data, d.length, &ret);
- if (data->data == NULL)
+ data_out->data = k5memdup(d.data, d.length, &ret);
+ if (data_out->data == NULL)
return ret;
- data->length = d.length;
-
+ data_out->length = d.length;
return 0;
}
* Return an array of the types of data in the PAC
*/
krb5_error_code KRB5_CALLCONV
-krb5_pac_get_types(krb5_context context,
- krb5_pac pac,
- size_t *len,
- krb5_ui_4 **types)
+krb5_pac_get_types(krb5_context context, krb5_pac pac, size_t *len_out,
+ uint32_t **types_out)
{
size_t i;
- *types = (krb5_ui_4 *)malloc(pac->pac->cBuffers * sizeof(krb5_ui_4));
- if (*types == NULL)
+ *types_out = calloc(pac->nbuffers, sizeof(*types_out));
+ if (*types_out == NULL)
return ENOMEM;
- *len = pac->pac->cBuffers;
+ *len_out = pac->nbuffers;
- for (i = 0; i < pac->pac->cBuffers; i++)
- (*types)[i] = pac->pac->Buffers[i].ulType;
+ for (i = 0; i < pac->nbuffers; i++)
+ (*types_out)[i] = pac->buffers[i].type;
return 0;
}
-/*
- * Initialize PAC
- */
krb5_error_code KRB5_CALLCONV
-krb5_pac_init(krb5_context context,
- krb5_pac *ppac)
+krb5_pac_init(krb5_context context, krb5_pac *pac_out)
{
+ krb5_error_code ret;
krb5_pac pac;
- pac = (krb5_pac)malloc(sizeof(*pac));
- if (pac == NULL)
- return ENOMEM;
+ *pac_out = NULL;
- pac->pac = (PACTYPE *)malloc(sizeof(PACTYPE));
- if (pac->pac == NULL) {
- free(pac);
+ pac = malloc(sizeof(*pac));
+ if (pac == NULL)
return ENOMEM;
- }
- pac->pac->cBuffers = 0;
- pac->pac->Version = 0;
+ pac->nbuffers = 0;
+ pac->buffers = NULL;
+ pac->version = 0;
pac->data.length = PACTYPE_LENGTH;
- pac->data.data = calloc(1, pac->data.length);
+ pac->data.data = k5alloc(pac->data.length, &ret);
if (pac->data.data == NULL) {
- krb5_pac_free(context, pac);
- return ENOMEM;
+ free(pac);
+ return ret;
}
pac->verified = FALSE;
- *ppac = pac;
-
+ *pac_out = pac;
return 0;
}
static krb5_error_code
-k5_pac_copy(krb5_context context,
- krb5_pac src,
- krb5_pac *dst)
+copy_pac(krb5_context context, krb5_pac src, krb5_pac *dst_out)
{
- size_t header_len;
- krb5_ui_4 cbuffers;
- krb5_error_code code;
+ krb5_error_code ret;
krb5_pac pac;
- cbuffers = src->pac->cBuffers;
- if (cbuffers != 0)
- cbuffers--;
-
- header_len = sizeof(PACTYPE) + cbuffers * sizeof(PAC_INFO_BUFFER);
+ *dst_out = NULL;
- pac = (krb5_pac)malloc(sizeof(*pac));
+ pac = k5alloc(sizeof(*pac), &ret);
if (pac == NULL)
- return ENOMEM;
+ goto fail;
- pac->pac = k5memdup(src->pac, header_len, &code);
- if (pac->pac == NULL) {
- free(pac);
- return code;
- }
+ pac->buffers = k5memdup(src->buffers,
+ src->nbuffers * sizeof(*pac->buffers), &ret);
+ if (pac->buffers == NULL)
+ goto fail;
- code = krb5int_copy_data_contents(context, &src->data, &pac->data);
- if (code != 0) {
- free(pac->pac);
- free(pac);
- return ENOMEM;
- }
+ ret = krb5int_copy_data_contents(context, &src->data, &pac->data);
+ if (ret)
+ goto fail;
+ pac->nbuffers = src->nbuffers;
+ pac->version = src->version;
pac->verified = src->verified;
- *dst = pac;
+ *dst_out = pac;
return 0;
+
+fail:
+ krb5_pac_free(context, pac);
+ return ret;
}
-/*
- * Parse the supplied data into the PAC allocated by this function
- */
+/* Parse the supplied data into an allocated PAC. */
krb5_error_code KRB5_CALLCONV
-krb5_pac_parse(krb5_context context,
- const void *ptr,
- size_t len,
+krb5_pac_parse(krb5_context context, const void *ptr, size_t len,
krb5_pac *ppac)
{
krb5_error_code ret;
size_t i;
- const unsigned char *p = (const unsigned char *)ptr;
krb5_pac pac;
size_t header_len;
- krb5_ui_4 cbuffers, version;
+ uint32_t nbuffers, version;
+ struct k5input in;
+ char *ndata;
*ppac = NULL;
- if (len < PACTYPE_LENGTH)
- return ERANGE;
-
- cbuffers = load_32_le(p);
- p += 4;
- version = load_32_le(p);
- p += 4;
+ k5_input_init(&in, ptr, len);
- if (version != 0)
+ nbuffers = k5_input_get_uint32_le(&in);
+ version = k5_input_get_uint32_le(&in);
+ if (in.status || version != 0)
return EINVAL;
- if (cbuffers < 1 || cbuffers > MAX_BUFFERS)
+ if (nbuffers < 1 || nbuffers > MAX_BUFFERS)
return ERANGE;
- header_len = PACTYPE_LENGTH + (cbuffers * PAC_INFO_BUFFER_LENGTH);
+ header_len = PACTYPE_LENGTH + (nbuffers * PAC_INFO_BUFFER_LENGTH);
if (len < header_len)
return ERANGE;
ret = krb5_pac_init(context, &pac);
- if (ret != 0)
+ if (ret)
return ret;
- pac->pac = (PACTYPE *)realloc(pac->pac,
- sizeof(PACTYPE) + ((cbuffers - 1) * sizeof(PAC_INFO_BUFFER)));
- if (pac->pac == NULL) {
- krb5_pac_free(context, pac);
- return ENOMEM;
- }
+ pac->buffers = k5calloc(nbuffers, sizeof(*pac->buffers), &ret);
+ if (ret)
+ goto fail;
- pac->pac->cBuffers = cbuffers;
- pac->pac->Version = version;
+ pac->nbuffers = nbuffers;
+ pac->version = version;
- for (i = 0; i < pac->pac->cBuffers; i++) {
- PAC_INFO_BUFFER *buffer = &pac->pac->Buffers[i];
+ for (i = 0; i < nbuffers; i++) {
+ struct k5_pac_buffer *buffer = &pac->buffers[i];
- buffer->ulType = load_32_le(p);
- p += 4;
- buffer->cbBufferSize = load_32_le(p);
- p += 4;
- buffer->Offset = load_64_le(p);
- p += 8;
+ buffer->type = k5_input_get_uint32_le(&in);
+ buffer->size = k5_input_get_uint32_le(&in);
+ buffer->offset = k5_input_get_uint64_le(&in);
- if (buffer->Offset % PAC_ALIGNMENT) {
- krb5_pac_free(context, pac);
- return EINVAL;
+ if (in.status || buffer->offset % PAC_ALIGNMENT) {
+ ret = EINVAL;
+ goto fail;
}
- if (buffer->Offset < header_len || buffer->Offset > len ||
- buffer->cbBufferSize > len - buffer->Offset) {
- krb5_pac_free(context, pac);
- return ERANGE;
+ if (buffer->offset < header_len || buffer->offset > len ||
+ buffer->size > len - buffer->offset) {
+ ret = ERANGE;
+ goto fail;
}
}
- pac->data.data = realloc(pac->data.data, len);
- if (pac->data.data == NULL) {
+ ndata = realloc(pac->data.data, len);
+ if (ndata == NULL) {
krb5_pac_free(context, pac);
return ENOMEM;
}
- memcpy(pac->data.data, ptr, len);
+ pac->data.data = ndata;
+ memcpy(ndata, ptr, len);
pac->data.length = len;
*ppac = pac;
return 0;
+
+fail:
+ krb5_pac_free(context, pac);
+ return ret;
}
static krb5_error_code
}
krb5_error_code KRB5_CALLCONV
-krb5_pac_get_client_info(krb5_context context,
- const krb5_pac pac,
- krb5_timestamp *authtime_out,
- char **princname_out)
+krb5_pac_get_client_info(krb5_context context, const krb5_pac pac,
+ krb5_timestamp *authtime_out, char **princname_out)
{
krb5_error_code ret;
krb5_data client_info;
char *pac_princname;
unsigned char *p;
krb5_timestamp pac_authtime;
- krb5_ui_2 pac_princname_length;
+ uint16_t pac_princname_length;
uint64_t pac_nt_authtime;
if (authtime_out != NULL)
ret = k5_pac_locate_buffer(context, pac, KRB5_PAC_CLIENT_INFO,
&client_info);
- if (ret != 0)
+ if (ret)
return ret;
if (client_info.length < PAC_CLIENT_INFO_LENGTH)
p += 2;
ret = k5_time_to_seconds_since_1970(pac_nt_authtime, &pac_authtime);
- if (ret != 0)
+ if (ret)
return ret;
if (client_info.length < PAC_CLIENT_INFO_LENGTH + pac_princname_length ||
return ERANGE;
ret = k5_utf16le_to_utf8(p, pac_princname_length, &pac_princname);
- if (ret != 0)
+ if (ret)
return ret;
if (authtime_out != NULL)
}
krb5_error_code
-k5_pac_validate_client(krb5_context context,
- const krb5_pac pac,
- krb5_timestamp authtime,
- krb5_const_principal principal,
+k5_pac_validate_client(krb5_context context, const krb5_pac pac,
+ krb5_timestamp authtime, krb5_const_principal principal,
krb5_boolean with_realm)
{
krb5_error_code ret;
ret = krb5_pac_get_client_info(context, pac, &pac_authtime,
&pac_princname);
- if (ret != 0)
+ if (ret)
return ret;
flags = KRB5_PRINCIPAL_UNPARSE_DISPLAY;
flags |= KRB5_PRINCIPAL_UNPARSE_NO_REALM;
ret = krb5_unparse_name_flags(context, principal, flags, &princname);
- if (ret != 0) {
+ if (ret) {
free(pac_princname);
return ret;
}
return ret;
}
+/* Zero out the signature in a copy of the PAC data. */
static krb5_error_code
-zero_signature(krb5_context context, const krb5_pac pac, krb5_ui_4 type,
+zero_signature(krb5_context context, const krb5_pac pac, uint32_t type,
krb5_data *data)
{
- PAC_INFO_BUFFER *buffer = NULL;
+ struct k5_pac_buffer *buffer = NULL;
size_t i;
assert(type == KRB5_PAC_SERVER_CHECKSUM ||
type == KRB5_PAC_FULL_CHECKSUM);
assert(data->length >= pac->data.length);
- for (i = 0; i < pac->pac->cBuffers; i++) {
- if (pac->pac->Buffers[i].ulType == type) {
- buffer = &pac->pac->Buffers[i];
+ for (i = 0; i < pac->nbuffers; i++) {
+ if (pac->buffers[i].type == type) {
+ buffer = &pac->buffers[i];
break;
}
}
if (buffer == NULL)
return ENOENT;
- if (buffer->Offset + buffer->cbBufferSize > pac->data.length)
- return ERANGE;
-
- if (buffer->cbBufferSize < PAC_SIGNATURE_DATA_LENGTH)
+ if (buffer->size < PAC_SIGNATURE_DATA_LENGTH)
return KRB5_BAD_MSIZE;
+ if (buffer->size > pac->data.length ||
+ buffer->offset > pac->data.length - buffer->size)
+ return ERANGE;
- /* Zero out the data portion of the checksum only */
- memset(data->data + buffer->Offset + PAC_SIGNATURE_DATA_LENGTH,
- 0,
- buffer->cbBufferSize - PAC_SIGNATURE_DATA_LENGTH);
+ /* Within the copy, zero out the data portion of the checksum only. */
+ memset(data->data + buffer->offset + PAC_SIGNATURE_DATA_LENGTH, 0,
+ buffer->size - PAC_SIGNATURE_DATA_LENGTH);
return 0;
}
size_t cksumlen;
ret = k5_pac_locate_buffer(context, pac, buffer_type, &buffer);
- if (ret != 0)
+ if (ret)
return ret;
if (buffer.length < PAC_SIGNATURE_DATA_LENGTH)
return KRB5_BAD_MSIZE;
ret = krb5int_copy_data_contents(context, &pac->data, ©);
if (ret)
return ret;
+
ret = zero_signature(context, pac, KRB5_PAC_SERVER_CHECKSUM, ©);
if (ret)
goto cleanup;
krb5_error_code ret;
krb5_pac pac = NULL;
krb5_data *recoded_tkt = NULL;
- krb5_authdata **authdata, *orig, **ifrel = NULL, **recoded_ifrel = NULL;
+ krb5_authdata **authdata = enc_tkt->authorization_data;
+ krb5_authdata *orig, **ifrel = NULL, **recoded_ifrel = NULL;
uint8_t z = 0;
krb5_authdata zpac = { KV5M_AUTHDATA, KRB5_AUTHDATA_WIN2K_PAC, 1, &z };
krb5_boolean is_service_tkt;
*pac_out = NULL;
+ if (authdata == NULL)
+ return 0;
+
/*
* Find the position of the PAC in the ticket authdata. ifrel will be the
* decoded AD-IF-RELEVANT container at position i containing a PAC, and j
* will be the offset within the container.
*/
- authdata = enc_tkt->authorization_data;
- for (i = 0; authdata != NULL && authdata[i] != NULL; i++) {
+ for (i = 0; authdata[i] != NULL; i++) {
if (authdata[i]->ad_type != KRB5_AUTHDATA_IF_RELEVANT)
continue;
}
/* Stop and return successfully if we didn't find a PAC. */
- if (ifrel == NULL) {
+ if (authdata[i] == NULL) {
ret = 0;
goto cleanup;
}
if (server != NULL || privsvr != NULL) {
ret = verify_pac_checksums(context, pac, FALSE, server, privsvr);
- if (ret != 0)
+ if (ret)
return ret;
}
if (principal != NULL) {
ret = k5_pac_validate_client(context, pac, authtime,
principal, with_realm);
- if (ret != 0)
+ if (ret)
return ret;
}
};
static krb5_error_code
-mspac_init(krb5_context kcontext, void **plugin_context)
+mspac_init(krb5_context context, void **plugin_context)
{
*plugin_context = NULL;
return 0;
}
static void
-mspac_flags(krb5_context kcontext,
- void *plugin_context,
- krb5_authdatatype ad_type,
- krb5_flags *flags)
+mspac_flags(krb5_context context, void *plugin_context,
+ krb5_authdatatype ad_type, krb5_flags *flags)
{
*flags = AD_USAGE_TGS_REQ;
}
static void
-mspac_fini(krb5_context kcontext, void *plugin_context)
+mspac_fini(krb5_context context, void *plugin_context)
{
return;
}
static krb5_error_code
-mspac_request_init(krb5_context kcontext,
- krb5_authdata_context context,
- void *plugin_context,
- void **request_context)
+mspac_request_init(krb5_context context, krb5_authdata_context actx,
+ void *plugin_context, void **request_context)
{
struct mspac_context *pacctx;
- pacctx = (struct mspac_context *)malloc(sizeof(*pacctx));
+ pacctx = malloc(sizeof(*pacctx));
if (pacctx == NULL)
return ENOMEM;
}
static krb5_error_code
-mspac_import_authdata(krb5_context kcontext,
- krb5_authdata_context context,
- void *plugin_context,
- void *request_context,
- krb5_authdata **authdata,
- krb5_boolean kdc_issued,
+mspac_import_authdata(krb5_context context, krb5_authdata_context actx,
+ void *plugin_context, void *request_context,
+ krb5_authdata **authdata, krb5_boolean kdc_issued,
krb5_const_principal kdc_issuer)
{
- krb5_error_code code;
struct mspac_context *pacctx = (struct mspac_context *)request_context;
if (kdc_issued)
return EINVAL;
if (pacctx->pac != NULL) {
- krb5_pac_free(kcontext, pacctx->pac);
+ krb5_pac_free(context, pacctx->pac);
pacctx->pac = NULL;
}
assert((authdata[0]->ad_type & AD_TYPE_FIELD_TYPE_MASK) ==
KRB5_AUTHDATA_WIN2K_PAC);
- code = krb5_pac_parse(kcontext, authdata[0]->contents,
- authdata[0]->length, &pacctx->pac);
-
- return code;
+ return krb5_pac_parse(context, authdata[0]->contents, authdata[0]->length,
+ &pacctx->pac);
}
static krb5_error_code
-mspac_export_authdata(krb5_context kcontext,
- krb5_authdata_context context,
- void *plugin_context,
- void *request_context,
- krb5_flags usage,
- krb5_authdata ***out_authdata)
+mspac_export_authdata(krb5_context context, krb5_authdata_context actx,
+ void *plugin_context, void *request_context,
+ krb5_flags usage, krb5_authdata ***authdata_out)
{
struct mspac_context *pacctx = (struct mspac_context *)request_context;
krb5_error_code code;
}
authdata[1] = NULL;
- code = krb5int_copy_data_contents(kcontext, &pacctx->pac->data, &data);
+ code = krb5int_copy_data_contents(context, &pacctx->pac->data, &data);
if (code != 0) {
- krb5_free_authdata(kcontext, authdata);
+ krb5_free_authdata(context, authdata);
return code;
}
authdata[1] = NULL;
- *out_authdata = authdata;
+ *authdata_out = authdata;
return 0;
}
static krb5_error_code
-mspac_verify(krb5_context kcontext,
- krb5_authdata_context context,
- void *plugin_context,
- void *request_context,
- const krb5_auth_context *auth_context,
- const krb5_keyblock *key,
+mspac_verify(krb5_context context, krb5_authdata_context actx,
+ void *plugin_context, void *request_context,
+ const krb5_auth_context *auth_context, const krb5_keyblock *key,
const krb5_ap_req *req)
{
- krb5_error_code code;
+ krb5_error_code ret;
struct mspac_context *pacctx = (struct mspac_context *)request_context;
if (pacctx->pac == NULL)
return EINVAL;
- code = krb5_pac_verify(kcontext, pacctx->pac,
- req->ticket->enc_part2->times.authtime,
- req->ticket->enc_part2->client, key, NULL);
- if (code != 0)
- TRACE_MSPAC_VERIFY_FAIL(kcontext, code);
+ ret = krb5_pac_verify(context, pacctx->pac,
+ req->ticket->enc_part2->times.authtime,
+ req->ticket->enc_part2->client, key, NULL);
+ if (ret)
+ TRACE_MSPAC_VERIFY_FAIL(context, ret);
/*
* If the above verification failed, don't fail the whole authentication,
}
static void
-mspac_request_fini(krb5_context kcontext,
- krb5_authdata_context context,
- void *plugin_context,
- void *request_context)
+mspac_request_fini(krb5_context context, krb5_authdata_context actx,
+ void *plugin_context, void *request_context)
{
struct mspac_context *pacctx = (struct mspac_context *)request_context;
if (pacctx != NULL) {
- if (pacctx->pac != NULL)
- krb5_pac_free(kcontext, pacctx->pac);
-
+ krb5_pac_free(context, pacctx->pac);
free(pacctx);
}
}
#define STRLENOF(x) (sizeof((x)) - 1)
static struct {
- krb5_ui_4 type;
+ uint32_t type;
krb5_data attribute;
} mspac_attribute_types[] = {
- { (krb5_ui_4)-1, { KV5M_DATA, STRLENOF("urn:mspac:"),
+ { (uint32_t)-1, { KV5M_DATA, STRLENOF("urn:mspac:"),
"urn:mspac:" } },
{ KRB5_PAC_LOGON_INFO, { KV5M_DATA,
STRLENOF("urn:mspac:logon-info"),
#define MSPAC_ATTRIBUTE_COUNT (sizeof(mspac_attribute_types)/sizeof(mspac_attribute_types[0]))
static krb5_error_code
-mspac_type2attr(krb5_ui_4 type, krb5_data *attr)
+mspac_type2attr(uint32_t type, krb5_data *attr)
{
unsigned int i;
}
static krb5_error_code
-mspac_attr2type(const krb5_data *attr, krb5_ui_4 *type)
+mspac_attr2type(const krb5_data *attr, uint32_t *type)
{
unsigned int i;
}
static krb5_error_code
-mspac_get_attribute_types(krb5_context kcontext,
- krb5_authdata_context context,
- void *plugin_context,
- void *request_context,
- krb5_data **out_attrs)
+mspac_get_attribute_types(krb5_context context, krb5_authdata_context actx,
+ void *plugin_context, void *request_context,
+ krb5_data **attrs_out)
{
struct mspac_context *pacctx = (struct mspac_context *)request_context;
unsigned int i, j;
krb5_data *attrs;
- krb5_error_code code;
+ krb5_error_code ret;
if (pacctx->pac == NULL)
return ENOENT;
- attrs = calloc(1 + pacctx->pac->pac->cBuffers + 1, sizeof(krb5_data));
+ attrs = calloc(1 + pacctx->pac->nbuffers + 1, sizeof(krb5_data));
if (attrs == NULL)
return ENOMEM;
j = 0;
/* The entire PAC */
- code = krb5int_copy_data_contents(kcontext,
- &mspac_attribute_types[0].attribute,
- &attrs[j++]);
- if (code != 0) {
- free(attrs);
- return code;
- }
+ ret = krb5int_copy_data_contents(context,
+ &mspac_attribute_types[0].attribute,
+ &attrs[j++]);
+ if (ret)
+ goto fail;
/* PAC buffers */
- for (i = 0; i < pacctx->pac->pac->cBuffers; i++) {
+ for (i = 0; i < pacctx->pac->nbuffers; i++) {
krb5_data attr;
- code = mspac_type2attr(pacctx->pac->pac->Buffers[i].ulType, &attr);
- if (code == 0) {
- code = krb5int_copy_data_contents(kcontext, &attr, &attrs[j++]);
- if (code != 0) {
- krb5int_free_data_list(kcontext, attrs);
- return code;
- }
+ ret = mspac_type2attr(pacctx->pac->buffers[i].type, &attr);
+ if (!ret) {
+ ret = krb5int_copy_data_contents(context, &attr, &attrs[j++]);
+ if (ret)
+ goto fail;
} else {
int length;
length = asprintf(&attrs[j].data, "urn:mspac:%d",
- pacctx->pac->pac->Buffers[i].ulType);
+ pacctx->pac->buffers[i].type);
if (length < 0) {
- krb5int_free_data_list(kcontext, attrs);
- return ENOMEM;
+ ret = ENOMEM;
+ goto fail;
}
attrs[j++].length = length;
}
attrs[j].data = NULL;
attrs[j].length = 0;
- *out_attrs = attrs;
+ *attrs_out = attrs;
return 0;
+
+fail:
+ krb5int_free_data_list(context, attrs);
+ return ret;
}
static krb5_error_code
-mspac_get_attribute(krb5_context kcontext,
- krb5_authdata_context context,
- void *plugin_context,
- void *request_context,
- const krb5_data *attribute,
- krb5_boolean *authenticated,
- krb5_boolean *complete,
- krb5_data *value,
- krb5_data *display_value,
- int *more)
+mspac_get_attribute(krb5_context context, krb5_authdata_context actx,
+ void *plugin_context, void *request_context,
+ const krb5_data *attribute, krb5_boolean *authenticated,
+ krb5_boolean *complete, krb5_data *value,
+ krb5_data *display_value, int *more)
{
struct mspac_context *pacctx = (struct mspac_context *)request_context;
- krb5_error_code code;
- krb5_ui_4 type;
+ krb5_error_code ret;
+ uint32_t type;
if (display_value != NULL) {
display_value->data = NULL;
/* If it didn't verify, pretend it didn't exist. */
if (!pacctx->pac->verified) {
- TRACE_MSPAC_DISCARD_UNVERF(kcontext);
+ TRACE_MSPAC_DISCARD_UNVERF(context);
return ENOENT;
}
- code = mspac_attr2type(attribute, &type);
- if (code != 0)
- return code;
+ ret = mspac_attr2type(attribute, &type);
+ if (ret)
+ return ret;
/* -1 is a magic type that refers to the entire PAC */
- if (type == (krb5_ui_4)-1) {
+ if (type == (uint32_t)-1) {
if (value != NULL)
- code = krb5int_copy_data_contents(kcontext,
- &pacctx->pac->data,
- value);
+ ret = krb5int_copy_data_contents(context, &pacctx->pac->data,
+ value);
else
- code = 0;
+ ret = 0;
} else {
if (value != NULL)
- code = krb5_pac_get_buffer(kcontext, pacctx->pac, type, value);
+ ret = krb5_pac_get_buffer(context, pacctx->pac, type, value);
else
- code = k5_pac_locate_buffer(kcontext, pacctx->pac, type, NULL);
+ ret = k5_pac_locate_buffer(context, pacctx->pac, type, NULL);
}
- if (code == 0) {
+ if (!ret) {
*authenticated = pacctx->pac->verified;
*complete = TRUE;
}
*more = 0;
- return code;
+ return ret;
}
static krb5_error_code
-mspac_set_attribute(krb5_context kcontext,
- krb5_authdata_context context,
- void *plugin_context,
- void *request_context,
- krb5_boolean complete,
- const krb5_data *attribute,
+mspac_set_attribute(krb5_context context, krb5_authdata_context actx,
+ void *plugin_context, void *request_context,
+ krb5_boolean complete, const krb5_data *attribute,
const krb5_data *value)
{
struct mspac_context *pacctx = (struct mspac_context *)request_context;
- krb5_error_code code;
- krb5_ui_4 type;
+ krb5_error_code ret;
+ uint32_t type;
if (pacctx->pac == NULL)
return ENOENT;
- code = mspac_attr2type(attribute, &type);
- if (code != 0)
- return code;
+ ret = mspac_attr2type(attribute, &type);
+ if (ret)
+ return ret;
/* -1 is a magic type that refers to the entire PAC */
- if (type == (krb5_ui_4)-1) {
+ if (type == (uint32_t)-1) {
krb5_pac newpac;
- code = krb5_pac_parse(kcontext, value->data, value->length, &newpac);
- if (code != 0)
- return code;
+ ret = krb5_pac_parse(context, value->data, value->length, &newpac);
+ if (ret)
+ return ret;
- krb5_pac_free(kcontext, pacctx->pac);
+ krb5_pac_free(context, pacctx->pac);
pacctx->pac = newpac;
} else {
- code = krb5_pac_add_buffer(kcontext, pacctx->pac, type, value);
+ ret = krb5_pac_add_buffer(context, pacctx->pac, type, value);
}
- return code;
+ return ret;
}
static krb5_error_code
-mspac_export_internal(krb5_context kcontext,
- krb5_authdata_context context,
- void *plugin_context,
- void *request_context,
- krb5_boolean restrict_authenticated,
- void **ptr)
+mspac_export_internal(krb5_context context, krb5_authdata_context actx,
+ void *plugin_context, void *request_context,
+ krb5_boolean restrict_authenticated, void **ptr)
{
struct mspac_context *pacctx = (struct mspac_context *)request_context;
- krb5_error_code code;
+ krb5_error_code ret;
krb5_pac pac;
*ptr = NULL;
if (restrict_authenticated && (pacctx->pac->verified) == FALSE)
return ENOENT;
- code = krb5_pac_parse(kcontext, pacctx->pac->data.data,
- pacctx->pac->data.length, &pac);
- if (code == 0) {
+ ret = krb5_pac_parse(context, pacctx->pac->data.data,
+ pacctx->pac->data.length, &pac);
+ if (!ret) {
pac->verified = pacctx->pac->verified;
*ptr = pac;
}
- return code;
+ return ret;
}
static void
-mspac_free_internal(krb5_context kcontext,
- krb5_authdata_context context,
- void *plugin_context,
- void *request_context,
- void *ptr)
+mspac_free_internal(krb5_context context, krb5_authdata_context actx,
+ void *plugin_context, void *request_context, void *ptr)
{
if (ptr != NULL)
- krb5_pac_free(kcontext, (krb5_pac)ptr);
+ krb5_pac_free(context, (krb5_pac)ptr);
return;
}
static krb5_error_code
-mspac_size(krb5_context kcontext,
- krb5_authdata_context context,
- void *plugin_context,
- void *request_context,
- size_t *sizep)
+mspac_size(krb5_context context, krb5_authdata_context actx,
+ void *plugin_context, void *request_context, size_t *sizep)
{
struct mspac_context *pacctx = (struct mspac_context *)request_context;
- *sizep += sizeof(krb5_int32);
+ *sizep += sizeof(int32_t);
if (pacctx->pac != NULL)
*sizep += pacctx->pac->data.length;
- *sizep += sizeof(krb5_int32);
+ *sizep += sizeof(int32_t);
return 0;
}
static krb5_error_code
-mspac_externalize(krb5_context kcontext,
- krb5_authdata_context context,
- void *plugin_context,
- void *request_context,
- krb5_octet **buffer,
- size_t *lenremain)
+mspac_externalize(krb5_context context, krb5_authdata_context actx,
+ void *plugin_context, void *request_context,
+ krb5_octet **buffer, size_t *lenremain)
{
- krb5_error_code code = 0;
+ krb5_error_code ret = 0;
struct mspac_context *pacctx = (struct mspac_context *)request_context;
size_t required = 0;
krb5_octet *bp;
remain = *lenremain;
if (pacctx->pac != NULL) {
- mspac_size(kcontext, context, plugin_context,
- request_context, &required);
+ mspac_size(context, actx, plugin_context, request_context, &required);
if (required <= remain) {
- krb5_ser_pack_int32((krb5_int32)pacctx->pac->data.length,
- &bp, &remain);
+ krb5_ser_pack_int32(pacctx->pac->data.length, &bp, &remain);
krb5_ser_pack_bytes((krb5_octet *)pacctx->pac->data.data,
(size_t)pacctx->pac->data.length,
&bp, &remain);
- krb5_ser_pack_int32((krb5_int32)pacctx->pac->verified,
- &bp, &remain);
+ krb5_ser_pack_int32(pacctx->pac->verified, &bp, &remain);
} else {
- code = ENOMEM;
+ ret = ENOMEM;
}
} else {
krb5_ser_pack_int32(0, &bp, &remain); /* length */
*buffer = bp;
*lenremain = remain;
- return code;
+ return ret;
}
static krb5_error_code
-mspac_internalize(krb5_context kcontext,
- krb5_authdata_context context,
- void *plugin_context,
- void *request_context,
- krb5_octet **buffer,
- size_t *lenremain)
+mspac_internalize(krb5_context context, krb5_authdata_context actx,
+ void *plugin_context, void *request_context,
+ krb5_octet **buffer, size_t *lenremain)
{
struct mspac_context *pacctx = (struct mspac_context *)request_context;
- krb5_error_code code;
- krb5_int32 ibuf;
- krb5_octet *bp;
+ krb5_error_code ret;
+ int32_t ibuf;
+ uint8_t *bp;
size_t remain;
krb5_pac pac = NULL;
remain = *lenremain;
/* length */
- code = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
- if (code != 0)
- return code;
+ ret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ if (ret)
+ return ret;
if (ibuf != 0) {
- code = krb5_pac_parse(kcontext, bp, ibuf, &pac);
- if (code != 0)
- return code;
+ ret = krb5_pac_parse(context, bp, ibuf, &pac);
+ if (ret)
+ return ret;
bp += ibuf;
remain -= ibuf;
}
/* verified */
- code = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
- if (code != 0) {
- krb5_pac_free(kcontext, pac);
- return code;
+ ret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
+ if (ret) {
+ krb5_pac_free(context, pac);
+ return ret;
}
- if (pac != NULL) {
+ if (pac != NULL)
pac->verified = (ibuf != 0);
- }
- if (pacctx->pac != NULL) {
- krb5_pac_free(kcontext, pacctx->pac);
- }
+ if (pacctx->pac != NULL)
+ krb5_pac_free(context, pacctx->pac);
pacctx->pac = pac;
}
static krb5_error_code
-mspac_copy(krb5_context kcontext,
- krb5_authdata_context context,
- void *plugin_context,
- void *request_context,
- void *dst_plugin_context,
- void *dst_request_context)
+mspac_copy(krb5_context context, krb5_authdata_context actx,
+ void *plugin_context, void *request_context,
+ void *dst_plugin_context, void *dst_request_context)
{
struct mspac_context *srcctx = (struct mspac_context *)request_context;
struct mspac_context *dstctx = (struct mspac_context *)dst_request_context;
- krb5_error_code code = 0;
+ krb5_error_code ret = 0;
assert(dstctx != NULL);
assert(dstctx->pac == NULL);
if (srcctx->pac != NULL)
- code = k5_pac_copy(kcontext, srcctx->pac, &dstctx->pac);
+ ret = copy_pac(context, srcctx->pac, &dstctx->pac);
- return code;
+ return ret;
}
static krb5_authdatatype mspac_ad_types[] = { KRB5_AUTHDATA_WIN2K_PAC, 0 };