Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/plugins/authdata/greet_client/greet.c
34909 views
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
/* plugins/authdata/greet_client/greet.c - Sample authorization data plugin */
3
/*
4
* Copyright 2009 by the Massachusetts Institute of Technology.
5
*
6
* Export of this software from the United States of America may
7
* require a specific license from the United States Government.
8
* It is the responsibility of any person or organization contemplating
9
* export to obtain such a license before exporting.
10
*
11
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
12
* distribute this software and its documentation for any purpose and
13
* without fee is hereby granted, provided that the above copyright
14
* notice appear in all copies and that both that copyright notice and
15
* this permission notice appear in supporting documentation, and that
16
* the name of M.I.T. not be used in advertising or publicity pertaining
17
* to distribution of the software without specific, written prior
18
* permission. Furthermore if you modify this software you must label
19
* your software as modified software and not distribute it in such a
20
* fashion that it might be confused with the original M.I.T. software.
21
* M.I.T. makes no representations about the suitability of
22
* this software for any purpose. It is provided "as is" without express
23
* or implied warranty.
24
*/
25
26
#include "k5-int.h"
27
#include <krb5/authdata_plugin.h>
28
#include <assert.h>
29
30
struct greet_context {
31
krb5_data greeting;
32
krb5_boolean verified;
33
};
34
35
static krb5_data greet_attr = {
36
KV5M_DATA, sizeof("urn:greet:greeting") - 1, "urn:greet:greeting" };
37
38
static krb5_error_code
39
greet_init(krb5_context kcontext, void **plugin_context)
40
{
41
*plugin_context = 0;
42
return 0;
43
}
44
45
static void
46
greet_flags(krb5_context kcontext,
47
void *plugin_context,
48
krb5_authdatatype ad_type,
49
krb5_flags *flags)
50
{
51
*flags = AD_USAGE_AP_REQ | AD_USAGE_KDC_ISSUED | AD_INFORMATIONAL;
52
}
53
54
static void
55
greet_fini(krb5_context kcontext, void *plugin_context)
56
{
57
return;
58
}
59
60
static krb5_error_code
61
greet_request_init(krb5_context kcontext,
62
krb5_authdata_context context,
63
void *plugin_context,
64
void **request_context)
65
{
66
struct greet_context *greet;
67
68
greet = malloc(sizeof(*greet));
69
if (greet == NULL)
70
return ENOMEM;
71
72
greet->greeting.data = NULL;
73
greet->greeting.length = 0;
74
greet->verified = FALSE;
75
76
*request_context = greet;
77
78
return 0;
79
}
80
81
static krb5_error_code
82
greet_export_authdata(krb5_context kcontext,
83
krb5_authdata_context context,
84
void *plugin_context,
85
void *request_context,
86
krb5_flags usage,
87
krb5_authdata ***out_authdata)
88
{
89
struct greet_context *greet = (struct greet_context *)request_context;
90
krb5_authdata *data[2];
91
krb5_authdata datum;
92
krb5_error_code code;
93
94
datum.ad_type = -42;
95
datum.length = greet->greeting.length;
96
datum.contents = (krb5_octet *)greet->greeting.data;
97
98
data[0] = &datum;
99
data[1] = NULL;
100
101
code = krb5_copy_authdata(kcontext, data, out_authdata);
102
103
return code;
104
}
105
106
static krb5_error_code
107
greet_import_authdata(krb5_context kcontext,
108
krb5_authdata_context context,
109
void *plugin_context,
110
void *request_context,
111
krb5_authdata **authdata,
112
krb5_boolean kdc_issued_flag,
113
krb5_const_principal issuer)
114
{
115
krb5_error_code code;
116
struct greet_context *greet = (struct greet_context *)request_context;
117
krb5_data data;
118
119
krb5_free_data_contents(kcontext, &greet->greeting);
120
greet->verified = FALSE;
121
122
assert(authdata[0] != NULL);
123
124
data.length = authdata[0]->length;
125
data.data = (char *)authdata[0]->contents;
126
127
code = krb5int_copy_data_contents_add0(kcontext, &data, &greet->greeting);
128
if (code == 0)
129
greet->verified = kdc_issued_flag;
130
131
return code;
132
}
133
134
static void
135
greet_request_fini(krb5_context kcontext,
136
krb5_authdata_context context,
137
void *plugin_context,
138
void *request_context)
139
{
140
struct greet_context *greet = (struct greet_context *)request_context;
141
142
if (greet != NULL) {
143
krb5_free_data_contents(kcontext, &greet->greeting);
144
free(greet);
145
}
146
}
147
148
static krb5_error_code
149
greet_get_attribute_types(krb5_context kcontext,
150
krb5_authdata_context context,
151
void *plugin_context,
152
void *request_context,
153
krb5_data **out_attrs)
154
{
155
krb5_error_code code;
156
struct greet_context *greet = (struct greet_context *)request_context;
157
158
if (greet->greeting.length == 0)
159
return ENOENT;
160
161
*out_attrs = calloc(2, sizeof(krb5_data));
162
if (*out_attrs == NULL)
163
return ENOMEM;
164
165
code = krb5int_copy_data_contents_add0(kcontext,
166
&greet_attr,
167
&(*out_attrs)[0]);
168
if (code != 0) {
169
free(*out_attrs);
170
*out_attrs = NULL;
171
return code;
172
}
173
174
return 0;
175
}
176
177
static krb5_error_code
178
greet_get_attribute(krb5_context kcontext,
179
krb5_authdata_context context,
180
void *plugin_context,
181
void *request_context,
182
const krb5_data *attribute,
183
krb5_boolean *authenticated,
184
krb5_boolean *complete,
185
krb5_data *value,
186
krb5_data *display_value,
187
int *more)
188
{
189
struct greet_context *greet = (struct greet_context *)request_context;
190
krb5_error_code code;
191
192
if (!data_eq(*attribute, greet_attr) || greet->greeting.length == 0)
193
return ENOENT;
194
195
*authenticated = greet->verified;
196
*complete = TRUE;
197
*more = 0;
198
199
code = krb5int_copy_data_contents_add0(kcontext, &greet->greeting, value);
200
if (code == 0) {
201
code = krb5int_copy_data_contents_add0(kcontext,
202
&greet->greeting,
203
display_value);
204
if (code != 0)
205
krb5_free_data_contents(kcontext, value);
206
}
207
208
return code;
209
}
210
211
static krb5_error_code
212
greet_set_attribute(krb5_context kcontext,
213
krb5_authdata_context context,
214
void *plugin_context,
215
void *request_context,
216
krb5_boolean complete,
217
const krb5_data *attribute,
218
const krb5_data *value)
219
{
220
struct greet_context *greet = (struct greet_context *)request_context;
221
krb5_data data;
222
krb5_error_code code;
223
224
if (!data_eq(*attribute, greet_attr))
225
return ENOENT;
226
227
if (greet->greeting.data != NULL)
228
return EEXIST;
229
230
code = krb5int_copy_data_contents_add0(kcontext, value, &data);
231
if (code != 0)
232
return code;
233
234
krb5_free_data_contents(kcontext, &greet->greeting);
235
greet->greeting = data;
236
greet->verified = FALSE;
237
238
return 0;
239
}
240
241
static krb5_error_code
242
greet_delete_attribute(krb5_context kcontext,
243
krb5_authdata_context context,
244
void *plugin_context,
245
void *request_context,
246
const krb5_data *attribute)
247
{
248
struct greet_context *greet = (struct greet_context *)request_context;
249
250
krb5_free_data_contents(kcontext, &greet->greeting);
251
greet->verified = FALSE;
252
253
return 0;
254
}
255
256
static krb5_error_code
257
greet_size(krb5_context kcontext,
258
krb5_authdata_context context,
259
void *plugin_context,
260
void *request_context,
261
size_t *sizep)
262
{
263
struct greet_context *greet = (struct greet_context *)request_context;
264
265
*sizep += sizeof(krb5_int32) +
266
greet->greeting.length +
267
sizeof(krb5_int32);
268
269
return 0;
270
}
271
272
static krb5_error_code
273
greet_externalize(krb5_context kcontext,
274
krb5_authdata_context context,
275
void *plugin_context,
276
void *request_context,
277
krb5_octet **buffer,
278
size_t *lenremain)
279
{
280
size_t required = 0;
281
struct greet_context *greet = (struct greet_context *)request_context;
282
283
greet_size(kcontext, context, plugin_context,
284
request_context, &required);
285
286
if (*lenremain < required)
287
return ENOMEM;
288
289
/* Greeting Length | Greeting Contents | Verified */
290
krb5_ser_pack_int32(greet->greeting.length, buffer, lenremain);
291
krb5_ser_pack_bytes((krb5_octet *)greet->greeting.data,
292
(size_t)greet->greeting.length,
293
buffer, lenremain);
294
krb5_ser_pack_int32((krb5_int32)greet->verified, buffer, lenremain);
295
296
return 0;
297
}
298
299
static krb5_error_code
300
greet_internalize(krb5_context kcontext,
301
krb5_authdata_context context,
302
void *plugin_context,
303
void *request_context,
304
krb5_octet **buffer,
305
size_t *lenremain)
306
{
307
struct greet_context *greet = (struct greet_context *)request_context;
308
krb5_error_code code;
309
krb5_int32 length;
310
krb5_octet *contents = NULL;
311
krb5_int32 verified;
312
krb5_octet *bp;
313
size_t remain;
314
315
bp = *buffer;
316
remain = *lenremain;
317
318
/* Greeting Length */
319
code = krb5_ser_unpack_int32(&length, &bp, &remain);
320
if (code != 0)
321
return code;
322
323
/* Greeting Contents */
324
if (length != 0) {
325
contents = malloc(length);
326
if (contents == NULL)
327
return ENOMEM;
328
329
code = krb5_ser_unpack_bytes(contents, (size_t)length, &bp, &remain);
330
if (code != 0) {
331
free(contents);
332
return code;
333
}
334
}
335
336
/* Verified */
337
code = krb5_ser_unpack_int32(&verified, &bp, &remain);
338
if (code != 0) {
339
free(contents);
340
return code;
341
}
342
343
krb5_free_data_contents(kcontext, &greet->greeting);
344
greet->greeting.length = length;
345
greet->greeting.data = (char *)contents;
346
greet->verified = (verified != 0);
347
348
*buffer = bp;
349
*lenremain = remain;
350
351
return 0;
352
}
353
354
static krb5_authdatatype greet_ad_types[] = { -42, 0 };
355
356
krb5plugin_authdata_client_ftable_v0 authdata_client_0 = {
357
"greet",
358
greet_ad_types,
359
greet_init,
360
greet_fini,
361
greet_flags,
362
greet_request_init,
363
greet_request_fini,
364
greet_get_attribute_types,
365
greet_get_attribute,
366
greet_set_attribute,
367
greet_delete_attribute,
368
greet_export_authdata,
369
greet_import_authdata,
370
NULL,
371
NULL,
372
NULL,
373
greet_size,
374
greet_externalize,
375
greet_internalize,
376
NULL
377
};
378
379