Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/heimdal/lib/gssapi/mech/gss_init_sec_context.c
34907 views
1
/*-
2
* Copyright (c) 2005 Doug Rabson
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
7
* are met:
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
10
* 2. Redistributions in binary form must reproduce the above copyright
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
* SUCH DAMAGE.
25
*
26
* $FreeBSD: src/lib/libgssapi/gss_init_sec_context.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
27
*/
28
29
#include "mech_locl.h"
30
31
static gss_cred_id_t
32
_gss_mech_cred_find(gss_cred_id_t cred_handle, gss_OID mech_type)
33
{
34
struct _gss_cred *cred = (struct _gss_cred *)cred_handle;
35
struct _gss_mechanism_cred *mc;
36
37
if (cred == NULL)
38
return GSS_C_NO_CREDENTIAL;
39
40
HEIM_SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
41
if (gss_oid_equal(mech_type, mc->gmc_mech_oid))
42
return mc->gmc_cred;
43
}
44
return GSS_C_NO_CREDENTIAL;
45
}
46
47
/**
48
* As the initiator build a context with an acceptor.
49
*
50
* Returns in the major
51
* - GSS_S_COMPLETE - if the context if build
52
* - GSS_S_CONTINUE_NEEDED - if the caller needs to continue another
53
* round of gss_i nit_sec_context
54
* - error code - any other error code
55
*
56
* @param minor_status minor status code.
57
*
58
* @param initiator_cred_handle the credential to use when building
59
* the context, if GSS_C_NO_CREDENTIAL is passed, the default
60
* credential for the mechanism will be used.
61
*
62
* @param context_handle a pointer to a context handle, will be
63
* returned as long as there is not an error.
64
*
65
* @param target_name the target name of acceptor, created using
66
* gss_import_name(). The name is can be of any name types the
67
* mechanism supports, check supported name types with
68
* gss_inquire_names_for_mech().
69
*
70
* @param input_mech_type mechanism type to use, if GSS_C_NO_OID is
71
* used, Kerberos (GSS_KRB5_MECHANISM) will be tried. Other
72
* available mechanism are listed in the @ref gssapi_mechs_intro
73
* section.
74
*
75
* @param req_flags flags using when building the context, see @ref
76
* gssapi_context_flags
77
*
78
* @param time_req time requested this context should be valid in
79
* seconds, common used value is GSS_C_INDEFINITE
80
*
81
* @param input_chan_bindings Channel bindings used, if not exepected
82
* otherwise, used GSS_C_NO_CHANNEL_BINDINGS
83
*
84
* @param input_token input token sent from the acceptor, for the
85
* initial packet the buffer of { NULL, 0 } should be used.
86
*
87
* @param actual_mech_type the actual mech used, MUST NOT be freed
88
* since it pointing to static memory.
89
*
90
* @param output_token if there is an output token, regardless of
91
* complete, continue_needed, or error it should be sent to the
92
* acceptor
93
*
94
* @param ret_flags return what flags was negotitated, caller should
95
* check if they are accetable. For example, if
96
* GSS_C_MUTUAL_FLAG was negotiated with the acceptor or not.
97
*
98
* @param time_rec amount of time this context is valid for
99
*
100
* @returns a gss_error code, see gss_display_status() about printing
101
* the error code.
102
*
103
* @ingroup gssapi
104
*/
105
106
107
108
GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
109
gss_init_sec_context(OM_uint32 * minor_status,
110
const gss_cred_id_t initiator_cred_handle,
111
gss_ctx_id_t * context_handle,
112
const gss_name_t target_name,
113
const gss_OID input_mech_type,
114
OM_uint32 req_flags,
115
OM_uint32 time_req,
116
const gss_channel_bindings_t input_chan_bindings,
117
const gss_buffer_t input_token,
118
gss_OID * actual_mech_type,
119
gss_buffer_t output_token,
120
OM_uint32 * ret_flags,
121
OM_uint32 * time_rec)
122
{
123
OM_uint32 major_status;
124
gssapi_mech_interface m;
125
struct _gss_name *name = (struct _gss_name *) target_name;
126
struct _gss_mechanism_name *mn;
127
struct _gss_context *ctx = (struct _gss_context *) *context_handle;
128
gss_cred_id_t cred_handle;
129
int allocated_ctx;
130
gss_OID mech_type = input_mech_type;
131
132
*minor_status = 0;
133
134
_mg_buffer_zero(output_token);
135
if (actual_mech_type)
136
*actual_mech_type = GSS_C_NO_OID;
137
if (ret_flags)
138
*ret_flags = 0;
139
if (time_rec)
140
*time_rec = 0;
141
142
/*
143
* If we haven't allocated a context yet, do so now and lookup
144
* the mechanism switch table. If we have one already, make
145
* sure we use the same mechanism switch as before.
146
*/
147
if (!ctx) {
148
if (mech_type == NULL)
149
mech_type = GSS_KRB5_MECHANISM;
150
151
ctx = malloc(sizeof(struct _gss_context));
152
if (!ctx) {
153
*minor_status = ENOMEM;
154
return (GSS_S_FAILURE);
155
}
156
memset(ctx, 0, sizeof(struct _gss_context));
157
m = ctx->gc_mech = __gss_get_mechanism(mech_type);
158
if (!m) {
159
free(ctx);
160
return (GSS_S_BAD_MECH);
161
}
162
allocated_ctx = 1;
163
} else {
164
m = ctx->gc_mech;
165
mech_type = &ctx->gc_mech->gm_mech_oid;
166
allocated_ctx = 0;
167
}
168
169
/*
170
* Find the MN for this mechanism.
171
*/
172
major_status = _gss_find_mn(minor_status, name, mech_type, &mn);
173
if (major_status != GSS_S_COMPLETE) {
174
if (allocated_ctx)
175
free(ctx);
176
return major_status;
177
}
178
179
/*
180
* If we have a cred, find the cred for this mechanism.
181
*/
182
if (m->gm_flags & GM_USE_MG_CRED)
183
cred_handle = initiator_cred_handle;
184
else
185
cred_handle = _gss_mech_cred_find(initiator_cred_handle, mech_type);
186
187
major_status = m->gm_init_sec_context(minor_status,
188
cred_handle,
189
&ctx->gc_ctx,
190
mn->gmn_name,
191
mech_type,
192
req_flags,
193
time_req,
194
input_chan_bindings,
195
input_token,
196
actual_mech_type,
197
output_token,
198
ret_flags,
199
time_rec);
200
201
if (major_status != GSS_S_COMPLETE
202
&& major_status != GSS_S_CONTINUE_NEEDED) {
203
if (allocated_ctx)
204
free(ctx);
205
_mg_buffer_zero(output_token);
206
_gss_mg_error(m, major_status, *minor_status);
207
} else {
208
*context_handle = (gss_ctx_id_t) ctx;
209
}
210
211
return (major_status);
212
}
213
214