Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/tests/shlib/t_loader.c
34879 views
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
/* tests/shlib/t_loader.c */
3
/*
4
* Copyright (C) 2005 by the Massachusetts Institute of Technology.
5
* All rights reserved.
6
*
7
* Export of this software from the United States of America may
8
* require a specific license from the United States Government.
9
* It is the responsibility of any person or organization contemplating
10
* export to obtain such a license before exporting.
11
*
12
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13
* distribute this software and its documentation for any purpose and
14
* without fee is hereby granted, provided that the above copyright
15
* notice appear in all copies and that both that copyright notice and
16
* this permission notice appear in supporting documentation, and that
17
* the name of M.I.T. not be used in advertising or publicity pertaining
18
* to distribution of the software without specific, written prior
19
* permission. Furthermore if you modify this software you must label
20
* your software as modified software and not distribute it in such a
21
* fashion that it might be confused with the original M.I.T. software.
22
* M.I.T. makes no representations about the suitability of
23
* this software for any purpose. It is provided "as is" without express
24
* or implied warranty.
25
*/
26
27
#include "k5-platform.h"
28
#include "krb5.h"
29
#include "gssapi/gssapi.h"
30
#define HAVE_DLOPEN 1
31
32
static int verbose = 1;
33
34
#ifdef HAVE_DLFCN_H
35
# include <dlfcn.h>
36
#endif
37
/* Solaris man page recommends link.h too */
38
39
/* lazy = 1 means resolve symbols later, 0 means now; any
40
other flags we should be testing? On Windows, maybe?
41
42
Return value is the library handle. On error, print a message and
43
exit. */
44
#define do_open(LIB,REV,FLAGS) do_open_1(LIB,REV,FLAGS,__LINE__)
45
static void *do_open_1(const char *libname, const char *rev, int lazy, int line);
46
47
/* Look up a function symbol in the library and return a pointer.
48
49
The return value may need casting to the correct type. On error,
50
print a message and exit. */
51
static void *get_sym_1(void *libhandle, const char *sym, int line);
52
#define get_sym(LIB, NAME) get_sym_1(LIB, NAME, __LINE__)
53
#define GET_FSYM(TYPE, LIB, NAME) ((TYPE) get_sym(LIB, NAME))
54
#define get_gfun(LIB, NAME) ((OM_uint32 KRB5_CALLCONV(*)()) get_sym(LIB, NAME))
55
56
/* Close dynamically-opened library.
57
58
If the OS reports an error in doing so, print a message and
59
exit. */
60
#define do_close(X) do_close_1(X, __LINE__)
61
static void do_close_1(void *libhandle, int line);
62
63
#ifdef HAVE_DLOPEN
64
65
#ifdef _AIX
66
# define SHLIB_SUFFIX ".a"
67
#else
68
# define SHLIB_SUFFIX ".so"
69
#endif
70
71
#define HORIZ 25
72
73
static void *do_open_1(const char *libname, const char *rev,
74
int lazy, int line)
75
{
76
void *p;
77
char *namebuf;
78
int r;
79
80
if (verbose)
81
printf("from line %d: do_open(%s)...%*s", line, libname,
82
HORIZ-strlen(libname), "");
83
#ifdef _AIX
84
r = asprintf(&namebuf, "lib%s%s", libname, SHLIB_SUFFIX);
85
#else
86
r = asprintf(&namebuf, "lib%s%s(shr.o.%s)", libname, SHLIB_SUFFIX, rev);
87
#endif
88
if (r < 0) {
89
perror("asprintf");
90
exit(1);
91
}
92
93
#ifndef RTLD_MEMBER
94
#define RTLD_MEMBER 0
95
#endif
96
p = dlopen(namebuf, (lazy ? RTLD_LAZY : RTLD_NOW) | RTLD_MEMBER);
97
if (p == 0) {
98
fprintf(stderr, "dlopen of %s failed: %s\n", namebuf, dlerror());
99
exit(1);
100
}
101
free(namebuf);
102
if (verbose)
103
printf("done: %p\n", p);
104
return p;
105
}
106
107
#define SYM_PREFIX ""
108
static void *get_sym_1(void *libhandle, const char *symname, int line)
109
{
110
void *s;
111
112
/* Bah. Fix this later, if we care. */
113
assert(strlen(SYM_PREFIX) == 0);
114
115
if (verbose)
116
printf("from line %d: get_sym(%s)...%*s", line, symname,
117
HORIZ-strlen(symname), "");
118
119
s = dlsym(libhandle, symname);
120
if (s == 0) {
121
fprintf(stderr, "symbol %s not found\n", symname);
122
exit(1);
123
}
124
if (verbose)
125
printf("done: %p\n", s);
126
return s;
127
}
128
129
static void do_close_1(void *libhandle, int line)
130
{
131
if (verbose) {
132
char pbuf[3*sizeof(libhandle)+4];
133
snprintf(pbuf, sizeof(pbuf), "%p", libhandle);
134
printf("from line %d: do_close(%s)...%*s", line, pbuf,
135
HORIZ-1-strlen(pbuf), "");
136
}
137
if (dlclose(libhandle) != 0) {
138
fprintf(stderr, "dlclose failed: %s\n", dlerror());
139
exit(1);
140
}
141
if (verbose)
142
printf("done\n");
143
}
144
145
#elif defined _WIN32
146
147
static void *do_open(const char *libname, int lazy)
148
{
149
/* To be written? */
150
abort();
151
}
152
153
static void *get_sym(void *libhandle, const char *symname)
154
{
155
abort();
156
}
157
158
static void do_close(void *libhandle)
159
{
160
abort();
161
}
162
163
#else
164
165
static void *do_open(const char *libname, int lazy)
166
{
167
printf("don't know how to do dynamic loading here, punting\n");
168
exit(0);
169
}
170
171
static void *get_sym(void *libhandle, const char *symname)
172
{
173
abort();
174
}
175
176
static void do_close(void *libhandle)
177
{
178
abort();
179
}
180
181
#endif
182
183
int main(void)
184
{
185
void *celib, *k5lib, *gsslib, *celib2;
186
187
(void) setvbuf(stdout, 0, _IONBF, 0);
188
189
celib = do_open("com_err", "3.0", 0);
190
k5lib = do_open("krb5", "3.2", 0);
191
gsslib = do_open("gssapi_krb5", "2.2", 0);
192
celib2 = do_open("com_err", "3.0", 0);
193
do_close(celib2);
194
{
195
typedef krb5_error_code KRB5_CALLCONV (*ict)(krb5_context *);
196
typedef void KRB5_CALLCONV (*fct)(krb5_context);
197
198
ict init_context = (ict) get_sym(k5lib, "krb5_init_context");
199
fct free_context = (fct) get_sym(k5lib, "krb5_free_context");
200
krb5_context ctx;
201
krb5_error_code err;
202
203
#define CALLING(S) (verbose ? printf("at line %d: calling %s...%*s", __LINE__, #S, (int)(HORIZ+1-strlen(#S)), "") : 0)
204
#define DONE() (verbose ? printf("done\n") : 0)
205
206
CALLING(krb5_init_context);
207
err = init_context(&ctx);
208
DONE();
209
if (err) {
210
fprintf(stderr, "error 0x%lx initializing context\n",
211
(unsigned long) err);
212
exit(1);
213
}
214
CALLING(krb5_free_context);
215
free_context(ctx);
216
DONE();
217
}
218
celib2 = do_open("com_err", "3.0", 0);
219
do_close(celib);
220
do_close(k5lib);
221
do_close(celib2);
222
do_close(gsslib);
223
224
/* Test gssapi_krb5 without having loaded anything else. */
225
gsslib = do_open("gssapi_krb5", "2.2", 1);
226
{
227
OM_uint32 KRB5_CALLCONV (*init_sec_context)(OM_uint32 *, gss_cred_id_t,
228
gss_ctx_id_t *, gss_name_t,
229
gss_OID,
230
OM_uint32, OM_uint32,
231
gss_channel_bindings_t,
232
gss_buffer_t, gss_OID *,
233
gss_buffer_t,
234
OM_uint32 *, OM_uint32 *)
235
= get_gfun(gsslib, "gss_init_sec_context");
236
OM_uint32 KRB5_CALLCONV (*import_name)(OM_uint32 *, gss_buffer_t,
237
gss_OID, gss_name_t *)
238
= get_gfun(gsslib, "gss_import_name");
239
OM_uint32 KRB5_CALLCONV (*release_buffer)(OM_uint32 *, gss_buffer_t)
240
= get_gfun(gsslib, "gss_release_buffer");
241
OM_uint32 KRB5_CALLCONV (*release_name)(OM_uint32 *, gss_name_t *)
242
= get_gfun(gsslib, "gss_release_name");
243
OM_uint32 KRB5_CALLCONV (*delete_sec_context)(OM_uint32 *,
244
gss_ctx_id_t *,
245
gss_buffer_t)
246
= get_gfun(gsslib, "gss_delete_sec_context");
247
248
OM_uint32 gmaj, gmin;
249
OM_uint32 retflags;
250
gss_ctx_id_t gctx = GSS_C_NO_CONTEXT;
251
gss_buffer_desc token;
252
gss_name_t target;
253
static gss_buffer_desc target_name_buf = {
254
9, "[email protected]"
255
};
256
static gss_OID_desc service_name = {
257
10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04"
258
};
259
260
CALLING(gss_import_name);
261
gmaj = import_name(&gmin, &target_name_buf, &service_name, &target);
262
DONE();
263
if (gmaj != GSS_S_COMPLETE) {
264
fprintf(stderr,
265
"import_name reports error major 0x%lx minor 0x%lx(%ld)\n",
266
(unsigned long) gmaj, (unsigned long) gmin,
267
(signed long) gmin);
268
exit(1);
269
}
270
/* This will probably get different errors, depending on
271
whether we have tickets at the time. Doesn't matter much,
272
we're ignoring the error and testing whether we're doing
273
cleanup properly. (Though the internal cleanup needed in
274
the two cases might be different.) */
275
CALLING(gss_init_sec_context);
276
gmaj = init_sec_context(&gmin, GSS_C_NO_CREDENTIAL, &gctx, target,
277
GSS_C_NULL_OID, 0, 0, NULL, GSS_C_NO_BUFFER,
278
NULL, &token, &retflags, NULL);
279
DONE();
280
/* Ignore success/failure indication. */
281
if (token.length) {
282
CALLING(gss_release_buffer);
283
release_buffer(&gmin, &token);
284
DONE();
285
}
286
CALLING(gss_release_name);
287
release_name(&gmin, &target);
288
DONE();
289
if (gctx != GSS_C_NO_CONTEXT) {
290
CALLING(gss_delete_sec_context);
291
delete_sec_context(&gmin, gctx, GSS_C_NO_BUFFER);
292
DONE();
293
}
294
}
295
do_close(gsslib);
296
297
/* Test gssapi_krb5 with com_err already loaded, then unload
298
com_err first. */
299
celib = do_open("com_err", "3.0", 1);
300
gsslib = do_open("gssapi_krb5", "2.2", 1);
301
{
302
OM_uint32 KRB5_CALLCONV (*init_sec_context)(OM_uint32 *, gss_cred_id_t,
303
gss_ctx_id_t *, gss_name_t,
304
gss_OID,
305
OM_uint32, OM_uint32,
306
gss_channel_bindings_t,
307
gss_buffer_t, gss_OID *,
308
gss_buffer_t,
309
OM_uint32 *, OM_uint32 *)
310
= get_gfun(gsslib, "gss_init_sec_context");
311
OM_uint32 KRB5_CALLCONV (*import_name)(OM_uint32 *, gss_buffer_t,
312
gss_OID, gss_name_t *)
313
= get_gfun(gsslib, "gss_import_name");
314
OM_uint32 KRB5_CALLCONV (*release_buffer)(OM_uint32 *, gss_buffer_t)
315
= get_gfun(gsslib, "gss_release_buffer");
316
OM_uint32 KRB5_CALLCONV (*release_name)(OM_uint32 *, gss_name_t *)
317
= get_gfun(gsslib, "gss_release_name");
318
OM_uint32 KRB5_CALLCONV (*delete_sec_context)(OM_uint32 *,
319
gss_ctx_id_t *,
320
gss_buffer_t)
321
= get_gfun(gsslib, "gss_delete_sec_context");
322
323
OM_uint32 gmaj, gmin;
324
OM_uint32 retflags;
325
gss_ctx_id_t gctx = GSS_C_NO_CONTEXT;
326
gss_buffer_desc token;
327
gss_name_t target;
328
static gss_buffer_desc target_name_buf = {
329
9, "[email protected]"
330
};
331
static gss_OID_desc service_name = {
332
10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04"
333
};
334
335
CALLING(gss_import_name);
336
gmaj = import_name(&gmin, &target_name_buf, &service_name, &target);
337
DONE();
338
if (gmaj != GSS_S_COMPLETE) {
339
fprintf(stderr,
340
"import_name reports error major 0x%lx minor 0x%lx(%ld)\n",
341
(unsigned long) gmaj, (unsigned long) gmin,
342
(signed long) gmin);
343
exit(1);
344
}
345
/* This will probably get different errors, depending on
346
whether we have tickets at the time. Doesn't matter much,
347
we're ignoring the error and testing whether we're doing
348
cleanup properly. (Though the internal cleanup needed in
349
the two cases might be different.) */
350
CALLING(gss_init_sec_context);
351
gmaj = init_sec_context(&gmin, GSS_C_NO_CREDENTIAL, &gctx, target,
352
GSS_C_NULL_OID, 0, 0, NULL, GSS_C_NO_BUFFER,
353
NULL, &token, &retflags, NULL);
354
DONE();
355
/* Ignore success/failure indication. */
356
if (token.length) {
357
CALLING(gss_release_buffer);
358
release_buffer(&gmin, &token);
359
DONE();
360
}
361
CALLING(gss_release_name);
362
release_name(&gmin, &target);
363
DONE();
364
if (gctx != GSS_C_NO_CONTEXT) {
365
CALLING(gss_delete_sec_context);
366
delete_sec_context(&gmin, gctx, GSS_C_NO_BUFFER);
367
DONE();
368
}
369
}
370
do_close(celib);
371
do_close(gsslib);
372
373
return 0;
374
}
375
376