1
2 #define __KRB5_MECHTYPE_OID &mygss_mech_krb5
3 #define __KRB5_OLD_MECHTYPE_OID &mygss_mech_krb5_old
4 #define __SPNEGO_MECHTYPE_OID &myspnego_oid_desc
5 #define __GSS_KRB5_NT_USER_NAME &mygss_nt_krb5_name
6 #define __GSS_KRB5_NT_PRINCIPAL_NAME &mygss_nt_krb5_principal
7 #define __gss_mech_krb5_v2 &mygss_mech_krb5_v2
8
9 /*
10 | Defines explanation:
11 |
12 | SEAM
13 | different structure of headerfiles on Solaris 10 / Opensolaris
14 | Trigger for setting SEAM is 'Solaris' keyword in output
15 | of krb5-config --version (See Makefile.PL)
16 | See <http://rt.cpan.org/Public/Bug/Display.html?id=32788>
17 |
18 | MITKERB12
19 | MIT-kerbeors of version 1.2.x does not provide alls constants
20 | of the uppercase GSS_C* style. Some tweaking is required.
21 | Trigger for setting MITKERB12 is the version-number in output
22 | of krb5-config --version (See Makefile.PL)
23 |
24 */
25
26 #if defined(HEIMDAL)
27 #include <gssapi.h>
28 #endif
29
30 #if !defined(HEIMDAL)
31
32 #include <gssapi/gssapi.h>
33 #if !defined(SEAM)
34 #include <gssapi/gssapi_generic.h>
35 #include <gssapi/gssapi_krb5.h>
36 #else
37 #include <gssapi/gssapi_ext.h>
38 #endif
39 #if defined(MITKERB12)
40 /* symbols not defined in MIT Kerberos 1.2.x */
41 #define GSS_C_NT_USER_NAME gss_nt_user_name
42 #define GSS_C_NT_MACHINE_UID_NAME gss_nt_machine_uid_name
43 #define GSS_C_NT_STRING_UID_NAME gss_nt_string_uid_name
44 #define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
45 #define GSS_C_NT_EXPORT_NAME gss_nt_exported_name
46 #endif
47 #endif
48
49 /*
50
51 See
52 http://mailman.mit.edu/pipermail/krbdev/2005-February/003193.html
53 "
54 */
55
56 #include "EXTERN.h"
57 #include "perl.h"
58 #include "XSUB.h"
59 #define NEED_newCONSTSUB
60 #include "ppport.h"
61
62 static gss_OID_desc mygss_mech_krb5 = {9, (void *) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"};
63 static gss_OID_desc mygss_mech_krb5_old = {5, (void *) "\x2b\x05\x01\x05\x02"};
64
65 static gss_OID_desc myspnego_oid_desc = {6, (void *) "\x2b\x06\x01\x05\x05\x02"};
66
67 static gss_OID_desc mygss_nt_krb5_name = {10, (void *) "\052\206\110\206\367\022\001\002\002\001"};
68
69 static gss_OID_desc mygss_nt_krb5_principal = {10, (void *) "\052\206\110\206\367\022\001\002\002\002"};
70
71 static gss_OID_desc mygss_mech_krb5_v2 = {9, (void *) "\052\206\110\206\367\022\001\002\003"};
72
73
74
75 static double
constant(char * name,int len,int arg)76 constant(char *name, int len, int arg)
77 {
78 warn("GSSAPI.xs - function constant() should never be called");
79 return 0;
80
81 }
82
83
84
85 /*
86 * These are not part of the GSSAPI C bindings, so we can't count on
87 * them being defined. They are part of the Kerberos 1.2 GSSAPI binding
88 * so we'll provide them
89 */
90
91 #ifndef GSS_CALLING_ERROR_FIELD
92 #define GSS_CALLING_ERROR_FIELD(x) \
93 (((x) >> GSS_C_CALLING_ERROR_OFFSET) & GSS_C_CALLING_ERROR_MASK)
94 #endif
95 #ifndef GSS_ROUTINE_ERROR_FIELD
96 #define GSS_ROUTINE_ERROR_FIELD(x) \
97 (((x) >> GSS_C_ROUTINE_ERROR_OFFSET) & GSS_C_ROUTINE_ERROR_MASK)
98 #endif
99 #ifndef GSS_SUPPLEMENTARY_INFO_FIELD
100 #define GSS_SUPPLEMENTARY_INFO_FIELD(x) \
101 (((x) >> GSS_C_SUPPLEMENTARY_OFFSET) & GSS_C_SUPPLEMENTARY_MASK)
102 #endif
103
104
105 typedef struct {
106 OM_uint32 major, minor;
107 } gss_status_desc;
108 typedef gss_status_desc GSSAPI__Status;
109
110 typedef gss_name_t GSSAPI__Name;
111 typedef gss_OID GSSAPI__OID;
112 typedef gss_OID_set GSSAPI__OID__Set;
113 typedef gss_cred_id_t GSSAPI__Cred;
114 typedef gss_ctx_id_t GSSAPI__Context;
115 typedef gss_channel_bindings_t GSSAPI__Binding;
116
117 typedef const gss_OID_desc * GSSAPI__OID_const;
118 typedef const gss_OID_set_desc * GSSAPI__OID__Set_const;
119
120 typedef gss_ctx_id_t GSSAPI__Context_Iopt;
121
122 typedef gss_name_t GSSAPI__Name_out;
123 typedef gss_OID GSSAPI__OID_out;
124 typedef gss_OID_set GSSAPI__OID__Set_out;
125 typedef gss_cred_id_t GSSAPI__Cred_out;
126 typedef gss_ctx_id_t GSSAPI__Context_out;
127 typedef gss_channel_bindings_t GSSAPI__Binding_out;
128 typedef I32 I32_out;
129 typedef int int_out;
130 typedef gss_cred_usage_t gss_cred_usage_t_out;
131 typedef U32 U32_out;
132 typedef OM_uint32 OM_uint32_out;
133
134 typedef gss_name_t * GSSAPI__Name_optout;
135 typedef gss_OID * GSSAPI__OID_optout;
136 typedef gss_OID_set * GSSAPI__OID__Set_optout;
137 typedef gss_cred_id_t * GSSAPI__Cred_optout;
138 typedef I32 * I32_optout;
139 typedef int * int_optout;
140 typedef gss_cred_usage_t * gss_cred_usage_t_optout;
141 typedef U32 * U32_optout;
142 typedef OM_uint32 * OM_uint32_optout;
143
144 typedef gss_name_t GSSAPI__Name_opt;
145 typedef gss_OID GSSAPI__OID_opt;
146 typedef gss_OID_set GSSAPI__OID__Set_opt;
147 typedef gss_channel_bindings_t GSSAPI__Binding_opt;
148 typedef gss_cred_id_t GSSAPI__Cred_opt;
149 typedef gss_ctx_id_t GSSAPI__Context_opt;
150
151 typedef gss_buffer_desc gss_buffer_desc_out;
152 typedef gss_buffer_desc gss_buffer_desc_copy;
153 typedef gss_buffer_desc gss_buffer_str;
154 typedef gss_buffer_desc gss_buffer_str_out;
155
156 typedef void * GSSAPI_obj;
157
158 typedef gss_buffer_desc gss_oidstr_out;
159
160 int
oid_set_is_dynamic(GSSAPI__OID__Set oidset)161 oid_set_is_dynamic(GSSAPI__OID__Set oidset)
162 {
163 return 1; /* 2006-02-13 all static sets are deleted */
164 }
165
166
167 MODULE = GSSAPI PACKAGE = GSSAPI
168
169
170 BOOT:
171 {
172 HV *stash = gv_stashpvn ("GSSAPI", 6, TRUE );
173 #if defined( GSS_C_ACCEPT )
174 newCONSTSUB( stash, "GSS_C_ACCEPT", newSVuv( GSS_C_ACCEPT ) );
175 #endif
176 #if defined( GSS_C_AF_APPLETALK )
177 newCONSTSUB( stash, "GSS_C_AF_APPLETALK", newSVuv( GSS_C_AF_APPLETALK ) );
178 #endif
179 #if defined( GSS_C_AF_BSC )
180 newCONSTSUB( stash, "GSS_C_AF_BSC", newSVuv( GSS_C_AF_BSC ) );
181 #endif
182 #if defined( GSS_C_AF_CCITT )
183 newCONSTSUB( stash, "GSS_C_AF_CCITT", newSVuv( GSS_C_AF_CCITT ) );
184 #endif
185 #if defined( GSS_C_AF_CHAOS )
186 newCONSTSUB( stash, "GSS_C_AF_CHAOS", newSVuv( GSS_C_AF_CHAOS ) );
187 #endif
188 #if defined( GSS_C_AF_DATAKIT )
189 newCONSTSUB( stash, "GSS_C_AF_DATAKIT", newSVuv( GSS_C_AF_DATAKIT ) );
190 #endif
191 #if defined( GSS_C_AF_DECnet )
192 newCONSTSUB( stash, "GSS_C_AF_DECnet", newSVuv( GSS_C_AF_DECnet ) );
193 #endif
194 #if defined( GSS_C_AF_DLI )
195 newCONSTSUB( stash, "GSS_C_AF_DLI", newSVuv( GSS_C_AF_DLI ) );
196 #endif
197 #if defined( GSS_C_AF_DSS )
198 newCONSTSUB( stash, "GSS_C_AF_DSS", newSVuv( GSS_C_AF_DSS ) );
199 #endif
200 #if defined( GSS_C_AF_ECMA )
201 newCONSTSUB( stash, "GSS_C_AF_ECMA", newSVuv( GSS_C_AF_ECMA ) );
202 #endif
203 #if defined( GSS_C_AF_HYLINK )
204 newCONSTSUB( stash, "GSS_C_AF_HYLINK", newSVuv( GSS_C_AF_HYLINK ) );
205 #endif
206 #if defined( GSS_C_AF_IMPLINK )
207 newCONSTSUB( stash, "GSS_C_AF_IMPLINK", newSVuv( GSS_C_AF_IMPLINK ) );
208 #endif
209 #if defined( GSS_C_AF_INET )
210 newCONSTSUB( stash, "GSS_C_AF_INET", newSVuv( GSS_C_AF_INET ) );
211 #endif
212 #if defined( GSS_C_AF_LAT )
213 newCONSTSUB( stash, "GSS_C_AF_LAT", newSVuv( GSS_C_AF_LAT ) );
214 #endif
215 #if defined( GSS_C_AF_LOCAL )
216 newCONSTSUB( stash, "GSS_C_AF_LOCAL", newSVuv( GSS_C_AF_LOCAL ) );
217 #endif
218 #if defined( GSS_C_AF_NBS )
219 newCONSTSUB( stash, "GSS_C_AF_NBS", newSVuv( GSS_C_AF_NBS ) );
220 #endif
221 #if defined( GSS_C_AF_NS )
222 newCONSTSUB( stash, "GSS_C_AF_NS", newSVuv( GSS_C_AF_NS ) );
223 #endif
224 #if defined( GSS_C_AF_NULLADDR )
225 newCONSTSUB( stash, "GSS_C_AF_NULLADDR", newSVuv( GSS_C_AF_NULLADDR ) );
226 #endif
227 #if defined( GSS_C_AF_OSI )
228 newCONSTSUB( stash, "GSS_C_AF_OSI", newSVuv( GSS_C_AF_OSI ) );
229 #endif
230 #if defined( GSS_C_AF_PUP )
231 newCONSTSUB( stash, "GSS_C_AF_PUP", newSVuv( GSS_C_AF_PUP ) );
232 #endif
233 #if defined( GSS_C_AF_SNA )
234 newCONSTSUB( stash, "GSS_C_AF_SNA", newSVuv( GSS_C_AF_SNA ) );
235 #endif
236 #if defined( GSS_C_AF_UNSPEC )
237 newCONSTSUB( stash, "GSS_C_AF_UNSPEC", newSVuv( GSS_C_AF_UNSPEC ) );
238 #endif
239 #if defined( GSS_C_AF_X25 )
240 newCONSTSUB( stash, "GSS_C_AF_X25", newSVuv( GSS_C_AF_X25 ) );
241 #endif
242 #if defined( GSS_C_ANON_FLAG )
243 newCONSTSUB( stash, "GSS_C_ANON_FLAG", newSVuv( GSS_C_ANON_FLAG ) );
244 #endif
245 #if defined( GSS_C_BOTH )
246 newCONSTSUB( stash, "GSS_C_BOTH", newSVuv( GSS_C_BOTH ) );
247 #endif
248 #if defined( GSS_C_CALLING_ERROR_MASK )
249 newCONSTSUB( stash, "GSS_C_CALLING_ERROR_MASK", newSVuv( GSS_C_CALLING_ERROR_MASK ) );
250 #endif
251 #if defined( GSS_C_CALLING_ERROR_OFFSET )
252 newCONSTSUB( stash, "GSS_C_CALLING_ERROR_OFFSET", newSVuv( GSS_C_CALLING_ERROR_OFFSET ) );
253 #endif
254 #if defined( GSS_C_CONF_FLAG )
255 newCONSTSUB( stash, "GSS_C_CONF_FLAG", newSVuv( GSS_C_CONF_FLAG ) );
256 #endif
257 #if defined( GSS_C_DELEG_FLAG )
258 newCONSTSUB( stash, "GSS_C_DELEG_FLAG", newSVuv( GSS_C_DELEG_FLAG ) );
259 #endif
260 #if defined( GSS_C_GSS_CODE )
261 newCONSTSUB( stash, "GSS_C_GSS_CODE", newSVuv( GSS_C_GSS_CODE ) );
262 #endif
263 #if defined( GSS_C_INDEFINITE )
264 newCONSTSUB( stash, "GSS_C_INDEFINITE", newSVuv( GSS_C_INDEFINITE ) );
265 #endif
266 #if defined( GSS_C_INITIATE )
267 newCONSTSUB( stash, "GSS_C_INITIATE", newSVuv( GSS_C_INITIATE ) );
268 #endif
269 #if defined( GSS_C_INTEG_FLAG )
270 newCONSTSUB( stash, "GSS_C_INTEG_FLAG", newSVuv( GSS_C_INTEG_FLAG ) );
271 #endif
272 #if defined( GSS_C_MECH_CODE )
273 newCONSTSUB( stash, "GSS_C_MECH_CODE", newSVuv( GSS_C_MECH_CODE ) );
274 #endif
275 #if defined( GSS_C_MUTUAL_FLAG )
276 newCONSTSUB( stash, "GSS_C_MUTUAL_FLAG", newSVuv( GSS_C_MUTUAL_FLAG ) );
277 #endif
278 #if defined( GSS_C_PROT_READY_FLAG )
279 newCONSTSUB( stash, "GSS_C_PROT_READY_FLAG", newSVuv( GSS_C_PROT_READY_FLAG ) );
280 #endif
281 #if defined( GSS_C_QOP_DEFAULT )
282 newCONSTSUB( stash, "GSS_C_QOP_DEFAULT", newSVuv( GSS_C_QOP_DEFAULT ) );
283 #endif
284 #if defined( GSS_C_REPLAY_FLAG )
285 newCONSTSUB( stash, "GSS_C_REPLAY_FLAG", newSVuv( GSS_C_REPLAY_FLAG ) );
286 #endif
287 #if defined( GSS_C_ROUTINE_ERROR_MASK )
288 newCONSTSUB( stash, "GSS_C_ROUTINE_ERROR_MASK", newSVuv( GSS_C_ROUTINE_ERROR_MASK ) );
289 #endif
290 #if defined( GSS_C_ROUTINE_ERROR_OFFSET )
291 newCONSTSUB( stash, "GSS_C_ROUTINE_ERROR_OFFSET", newSVuv( GSS_C_ROUTINE_ERROR_OFFSET ) );
292 #endif
293 #if defined( GSS_C_SEQUENCE_FLAG )
294 newCONSTSUB( stash, "GSS_C_SEQUENCE_FLAG", newSVuv( GSS_C_SEQUENCE_FLAG ) );
295 #endif
296 #if defined( GSS_C_SUPPLEMENTARY_MASK )
297 newCONSTSUB( stash, "GSS_C_SUPPLEMENTARY_MASK", newSVuv( GSS_C_SUPPLEMENTARY_MASK ) );
298 #endif
299 #if defined( GSS_C_SUPPLEMENTARY_OFFSET )
300 newCONSTSUB( stash, "GSS_C_SUPPLEMENTARY_OFFSET", newSVuv( GSS_C_SUPPLEMENTARY_OFFSET ) );
301 #endif
302 #if defined( GSS_C_TRANS_FLAG )
303 newCONSTSUB( stash, "GSS_C_TRANS_FLAG", newSVuv( GSS_C_TRANS_FLAG ) );
304 #endif
305 #if defined( GSS_S_BAD_BINDINGS )
306 newCONSTSUB( stash, "GSS_S_BAD_BINDINGS", newSVuv( GSS_S_BAD_BINDINGS ) );
307 #endif
308 #if defined( GSS_S_BAD_MECH )
309 newCONSTSUB( stash, "GSS_S_BAD_MECH", newSVuv( GSS_S_BAD_MECH ) );
310 #endif
311 #if defined( GSS_S_BAD_NAME )
312 newCONSTSUB( stash, "GSS_S_BAD_NAME", newSVuv( GSS_S_BAD_NAME ) );
313 #endif
314 #if defined( GSS_S_BAD_NAMETYPE )
315 newCONSTSUB( stash, "GSS_S_BAD_NAMETYPE", newSVuv( GSS_S_BAD_NAMETYPE ) );
316 #endif
317 #if defined( GSS_S_BAD_QOP )
318 newCONSTSUB( stash, "GSS_S_BAD_QOP", newSVuv( GSS_S_BAD_QOP ) );
319 #endif
320 #if defined( GSS_S_BAD_SIG )
321 newCONSTSUB( stash, "GSS_S_BAD_SIG", newSVuv( GSS_S_BAD_SIG ) );
322 #endif
323 #if defined( GSS_S_BAD_STATUS )
324 newCONSTSUB( stash, "GSS_S_BAD_STATUS", newSVuv( GSS_S_BAD_STATUS ) );
325 #endif
326 #if defined( GSS_S_CALL_BAD_STRUCTURE )
327 newCONSTSUB( stash, "GSS_S_CALL_BAD_STRUCTURE", newSVuv( GSS_S_CALL_BAD_STRUCTURE ) );
328 #endif
329 #if defined( GSS_S_CALL_INACCESSIBLE_READ )
330 newCONSTSUB( stash, "GSS_S_CALL_INACCESSIBLE_READ", newSVuv( GSS_S_CALL_INACCESSIBLE_READ ) );
331 #endif
332 #if defined( GSS_S_CALL_INACCESSIBLE_WRITE )
333 newCONSTSUB( stash, "GSS_S_CALL_INACCESSIBLE_WRITE", newSVuv( GSS_S_CALL_INACCESSIBLE_WRITE ) );
334 #endif
335 #if defined( GSS_S_COMPLETE )
336 newCONSTSUB( stash, "GSS_S_COMPLETE", newSVuv( GSS_S_COMPLETE ) );
337 #endif
338 #if defined( GSS_S_CONTEXT_EXPIRED )
339 newCONSTSUB( stash, "GSS_S_CONTEXT_EXPIRED", newSVuv( GSS_S_CONTEXT_EXPIRED ) );
340 #endif
341 #if defined( GSS_S_CONTINUE_NEEDED )
342 newCONSTSUB( stash, "GSS_S_CONTINUE_NEEDED", newSVuv( GSS_S_CONTINUE_NEEDED ) );
343 #endif
344 #if defined( GSS_S_CREDENTIALS_EXPIRED )
345 newCONSTSUB( stash, "GSS_S_CREDENTIALS_EXPIRED", newSVuv( GSS_S_CREDENTIALS_EXPIRED ) );
346 #endif
347 #if defined( GSS_S_CRED_UNAVAIL )
348 newCONSTSUB( stash, "GSS_S_CRED_UNAVAIL", newSVuv( GSS_S_CRED_UNAVAIL ) );
349 #endif
350 #if defined( GSS_S_DEFECTIVE_CREDENTIAL )
351 newCONSTSUB( stash, "GSS_S_DEFECTIVE_CREDENTIAL", newSVuv( GSS_S_DEFECTIVE_CREDENTIAL ) );
352 #endif
353 #if defined( GSS_S_DEFECTIVE_TOKEN )
354 newCONSTSUB( stash, "GSS_S_DEFECTIVE_TOKEN", newSVuv( GSS_S_DEFECTIVE_TOKEN ) );
355 #endif
356 #if defined( GSS_S_DUPLICATE_ELEMENT )
357 newCONSTSUB( stash, "GSS_S_DUPLICATE_ELEMENT", newSVuv( GSS_S_DUPLICATE_ELEMENT ) );
358 #endif
359 #if defined( GSS_S_DUPLICATE_TOKEN )
360 newCONSTSUB( stash, "GSS_S_DUPLICATE_TOKEN", newSVuv( GSS_S_DUPLICATE_TOKEN ) );
361 #endif
362 #if defined( GSS_S_FAILURE )
363 newCONSTSUB( stash, "GSS_S_FAILURE", newSVuv( GSS_S_FAILURE ) );
364 #endif
365 #if defined( GSS_S_GAP_TOKEN )
366 newCONSTSUB( stash, "GSS_S_GAP_TOKEN", newSVuv( GSS_S_GAP_TOKEN ) );
367 #endif
368 #if defined( GSS_S_NAME_NOT_MN )
369 newCONSTSUB( stash, "GSS_S_NAME_NOT_MN", newSVuv( GSS_S_NAME_NOT_MN ) );
370 #endif
371 #if defined( GSS_S_NO_CONTEXT )
372 newCONSTSUB( stash, "GSS_S_NO_CONTEXT", newSVuv( GSS_S_NO_CONTEXT ) );
373 #endif
374 #if defined( GSS_S_NO_CRED )
375 newCONSTSUB( stash, "GSS_S_NO_CRED", newSVuv( GSS_S_NO_CRED ) );
376 #endif
377 #if defined( GSS_S_OLD_TOKEN )
378 newCONSTSUB( stash, "GSS_S_OLD_TOKEN", newSVuv( GSS_S_OLD_TOKEN ) );
379 #endif
380 #if defined( GSS_S_UNAUTHORIZED )
381 newCONSTSUB( stash, "GSS_S_UNAUTHORIZED", newSVuv( GSS_S_UNAUTHORIZED ) );
382 #endif
383 #if defined( GSS_S_UNAVAILABLE )
384 newCONSTSUB( stash, "GSS_S_UNAVAILABLE", newSVuv( GSS_S_UNAVAILABLE ) );
385 #endif
386 #if defined( GSS_S_UNSEQ_TOKEN )
387 newCONSTSUB( stash, "GSS_S_UNSEQ_TOKEN", newSVuv( GSS_S_UNSEQ_TOKEN ) );
388 #endif
389 }
390
391
392 PROTOTYPES: ENABLE
393
394 int
395 gssapi_implementation_is_heimdal()
396 CODE:
397 #if defined(HEIMDAL)
398 RETVAL = 1;
399 #endif
400 #if !defined(HEIMDAL)
401 RETVAL = 0;
402 #endif
403 OUTPUT:
404 RETVAL
405
406
407 double
408 constant(sv,arg)
409 PREINIT:
410 STRLEN len;
411 INPUT:
412 SV * sv
413 char * s = SvPV(sv, len);
414 int arg
415 CODE:
416 RETVAL = constant(s,len,arg);
417 OUTPUT:
418 RETVAL
419
420
421 GSSAPI::Status
422 indicate_mechs(oidset)
423 GSSAPI::OID::Set_out oidset
424 CODE:
425 RETVAL.major = gss_indicate_mechs(&RETVAL.minor, &oidset);
426 OUTPUT:
427 RETVAL
428 oidset
429
430 bool
431 is_valid(object)
432 GSSAPI_obj object
433 CODE:
434 RETVAL = (object != NULL);
435 OUTPUT:
436 RETVAL
437
438
439 MODULE = GSSAPI PACKAGE = GSSAPI::Status
440
441 INCLUDE: xs/Status.xs
442
443
444 MODULE = GSSAPI PACKAGE = GSSAPI::Name
445
446 INCLUDE: xs/Name.xs
447
448
449 MODULE = GSSAPI PACKAGE = GSSAPI::OID
450
451 INCLUDE: xs/OID.xs
452
453
454 MODULE = GSSAPI PACKAGE = GSSAPI::OID::Set
455
456 INCLUDE: xs/OID__Set.xs
457
458
459 MODULE = GSSAPI PACKAGE = GSSAPI::Cred
460
461 INCLUDE: xs/Cred.xs
462
463
464 MODULE = GSSAPI PACKAGE = GSSAPI::Binding
465
466 INCLUDE: xs/Binding.xs
467
468
469 MODULE = GSSAPI PACKAGE = GSSAPI::Context
470
471 INCLUDE: xs/Context.xs
472