Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/lib/rpc/auth_gssapi_misc.c
39536 views
1
/*
2
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
3
*
4
*/
5
6
#include <gssrpc/rpc.h>
7
#include <stdio.h>
8
9
#include <gssapi/gssapi.h>
10
#include <gssrpc/auth_gssapi.h>
11
12
#include "gssrpcint.h"
13
14
#ifdef __CODECENTER__
15
#define DEBUG_GSSAPI 1
16
#endif
17
18
#ifdef DEBUG_GSSAPI
19
int misc_debug_gssapi = DEBUG_GSSAPI;
20
extern void gssrpcint_printf(const char *, ...);
21
#define L_PRINTF(l,args) if (misc_debug_gssapi >= l) gssrpcint_printf args
22
#define PRINTF(args) L_PRINTF(99, args)
23
#define AUTH_GSSAPI_DISPLAY_STATUS(args) \
24
if (misc_debug_gssapi) auth_gssapi_display_status args
25
#else
26
#define PRINTF(args)
27
#define L_PRINTF(l, args)
28
#define AUTH_GSSAPI_DISPLAY_STATUS(args)
29
#endif
30
31
static void auth_gssapi_display_status_1
32
(char *, OM_uint32, int, int);
33
34
bool_t xdr_gss_buf(
35
XDR *xdrs,
36
gss_buffer_t buf)
37
{
38
/*
39
* On decode, xdr_bytes will only allocate buf->value if the
40
* length read in is < maxsize (last arg). This is dumb, because
41
* the whole point of allocating memory is so that I don't *have*
42
* to know the maximum length. -1 effectively disables this
43
* braindamage.
44
*/
45
bool_t result;
46
/* Fix type mismatches between APIs. */
47
unsigned int length = buf->length;
48
char *cp = buf->value;
49
result = xdr_bytes(xdrs, &cp, &length,
50
(xdrs->x_op == XDR_DECODE && buf->value == NULL)
51
? (unsigned int) -1 : (unsigned int) buf->length);
52
buf->value = cp;
53
buf->length = length;
54
return result;
55
}
56
57
bool_t xdr_authgssapi_creds(
58
XDR *xdrs,
59
auth_gssapi_creds *creds)
60
{
61
if (! xdr_u_int32(xdrs, &creds->version) ||
62
! xdr_bool(xdrs, &creds->auth_msg) ||
63
! xdr_gss_buf(xdrs, &creds->client_handle))
64
return FALSE;
65
return TRUE;
66
}
67
68
bool_t xdr_authgssapi_init_arg(
69
XDR *xdrs,
70
auth_gssapi_init_arg *init_arg)
71
{
72
if (! xdr_u_int32(xdrs, &init_arg->version) ||
73
! xdr_gss_buf(xdrs, &init_arg->token))
74
return FALSE;
75
return TRUE;
76
}
77
78
bool_t xdr_authgssapi_init_res(
79
XDR *xdrs,
80
auth_gssapi_init_res *init_res)
81
{
82
if (! xdr_u_int32(xdrs, &init_res->version) ||
83
! xdr_gss_buf(xdrs, &init_res->client_handle) ||
84
! xdr_u_int32(xdrs, &init_res->gss_major) ||
85
! xdr_u_int32(xdrs, &init_res->gss_minor) ||
86
! xdr_gss_buf(xdrs, &init_res->token) ||
87
! xdr_gss_buf(xdrs, &init_res->signed_isn))
88
return FALSE;
89
return TRUE;
90
}
91
92
bool_t auth_gssapi_seal_seq(
93
gss_ctx_id_t context,
94
uint32_t seq_num,
95
gss_buffer_t out_buf)
96
{
97
gss_buffer_desc in_buf;
98
OM_uint32 gssstat, minor_stat;
99
uint32_t nl_seq_num;
100
101
nl_seq_num = htonl(seq_num);
102
103
in_buf.length = sizeof(uint32_t);
104
in_buf.value = (char *) &nl_seq_num;
105
gssstat = gss_seal(&minor_stat, context, 0, GSS_C_QOP_DEFAULT,
106
&in_buf, NULL, out_buf);
107
if (gssstat != GSS_S_COMPLETE) {
108
PRINTF(("gssapi_seal_seq: failed\n"));
109
AUTH_GSSAPI_DISPLAY_STATUS(("sealing sequence number",
110
gssstat, minor_stat));
111
return FALSE;
112
}
113
return TRUE;
114
}
115
116
bool_t auth_gssapi_unseal_seq(
117
gss_ctx_id_t context,
118
gss_buffer_t in_buf,
119
uint32_t *seq_num)
120
{
121
gss_buffer_desc out_buf;
122
OM_uint32 gssstat, minor_stat;
123
uint32_t nl_seq_num;
124
125
gssstat = gss_unseal(&minor_stat, context, in_buf, &out_buf,
126
NULL, NULL);
127
if (gssstat != GSS_S_COMPLETE) {
128
PRINTF(("gssapi_unseal_seq: failed\n"));
129
AUTH_GSSAPI_DISPLAY_STATUS(("unsealing sequence number",
130
gssstat, minor_stat));
131
return FALSE;
132
} else if (out_buf.length != sizeof(uint32_t)) {
133
PRINTF(("gssapi_unseal_seq: unseal gave %d bytes\n",
134
(int) out_buf.length));
135
gss_release_buffer(&minor_stat, &out_buf);
136
return FALSE;
137
}
138
139
nl_seq_num = *((uint32_t *) out_buf.value);
140
*seq_num = (uint32_t) ntohl(nl_seq_num);
141
gss_release_buffer(&minor_stat, &out_buf);
142
143
return TRUE;
144
}
145
146
void auth_gssapi_display_status(
147
char *msg,
148
OM_uint32 major,
149
OM_uint32 minor)
150
{
151
auth_gssapi_display_status_1(msg, major, GSS_C_GSS_CODE, 0);
152
auth_gssapi_display_status_1(msg, minor, GSS_C_MECH_CODE, 0);
153
}
154
155
static void auth_gssapi_display_status_1(
156
char *m,
157
OM_uint32 code,
158
int type,
159
int rec)
160
{
161
OM_uint32 gssstat, minor_stat;
162
gss_buffer_desc msg;
163
OM_uint32 msg_ctx;
164
165
msg_ctx = 0;
166
while (1) {
167
gssstat = gss_display_status(&minor_stat, code,
168
type, GSS_C_NULL_OID,
169
&msg_ctx, &msg);
170
if (gssstat != GSS_S_COMPLETE) {
171
if (!rec) {
172
auth_gssapi_display_status_1(m,gssstat,GSS_C_GSS_CODE,1);
173
auth_gssapi_display_status_1(m, minor_stat,
174
GSS_C_MECH_CODE, 1);
175
} else {
176
fputs ("GSS-API authentication error ", stderr);
177
fwrite (msg.value, msg.length, 1, stderr);
178
fputs (": recursive failure!\n", stderr);
179
}
180
return;
181
}
182
183
fprintf (stderr, "GSS-API authentication error %s: ", m);
184
fwrite (msg.value, msg.length, 1, stderr);
185
putc ('\n', stderr);
186
if (misc_debug_gssapi)
187
gssrpcint_printf("GSS-API authentication error %s: %*s\n",
188
m, (int)msg.length, (char *) msg.value);
189
(void) gss_release_buffer(&minor_stat, &msg);
190
191
if (!msg_ctx)
192
break;
193
}
194
}
195
196
bool_t auth_gssapi_wrap_data(
197
OM_uint32 *major,
198
OM_uint32 *minor,
199
gss_ctx_id_t context,
200
uint32_t seq_num,
201
XDR *out_xdrs,
202
xdrproc_t xdr_func,
203
caddr_t xdr_ptr)
204
{
205
gss_buffer_desc in_buf, out_buf;
206
XDR temp_xdrs;
207
int conf_state;
208
unsigned int length;
209
char *cp;
210
211
PRINTF(("gssapi_wrap_data: starting\n"));
212
213
*major = GSS_S_COMPLETE;
214
*minor = 0; /* assumption */
215
216
xdralloc_create(&temp_xdrs, XDR_ENCODE);
217
218
/* serialize the sequence number into local memory */
219
PRINTF(("gssapi_wrap_data: encoding seq_num %d\n", seq_num));
220
if (! xdr_u_int32(&temp_xdrs, &seq_num)) {
221
PRINTF(("gssapi_wrap_data: serializing seq_num failed\n"));
222
XDR_DESTROY(&temp_xdrs);
223
return FALSE;
224
}
225
226
/* serialize the arguments into local memory */
227
if (!(*xdr_func)(&temp_xdrs, xdr_ptr)) {
228
PRINTF(("gssapi_wrap_data: serializing arguments failed\n"));
229
XDR_DESTROY(&temp_xdrs);
230
return FALSE;
231
}
232
233
in_buf.length = xdr_getpos(&temp_xdrs);
234
in_buf.value = xdralloc_getdata(&temp_xdrs);
235
236
*major = gss_seal(minor, context, 1,
237
GSS_C_QOP_DEFAULT, &in_buf, &conf_state,
238
&out_buf);
239
if (*major != GSS_S_COMPLETE) {
240
XDR_DESTROY(&temp_xdrs);
241
return FALSE;
242
}
243
244
PRINTF(("gssapi_wrap_data: %d bytes data, %d bytes sealed\n",
245
(int) in_buf.length, (int) out_buf.length));
246
247
/* write the token */
248
length = out_buf.length;
249
cp = out_buf.value;
250
if (! xdr_bytes(out_xdrs, &cp, &length, out_buf.length)) {
251
PRINTF(("gssapi_wrap_data: serializing encrypted data failed\n"));
252
XDR_DESTROY(&temp_xdrs);
253
return FALSE;
254
}
255
out_buf.value = cp;
256
257
*major = gss_release_buffer(minor, &out_buf);
258
259
PRINTF(("gssapi_wrap_data: succeeding\n\n"));
260
XDR_DESTROY(&temp_xdrs);
261
return TRUE;
262
}
263
264
bool_t auth_gssapi_unwrap_data(
265
OM_uint32 *major,
266
OM_uint32 *minor,
267
gss_ctx_id_t context,
268
uint32_t seq_num,
269
XDR *in_xdrs,
270
xdrproc_t xdr_func,
271
caddr_t xdr_ptr)
272
{
273
gss_buffer_desc in_buf, out_buf;
274
XDR temp_xdrs;
275
uint32_t verf_seq_num;
276
int conf, qop;
277
unsigned int length;
278
char *cp;
279
280
PRINTF(("gssapi_unwrap_data: starting\n"));
281
282
*major = GSS_S_COMPLETE;
283
*minor = 0; /* assumption */
284
285
in_buf.value = NULL;
286
out_buf.value = NULL;
287
cp = in_buf.value;
288
if (! xdr_bytes(in_xdrs, &cp, &length, (unsigned int) -1)) {
289
PRINTF(("gssapi_unwrap_data: deserializing encrypted data failed\n"));
290
temp_xdrs.x_op = XDR_FREE;
291
(void)xdr_bytes(&temp_xdrs, &cp, &length, (unsigned int) -1);
292
in_buf.value = NULL;
293
return FALSE;
294
}
295
in_buf.value = cp;
296
in_buf.length = length;
297
298
*major = gss_unseal(minor, context, &in_buf, &out_buf, &conf,
299
&qop);
300
free(in_buf.value);
301
if (*major != GSS_S_COMPLETE)
302
return FALSE;
303
304
PRINTF(("gssapi_unwrap_data: %llu bytes data, %llu bytes sealed\n",
305
(unsigned long long)out_buf.length,
306
(unsigned long long)in_buf.length));
307
308
xdrmem_create(&temp_xdrs, out_buf.value, out_buf.length, XDR_DECODE);
309
310
/* deserialize the sequence number */
311
if (! xdr_u_int32(&temp_xdrs, &verf_seq_num)) {
312
PRINTF(("gssapi_unwrap_data: deserializing verf_seq_num failed\n"));
313
gss_release_buffer(minor, &out_buf);
314
XDR_DESTROY(&temp_xdrs);
315
return FALSE;
316
}
317
if (verf_seq_num != seq_num) {
318
PRINTF(("gssapi_unwrap_data: seq %d specified, read %d\n",
319
seq_num, verf_seq_num));
320
gss_release_buffer(minor, &out_buf);
321
XDR_DESTROY(&temp_xdrs);
322
return FALSE;
323
}
324
PRINTF(("gssapi_unwrap_data: unwrap seq_num %d okay\n", verf_seq_num));
325
326
/* deserialize the arguments into xdr_ptr */
327
if (! (*xdr_func)(&temp_xdrs, xdr_ptr)) {
328
PRINTF(("gssapi_unwrap_data: deserializing arguments failed\n"));
329
gss_release_buffer(minor, &out_buf);
330
XDR_DESTROY(&temp_xdrs);
331
return FALSE;
332
}
333
334
PRINTF(("gssapi_unwrap_data: succeeding\n\n"));
335
336
gss_release_buffer(minor, &out_buf);
337
XDR_DESTROY(&temp_xdrs);
338
return TRUE;
339
}
340
341