|
Packit Service |
99d1c0 |
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
Packit Service |
99d1c0 |
/* lib/krad/attrset.c - RADIUS attribute set functions for libkrad */
|
|
Packit Service |
99d1c0 |
/*
|
|
Packit Service |
99d1c0 |
* Copyright 2013 Red Hat, Inc. All rights reserved.
|
|
Packit Service |
99d1c0 |
*
|
|
Packit Service |
99d1c0 |
* Redistribution and use in source and binary forms, with or without
|
|
Packit Service |
99d1c0 |
* modification, are permitted provided that the following conditions are met:
|
|
Packit Service |
99d1c0 |
*
|
|
Packit Service |
99d1c0 |
* 1. Redistributions of source code must retain the above copyright
|
|
Packit Service |
99d1c0 |
* notice, this list of conditions and the following disclaimer.
|
|
Packit Service |
99d1c0 |
*
|
|
Packit Service |
99d1c0 |
* 2. Redistributions in binary form must reproduce the above copyright
|
|
Packit Service |
99d1c0 |
* notice, this list of conditions and the following disclaimer in
|
|
Packit Service |
99d1c0 |
* the documentation and/or other materials provided with the
|
|
Packit Service |
99d1c0 |
* distribution.
|
|
Packit Service |
99d1c0 |
*
|
|
Packit Service |
99d1c0 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
|
Packit Service |
99d1c0 |
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
Packit Service |
99d1c0 |
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
Packit Service |
99d1c0 |
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
|
Packit Service |
99d1c0 |
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
Packit Service |
99d1c0 |
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
Packit Service |
99d1c0 |
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
Packit Service |
99d1c0 |
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
Packit Service |
99d1c0 |
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
Packit Service |
99d1c0 |
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
Packit Service |
99d1c0 |
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit Service |
99d1c0 |
*/
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
#include <k5-int.h>
|
|
Packit Service |
99d1c0 |
#include <k5-queue.h>
|
|
Packit Service |
99d1c0 |
#include "internal.h"
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
#include <string.h>
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
K5_TAILQ_HEAD(attr_head, attr_st);
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
typedef struct attr_st attr;
|
|
Packit Service |
99d1c0 |
struct attr_st {
|
|
Packit Service |
99d1c0 |
K5_TAILQ_ENTRY(attr_st) list;
|
|
Packit Service |
99d1c0 |
krad_attr type;
|
|
Packit Service |
99d1c0 |
krb5_data attr;
|
|
Packit Service |
99d1c0 |
char buffer[MAX_ATTRSIZE];
|
|
Packit Service |
99d1c0 |
};
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
struct krad_attrset_st {
|
|
Packit Service |
99d1c0 |
krb5_context ctx;
|
|
Packit Service |
99d1c0 |
struct attr_head list;
|
|
Packit Service |
99d1c0 |
};
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
krb5_error_code
|
|
Packit Service |
99d1c0 |
krad_attrset_new(krb5_context ctx, krad_attrset **set)
|
|
Packit Service |
99d1c0 |
{
|
|
Packit Service |
99d1c0 |
krad_attrset *tmp;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
tmp = calloc(1, sizeof(krad_attrset));
|
|
Packit Service |
99d1c0 |
if (tmp == NULL)
|
|
Packit Service |
99d1c0 |
return ENOMEM;
|
|
Packit Service |
99d1c0 |
tmp->ctx = ctx;
|
|
Packit Service |
99d1c0 |
K5_TAILQ_INIT(&tmp->list);
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
*set = tmp;
|
|
Packit Service |
99d1c0 |
return 0;
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
void
|
|
Packit Service |
99d1c0 |
krad_attrset_free(krad_attrset *set)
|
|
Packit Service |
99d1c0 |
{
|
|
Packit Service |
99d1c0 |
attr *a;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
if (set == NULL)
|
|
Packit Service |
99d1c0 |
return;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
while (!K5_TAILQ_EMPTY(&set->list)) {
|
|
Packit Service |
99d1c0 |
a = K5_TAILQ_FIRST(&set->list);
|
|
Packit Service |
99d1c0 |
K5_TAILQ_REMOVE(&set->list, a, list);
|
|
Packit Service |
99d1c0 |
zap(a->buffer, sizeof(a->buffer));
|
|
Packit Service |
99d1c0 |
free(a);
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
free(set);
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
krb5_error_code
|
|
Packit Service |
99d1c0 |
krad_attrset_add(krad_attrset *set, krad_attr type, const krb5_data *data)
|
|
Packit Service |
99d1c0 |
{
|
|
Packit Service |
99d1c0 |
krb5_error_code retval;
|
|
Packit Service |
99d1c0 |
attr *tmp;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
retval = kr_attr_valid(type, data);
|
|
Packit Service |
99d1c0 |
if (retval != 0)
|
|
Packit Service |
99d1c0 |
return retval;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
tmp = calloc(1, sizeof(attr));
|
|
Packit Service |
99d1c0 |
if (tmp == NULL)
|
|
Packit Service |
99d1c0 |
return ENOMEM;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
tmp->type = type;
|
|
Packit Service |
99d1c0 |
tmp->attr = make_data(tmp->buffer, data->length);
|
|
Packit Service |
99d1c0 |
memcpy(tmp->attr.data, data->data, data->length);
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
K5_TAILQ_INSERT_TAIL(&set->list, tmp, list);
|
|
Packit Service |
99d1c0 |
return 0;
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
krb5_error_code
|
|
Packit Service |
99d1c0 |
krad_attrset_add_number(krad_attrset *set, krad_attr type, krb5_ui_4 num)
|
|
Packit Service |
99d1c0 |
{
|
|
Packit Service |
99d1c0 |
krb5_data data;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
num = htonl(num);
|
|
Packit Service |
99d1c0 |
data = make_data(&num, sizeof(num));
|
|
Packit Service |
99d1c0 |
return krad_attrset_add(set, type, &data);
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
void
|
|
Packit Service |
99d1c0 |
krad_attrset_del(krad_attrset *set, krad_attr type, size_t indx)
|
|
Packit Service |
99d1c0 |
{
|
|
Packit Service |
99d1c0 |
attr *a;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
K5_TAILQ_FOREACH(a, &set->list, list) {
|
|
Packit Service |
99d1c0 |
if (a->type == type && indx-- == 0) {
|
|
Packit Service |
99d1c0 |
K5_TAILQ_REMOVE(&set->list, a, list);
|
|
Packit Service |
99d1c0 |
zap(a->buffer, sizeof(a->buffer));
|
|
Packit Service |
99d1c0 |
free(a);
|
|
Packit Service |
99d1c0 |
return;
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
const krb5_data *
|
|
Packit Service |
99d1c0 |
krad_attrset_get(const krad_attrset *set, krad_attr type, size_t indx)
|
|
Packit Service |
99d1c0 |
{
|
|
Packit Service |
99d1c0 |
attr *a;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
K5_TAILQ_FOREACH(a, &set->list, list) {
|
|
Packit Service |
99d1c0 |
if (a->type == type && indx-- == 0)
|
|
Packit Service |
99d1c0 |
return &a->attr;
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
return NULL;
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
krb5_error_code
|
|
Packit Service |
99d1c0 |
krad_attrset_copy(const krad_attrset *set, krad_attrset **copy)
|
|
Packit Service |
99d1c0 |
{
|
|
Packit Service |
99d1c0 |
krb5_error_code retval;
|
|
Packit Service |
99d1c0 |
krad_attrset *tmp;
|
|
Packit Service |
99d1c0 |
attr *a;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
retval = krad_attrset_new(set->ctx, &tmp);
|
|
Packit Service |
99d1c0 |
if (retval != 0)
|
|
Packit Service |
99d1c0 |
return retval;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
K5_TAILQ_FOREACH(a, &set->list, list) {
|
|
Packit Service |
99d1c0 |
retval = krad_attrset_add(tmp, a->type, &a->attr);
|
|
Packit Service |
99d1c0 |
if (retval != 0) {
|
|
Packit Service |
99d1c0 |
krad_attrset_free(tmp);
|
|
Packit Service |
99d1c0 |
return retval;
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
*copy = tmp;
|
|
Packit Service |
99d1c0 |
return 0;
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
krb5_error_code
|
|
Packit Service |
99d1c0 |
kr_attrset_encode(const krad_attrset *set, const char *secret,
|
|
Packit Service |
99d1c0 |
const unsigned char *auth,
|
|
rpm-build |
490d66 |
unsigned char outbuf[MAX_ATTRSETSIZE], size_t *outlen,
|
|
rpm-build |
490d66 |
krb5_boolean *is_fips)
|
|
Packit Service |
99d1c0 |
{
|
|
Packit Service |
99d1c0 |
unsigned char buffer[MAX_ATTRSIZE];
|
|
Packit Service |
99d1c0 |
krb5_error_code retval;
|
|
Packit Service |
99d1c0 |
size_t i = 0, attrlen;
|
|
Packit Service |
99d1c0 |
attr *a;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
if (set == NULL) {
|
|
Packit Service |
99d1c0 |
*outlen = 0;
|
|
Packit Service |
99d1c0 |
return 0;
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
K5_TAILQ_FOREACH(a, &set->list, list) {
|
|
Packit Service |
99d1c0 |
retval = kr_attr_encode(set->ctx, secret, auth, a->type, &a->attr,
|
|
rpm-build |
490d66 |
buffer, &attrlen, is_fips);
|
|
Packit Service |
99d1c0 |
if (retval != 0)
|
|
Packit Service |
99d1c0 |
return retval;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
if (i + attrlen + 2 > MAX_ATTRSETSIZE)
|
|
Packit Service |
99d1c0 |
return EMSGSIZE;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
outbuf[i++] = a->type;
|
|
Packit Service |
99d1c0 |
outbuf[i++] = attrlen + 2;
|
|
Packit Service |
99d1c0 |
memcpy(&outbuf[i], buffer, attrlen);
|
|
Packit Service |
99d1c0 |
i += attrlen;
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
*outlen = i;
|
|
Packit Service |
99d1c0 |
return 0;
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
krb5_error_code
|
|
Packit Service |
99d1c0 |
kr_attrset_decode(krb5_context ctx, const krb5_data *in, const char *secret,
|
|
Packit Service |
99d1c0 |
const unsigned char *auth, krad_attrset **set_out)
|
|
Packit Service |
99d1c0 |
{
|
|
Packit Service |
99d1c0 |
unsigned char buffer[MAX_ATTRSIZE];
|
|
Packit Service |
99d1c0 |
krb5_data tmp;
|
|
Packit Service |
99d1c0 |
krb5_error_code retval;
|
|
Packit Service |
99d1c0 |
krad_attr type;
|
|
Packit Service |
99d1c0 |
krad_attrset *set;
|
|
Packit Service |
99d1c0 |
size_t i, len;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
*set_out = NULL;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
retval = krad_attrset_new(ctx, &set);
|
|
Packit Service |
99d1c0 |
if (retval != 0)
|
|
Packit Service |
99d1c0 |
return retval;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
for (i = 0; i + 2 < in->length; ) {
|
|
Packit Service |
99d1c0 |
type = in->data[i++];
|
|
Packit Service |
99d1c0 |
tmp = make_data(&in->data[i + 1], in->data[i] - 2);
|
|
Packit Service |
99d1c0 |
i += tmp.length + 1;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
retval = (in->length < i) ? EBADMSG : 0;
|
|
Packit Service |
99d1c0 |
if (retval != 0)
|
|
Packit Service |
99d1c0 |
goto cleanup;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
retval = kr_attr_decode(ctx, secret, auth, type, &tmp, buffer, &len;;
|
|
Packit Service |
99d1c0 |
if (retval != 0)
|
|
Packit Service |
99d1c0 |
goto cleanup;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
tmp = make_data(buffer, len);
|
|
Packit Service |
99d1c0 |
retval = krad_attrset_add(set, type, &tmp);
|
|
Packit Service |
99d1c0 |
if (retval != 0)
|
|
Packit Service |
99d1c0 |
goto cleanup;
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
*set_out = set;
|
|
Packit Service |
99d1c0 |
set = NULL;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
cleanup:
|
|
Packit Service |
99d1c0 |
zap(buffer, sizeof(buffer));
|
|
Packit Service |
99d1c0 |
krad_attrset_free(set);
|
|
Packit Service |
99d1c0 |
return retval;
|
|
Packit Service |
99d1c0 |
}
|