Annotation of embedaddon/curl/tests/libtest/stub_gssapi.c, revision 1.1.1.1
1.1 misho 1: /***************************************************************************
2: * _ _ ____ _
3: * Project ___| | | | _ \| |
4: * / __| | | | |_) | |
5: * | (__| |_| | _ <| |___
6: * \___|\___/|_| \_\_____|
7: *
8: * Copyright (C) 2017-2019, Daniel Stenberg, <daniel@haxx.se>, et al.
9: *
10: * This software is licensed as described in the file COPYING, which
11: * you should have received as part of this distribution. The terms
12: * are also available at https://curl.haxx.se/docs/copyright.html.
13: *
14: * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15: * copies of the Software, and permit persons to whom the Software is
16: * furnished to do so, under the terms of the COPYING file.
17: *
18: * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19: * KIND, either express or implied.
20: *
21: ***************************************************************************/
22:
23: /* Only provides the bare minimum to link with libcurl */
24:
25: #include <stdio.h>
26: #include <stdlib.h>
27: #include <string.h>
28:
29: #include "stub_gssapi.h"
30:
31: /* !checksrc! disable SNPRINTF all */
32:
33: #define MAX_CREDS_LENGTH 250
34: #define APPROX_TOKEN_LEN 250
35:
36: enum min_err_code {
37: GSS_OK = 0,
38: GSS_NO_MEMORY,
39: GSS_INVALID_ARGS,
40: GSS_INVALID_CREDS,
41: GSS_INVALID_CTX,
42: GSS_SERVER_ERR,
43: GSS_NO_MECH,
44: GSS_LAST
45: };
46:
47: static const char *min_err_table[] = {
48: "stub-gss: no error",
49: "stub-gss: no memory",
50: "stub-gss: invalid arguments",
51: "stub-gss: invalid credentials",
52: "stub-gss: invalid context",
53: "stub-gss: server returned error",
54: "stub-gss: cannot find a mechanism",
55: NULL
56: };
57:
58: struct gss_ctx_id_t_desc_struct {
59: enum { NONE, KRB5, NTLM1, NTLM3 } sent;
60: int have_krb5;
61: int have_ntlm;
62: OM_uint32 flags;
63: char creds[MAX_CREDS_LENGTH];
64: };
65:
66: OM_uint32 gss_init_sec_context(OM_uint32 *min,
67: gss_const_cred_id_t initiator_cred_handle,
68: gss_ctx_id_t *context_handle,
69: gss_const_name_t target_name,
70: const gss_OID mech_type,
71: OM_uint32 req_flags,
72: OM_uint32 time_req,
73: const gss_channel_bindings_t input_chan_bindings,
74: const gss_buffer_t input_token,
75: gss_OID *actual_mech_type,
76: gss_buffer_t output_token,
77: OM_uint32 *ret_flags,
78: OM_uint32 *time_rec)
79: {
80: /* The token will be encoded in base64 */
81: int length = APPROX_TOKEN_LEN * 3 / 4;
82: int used = 0;
83: char *token = NULL;
84: const char *creds = NULL;
85: gss_ctx_id_t ctx = NULL;
86:
87: (void)initiator_cred_handle;
88: (void)mech_type;
89: (void)time_req;
90: (void)input_chan_bindings;
91: (void)actual_mech_type;
92:
93: if(!min)
94: return GSS_S_FAILURE;
95:
96: *min = 0;
97:
98: if(!context_handle || !target_name || !output_token) {
99: *min = GSS_INVALID_ARGS;
100: return GSS_S_FAILURE;
101: }
102:
103: creds = getenv("CURL_STUB_GSS_CREDS");
104: if(!creds || strlen(creds) >= MAX_CREDS_LENGTH) {
105: *min = GSS_INVALID_CREDS;
106: return GSS_S_FAILURE;
107: }
108:
109: ctx = *context_handle;
110: if(ctx && strcmp(ctx->creds, creds)) {
111: *min = GSS_INVALID_CREDS;
112: return GSS_S_FAILURE;
113: }
114:
115: output_token->length = 0;
116: output_token->value = NULL;
117:
118: if(input_token && input_token->length) {
119: if(!ctx) {
120: *min = GSS_INVALID_CTX;
121: return GSS_S_FAILURE;
122: }
123:
124: /* Server response, either D (RA==) or C (Qw==) */
125: if(((char *) input_token->value)[0] == 'D') {
126: /* Done */
127: switch(ctx->sent) {
128: case KRB5:
129: case NTLM3:
130: if(ret_flags)
131: *ret_flags = ctx->flags;
132: if(time_rec)
133: *time_rec = GSS_C_INDEFINITE;
134: return GSS_S_COMPLETE;
135: default:
136: *min = GSS_SERVER_ERR;
137: return GSS_S_FAILURE;
138: }
139: }
140:
141: if(((char *) input_token->value)[0] != 'C') {
142: /* We only support Done or Continue */
143: *min = GSS_SERVER_ERR;
144: return GSS_S_FAILURE;
145: }
146:
147: /* Continue */
148: switch(ctx->sent) {
149: case KRB5:
150: /* We sent KRB5 and it failed, let's try NTLM */
151: if(ctx->have_ntlm) {
152: ctx->sent = NTLM1;
153: break;
154: }
155: else {
156: *min = GSS_SERVER_ERR;
157: return GSS_S_FAILURE;
158: }
159: case NTLM1:
160: ctx->sent = NTLM3;
161: break;
162: default:
163: *min = GSS_SERVER_ERR;
164: return GSS_S_FAILURE;
165: }
166: }
167: else {
168: if(ctx) {
169: *min = GSS_INVALID_CTX;
170: return GSS_S_FAILURE;
171: }
172:
173: ctx = (gss_ctx_id_t) calloc(sizeof(*ctx), 1);
174: if(!ctx) {
175: *min = GSS_NO_MEMORY;
176: return GSS_S_FAILURE;
177: }
178:
179: if(strstr(creds, "KRB5"))
180: ctx->have_krb5 = 1;
181:
182: if(strstr(creds, "NTLM"))
183: ctx->have_ntlm = 1;
184:
185: if(ctx->have_krb5)
186: ctx->sent = KRB5;
187: else if(ctx->have_ntlm)
188: ctx->sent = NTLM1;
189: else {
190: free(ctx);
191: *min = GSS_NO_MECH;
192: return GSS_S_FAILURE;
193: }
194:
195: strcpy(ctx->creds, creds);
196: ctx->flags = req_flags;
197: }
198:
199: token = malloc(length);
200: if(!token) {
201: free(ctx);
202: *min = GSS_NO_MEMORY;
203: return GSS_S_FAILURE;
204: }
205:
206: /* Token format: creds:target:type:padding */
207: /* Note: this is using the *real* snprintf() and not the curl provided
208: one */
209: used = snprintf(token, length, "%s:%s:%d:", creds,
210: (char *) target_name, ctx->sent);
211:
212: if(used >= length) {
213: free(token);
214: free(ctx);
215: *min = GSS_NO_MEMORY;
216: return GSS_S_FAILURE;
217: }
218:
219: /* Overwrite null terminator */
220: memset(token + used, 'A', length - used);
221:
222: *context_handle = ctx;
223:
224: output_token->value = token;
225: output_token->length = length;
226:
227: return GSS_S_CONTINUE_NEEDED;
228: }
229:
230: OM_uint32 gss_delete_sec_context(OM_uint32 *min,
231: gss_ctx_id_t *context_handle,
232: gss_buffer_t output_token)
233: {
234: (void)output_token;
235:
236: if(!min)
237: return GSS_S_FAILURE;
238:
239: if(!context_handle) {
240: *min = GSS_INVALID_CTX;
241: return GSS_S_FAILURE;
242: }
243:
244: free(*context_handle);
245: *context_handle = NULL;
246: *min = 0;
247:
248: return GSS_S_COMPLETE;
249: }
250:
251: OM_uint32 gss_release_buffer(OM_uint32 *min,
252: gss_buffer_t buffer)
253: {
254: if(min)
255: *min = 0;
256:
257: if(buffer && buffer->length) {
258: free(buffer->value);
259: buffer->length = 0;
260: }
261:
262: return GSS_S_COMPLETE;
263: }
264:
265: OM_uint32 gss_import_name(OM_uint32 *min,
266: const gss_buffer_t input_name_buffer,
267: const gss_OID input_name_type,
268: gss_name_t *output_name)
269: {
270: char *name = NULL;
271: (void)input_name_type;
272:
273: if(!min)
274: return GSS_S_FAILURE;
275:
276: if(!input_name_buffer || !output_name) {
277: *min = GSS_INVALID_ARGS;
278: return GSS_S_FAILURE;
279: }
280:
281: name = strndup(input_name_buffer->value, input_name_buffer->length);
282: if(!name) {
283: *min = GSS_NO_MEMORY;
284: return GSS_S_FAILURE;
285: }
286:
287: *output_name = (gss_name_t) name;
288: *min = 0;
289:
290: return GSS_S_COMPLETE;
291: }
292:
293: OM_uint32 gss_release_name(OM_uint32 *min,
294: gss_name_t *input_name)
295: {
296: if(min)
297: *min = 0;
298:
299: if(input_name)
300: free(*input_name);
301:
302: return GSS_S_COMPLETE;
303: }
304:
305: OM_uint32 gss_display_status(OM_uint32 *min,
306: OM_uint32 status_value,
307: int status_type,
308: const gss_OID mech_type,
309: OM_uint32 *message_context,
310: gss_buffer_t status_string)
311: {
312: const char maj_str[] = "Stub GSS error";
313: (void)mech_type;
314: if(min)
315: *min = 0;
316:
317: if(message_context)
318: *message_context = 0;
319:
320: if(status_string) {
321: status_string->value = NULL;
322: status_string->length = 0;
323:
324: if(status_value >= GSS_LAST)
325: return GSS_S_FAILURE;
326:
327: switch(status_type) {
328: case GSS_C_GSS_CODE:
329: status_string->value = strdup(maj_str);
330: break;
331: case GSS_C_MECH_CODE:
332: status_string->value = strdup(min_err_table[status_value]);
333: break;
334: default:
335: return GSS_S_FAILURE;
336: }
337:
338: if(status_string->value)
339: status_string->length = strlen(status_string->value);
340: else
341: return GSS_S_FAILURE;
342: }
343:
344: return GSS_S_COMPLETE;
345: }
346:
347: /* Stubs returning error */
348:
349: OM_uint32 gss_display_name(OM_uint32 *min,
350: gss_const_name_t input_name,
351: gss_buffer_t output_name_buffer,
352: gss_OID *output_name_type)
353: {
354: (void)min;
355: (void)input_name;
356: (void)output_name_buffer;
357: (void)output_name_type;
358: return GSS_S_FAILURE;
359: }
360:
361: OM_uint32 gss_inquire_context(OM_uint32 *min,
362: gss_const_ctx_id_t context_handle,
363: gss_name_t *src_name,
364: gss_name_t *targ_name,
365: OM_uint32 *lifetime_rec,
366: gss_OID *mech_type,
367: OM_uint32 *ctx_flags,
368: int *locally_initiated,
369: int *open_context)
370: {
371: (void)min;
372: (void)context_handle;
373: (void)src_name;
374: (void)targ_name;
375: (void)lifetime_rec;
376: (void)mech_type;
377: (void)ctx_flags;
378: (void)locally_initiated;
379: (void)open_context;
380: return GSS_S_FAILURE;
381: }
382:
383: OM_uint32 gss_wrap(OM_uint32 *min,
384: gss_const_ctx_id_t context_handle,
385: int conf_req_flag,
386: gss_qop_t qop_req,
387: const gss_buffer_t input_message_buffer,
388: int *conf_state,
389: gss_buffer_t output_message_buffer)
390: {
391: (void)min;
392: (void)context_handle;
393: (void)conf_req_flag;
394: (void)qop_req;
395: (void)input_message_buffer;
396: (void)conf_state;
397: (void)output_message_buffer;
398: return GSS_S_FAILURE;
399: }
400:
401: OM_uint32 gss_unwrap(OM_uint32 *min,
402: gss_const_ctx_id_t context_handle,
403: const gss_buffer_t input_message_buffer,
404: gss_buffer_t output_message_buffer,
405: int *conf_state,
406: gss_qop_t *qop_state)
407: {
408: (void)min;
409: (void)context_handle;
410: (void)input_message_buffer;
411: (void)output_message_buffer;
412: (void)conf_state;
413: (void)qop_state;
414: return GSS_S_FAILURE;
415: }
416:
417: OM_uint32 gss_seal(OM_uint32 *min,
418: gss_ctx_id_t context_handle,
419: int conf_req_flag,
420: int qop_req,
421: gss_buffer_t input_message_buffer,
422: int *conf_state,
423: gss_buffer_t output_message_buffer)
424: {
425: (void)min;
426: (void)context_handle;
427: (void)conf_req_flag;
428: (void)qop_req;
429: (void)input_message_buffer;
430: (void)conf_state;
431: (void)output_message_buffer;
432: return GSS_S_FAILURE;
433: }
434:
435: OM_uint32 gss_unseal(OM_uint32 *min,
436: gss_ctx_id_t context_handle,
437: gss_buffer_t input_message_buffer,
438: gss_buffer_t output_message_buffer,
439: int *conf_state,
440: int *qop_state)
441: {
442: (void)min;
443: (void)context_handle;
444: (void)input_message_buffer;
445: (void)output_message_buffer;
446: (void)conf_state;
447: (void)qop_state;
448: return GSS_S_FAILURE;
449: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>