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