1331722Seadler/*
2178828Sdfr * Copyright (c) 2004, PADL Software Pty Ltd.
3178828Sdfr * All rights reserved.
4178828Sdfr *
5178828Sdfr * Redistribution and use in source and binary forms, with or without
6178828Sdfr * modification, are permitted provided that the following conditions
7178828Sdfr * are met:
8178828Sdfr *
9178828Sdfr * 1. Redistributions of source code must retain the above copyright
10178828Sdfr *    notice, this list of conditions and the following disclaimer.
11178828Sdfr *
12178828Sdfr * 2. Redistributions in binary form must reproduce the above copyright
13178828Sdfr *    notice, this list of conditions and the following disclaimer in the
14178828Sdfr *    documentation and/or other materials provided with the distribution.
15178828Sdfr *
16178828Sdfr * 3. Neither the name of PADL Software nor the names of its contributors
17178828Sdfr *    may be used to endorse or promote products derived from this software
18178828Sdfr *    without specific prior written permission.
19178828Sdfr *
20178828Sdfr * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
21178828Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22178828Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23178828Sdfr * ARE DISCLAIMED.  IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
24178828Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25178828Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26178828Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27178828Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28178828Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29178828Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30178828Sdfr * SUCH DAMAGE.
31178828Sdfr */
32178828Sdfr/* $FreeBSD: stable/11/lib/libgssapi/gss_buffer_set.c 318121 2017-05-09 23:31:09Z pfg $ */
33178828Sdfr
34178828Sdfr#include <gssapi/gssapi.h>
35178828Sdfr#include <errno.h>
36178828Sdfr#include <stdlib.h>
37178828Sdfr#include <string.h>
38178828Sdfr
39178828Sdfr/* RCSID("$Id: gss_buffer_set.c 18885 2006-10-24 21:53:02Z lha $"); */
40178828Sdfr
41178828SdfrOM_uint32
42178828Sdfrgss_create_empty_buffer_set(OM_uint32 * minor_status,
43178828Sdfr    gss_buffer_set_t *buffer_set)
44178828Sdfr{
45178828Sdfr	gss_buffer_set_t set;
46178828Sdfr
47178828Sdfr	set = (gss_buffer_set_desc *) malloc(sizeof(*set));
48178828Sdfr	if (set == GSS_C_NO_BUFFER_SET) {
49178828Sdfr		*minor_status = ENOMEM;
50178828Sdfr		return (GSS_S_FAILURE);
51178828Sdfr	}
52178828Sdfr
53178828Sdfr	set->count = 0;
54178828Sdfr	set->elements = NULL;
55178828Sdfr
56178828Sdfr	*buffer_set = set;
57178828Sdfr
58178828Sdfr	*minor_status = 0;
59178828Sdfr	return (GSS_S_COMPLETE);
60178828Sdfr}
61178828Sdfr
62178828SdfrOM_uint32
63178828Sdfrgss_add_buffer_set_member(OM_uint32 * minor_status,
64178828Sdfr    const gss_buffer_t member_buffer, gss_buffer_set_t *buffer_set)
65178828Sdfr{
66178828Sdfr	gss_buffer_set_t set;
67178828Sdfr	gss_buffer_t p;
68178828Sdfr	OM_uint32 ret;
69178828Sdfr
70178828Sdfr	if (*buffer_set == GSS_C_NO_BUFFER_SET) {
71178828Sdfr		ret = gss_create_empty_buffer_set(minor_status,
72178828Sdfr		    buffer_set);
73178828Sdfr		if (ret) {
74178828Sdfr			return (ret);
75178828Sdfr		}
76178828Sdfr	}
77178828Sdfr
78178828Sdfr	set = *buffer_set;
79318121Spfg	set->elements = reallocarray(set->elements, set->count + 1,
80318121Spfg	    sizeof(set->elements[0]));
81178828Sdfr	if (set->elements == NULL) {
82178828Sdfr		*minor_status = ENOMEM;
83178828Sdfr		return (GSS_S_FAILURE);
84178828Sdfr	}
85178828Sdfr
86178828Sdfr	p = &set->elements[set->count];
87178828Sdfr
88178828Sdfr	p->value = malloc(member_buffer->length);
89178828Sdfr	if (p->value == NULL) {
90178828Sdfr		*minor_status = ENOMEM;
91178828Sdfr		return (GSS_S_FAILURE);
92178828Sdfr	}
93178828Sdfr	memcpy(p->value, member_buffer->value, member_buffer->length);
94178828Sdfr	p->length = member_buffer->length;
95178828Sdfr
96178828Sdfr	set->count++;
97178828Sdfr
98178828Sdfr	*minor_status = 0;
99178828Sdfr	return (GSS_S_COMPLETE);
100178828Sdfr}
101178828Sdfr
102178828SdfrOM_uint32
103178828Sdfrgss_release_buffer_set(OM_uint32 * minor_status, gss_buffer_set_t *buffer_set)
104178828Sdfr{
105178828Sdfr	size_t i;
106178828Sdfr	OM_uint32 minor;
107178828Sdfr
108178828Sdfr	*minor_status = 0;
109178828Sdfr
110178828Sdfr	if (*buffer_set == GSS_C_NO_BUFFER_SET)
111178828Sdfr		return (GSS_S_COMPLETE);
112178828Sdfr
113178828Sdfr	for (i = 0; i < (*buffer_set)->count; i++)
114178828Sdfr		gss_release_buffer(&minor, &((*buffer_set)->elements[i]));
115178828Sdfr
116178828Sdfr	free((*buffer_set)->elements);
117178828Sdfr
118178828Sdfr	(*buffer_set)->elements = NULL;
119178828Sdfr	(*buffer_set)->count = 0;
120178828Sdfr
121178828Sdfr	free(*buffer_set);
122178828Sdfr	*buffer_set = GSS_C_NO_BUFFER_SET;
123178828Sdfr
124178828Sdfr	return (GSS_S_COMPLETE);
125178828Sdfr}
126178828Sdfr
127