stub_gssapi.c
Go to the documentation of this file.
1 /***************************************************************************
2  * _ _ ____ _
3  * Project ___| | | | _ \| |
4  * / __| | | | |_) | |
5  * | (__| |_| | _ <| |___
6  * \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 2017, 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 #define MAX_CREDS_LENGTH 250
32 #define APPROX_TOKEN_LEN 250
33 
35  GSS_OK = 0,
43 };
44 
45 const char *min_err_table[] = {
46  "stub-gss: no error",
47  "stub-gss: no memory",
48  "stub-gss: invalid arguments",
49  "stub-gss: invalid credentials",
50  "stub-gss: invalid context",
51  "stub-gss: server returned error",
52  "stub-gss: cannot find a mechanism",
53  NULL
54 };
55 
57  enum { NONE, KRB5, NTLM1, NTLM3 } sent;
58  int have_krb5;
59  int have_ntlm;
62 };
63 
65  gss_const_cred_id_t initiator_cred_handle,
66  gss_ctx_id_t *context_handle,
67  gss_const_name_t target_name,
68  const gss_OID mech_type,
69  OM_uint32 req_flags,
70  OM_uint32 time_req,
71  const gss_channel_bindings_t input_chan_bindings,
72  const gss_buffer_t input_token,
73  gss_OID *actual_mech_type,
74  gss_buffer_t output_token,
75  OM_uint32 *ret_flags,
76  OM_uint32 *time_rec)
77 {
78  /* The token will be encoded in base64 */
79  int length = APPROX_TOKEN_LEN * 3 / 4;
80  int used = 0;
81  char *token = NULL;
82  const char *creds = NULL;
83  gss_ctx_id_t ctx = NULL;
84 
85  if(!min)
86  return GSS_S_FAILURE;
87 
88  *min = 0;
89 
90  if(!context_handle || !target_name || !output_token) {
91  *min = GSS_INVALID_ARGS;
92  return GSS_S_FAILURE;
93  }
94 
95  creds = getenv("CURL_STUB_GSS_CREDS");
96  if(!creds || strlen(creds) >= MAX_CREDS_LENGTH) {
97  *min = GSS_INVALID_CREDS;
98  return GSS_S_FAILURE;
99  }
100 
101  ctx = *context_handle;
102  if(ctx && strcmp(ctx->creds, creds)) {
103  *min = GSS_INVALID_CREDS;
104  return GSS_S_FAILURE;
105  }
106 
107  output_token->length = 0;
108  output_token->value = NULL;
109 
110  if(input_token && input_token->length) {
111  if(!ctx) {
112  *min = GSS_INVALID_CTX;
113  return GSS_S_FAILURE;
114  }
115 
116  /* Server response, either D (RA==) or C (Qw==) */
117  if(((char *) input_token->value)[0] == 'D') {
118  /* Done */
119  switch(ctx->sent) {
120  case KRB5:
121  case NTLM3:
122  if(ret_flags)
123  *ret_flags = ctx->flags;
124  if(time_rec)
125  *time_rec = GSS_C_INDEFINITE;
126  return GSS_S_COMPLETE;
127  default:
128  *min = GSS_SERVER_ERR;
129  return GSS_S_FAILURE;
130  }
131  }
132 
133  if(((char *) input_token->value)[0] != 'C') {
134  /* We only support Done or Continue */
135  *min = GSS_SERVER_ERR;
136  return GSS_S_FAILURE;
137  }
138 
139  /* Continue */
140  switch(ctx->sent) {
141  case KRB5:
142  /* We sent KRB5 and it failed, let's try NTLM */
143  if(ctx->have_ntlm) {
144  ctx->sent = NTLM1;
145  break;
146  }
147  else {
148  *min = GSS_SERVER_ERR;
149  return GSS_S_FAILURE;
150  }
151  case NTLM1:
152  ctx->sent = NTLM3;
153  break;
154  default:
155  *min = GSS_SERVER_ERR;
156  return GSS_S_FAILURE;
157  }
158  }
159  else {
160  if(ctx) {
161  *min = GSS_INVALID_CTX;
162  return GSS_S_FAILURE;
163  }
164 
165  ctx = (gss_ctx_id_t) calloc(sizeof(*ctx), 1);
166  if(!ctx) {
167  *min = GSS_NO_MEMORY;
168  return GSS_S_FAILURE;
169  }
170 
171  if(strstr(creds, "KRB5"))
172  ctx->have_krb5 = 1;
173 
174  if(strstr(creds, "NTLM"))
175  ctx->have_ntlm = 1;
176 
177  if(ctx->have_krb5)
178  ctx->sent = KRB5;
179  else if(ctx->have_ntlm)
180  ctx->sent = NTLM1;
181  else {
182  free(ctx);
183  *min = GSS_NO_MECH;
184  return GSS_S_FAILURE;
185  }
186 
187  strcpy(ctx->creds, creds);
188  ctx->flags = req_flags;
189  }
190 
191  token = malloc(length);
192  if(!token) {
193  free(ctx);
194  *min = GSS_NO_MEMORY;
195  return GSS_S_FAILURE;
196  }
197 
198  /* Token format: creds:target:type:padding */
199  used = snprintf(token, length, "%s:%s:%d:", creds,
200  (char *) target_name, ctx->sent);
201 
202  if(used >= length) {
203  free(token);
204  free(ctx);
205  *min = GSS_NO_MEMORY;
206  return GSS_S_FAILURE;
207  }
208 
209  /* Overwrite null terminator */
210  memset(token + used, 'A', length - used);
211 
212  *context_handle = ctx;
213 
214  output_token->value = token;
215  output_token->length = length;
216 
217  return GSS_S_CONTINUE_NEEDED;
218 }
219 
221  gss_ctx_id_t *context_handle,
222  gss_buffer_t output_token)
223 {
224  if(!min)
225  return GSS_S_FAILURE;
226 
227  if(!context_handle) {
228  *min = GSS_INVALID_CTX;
229  return GSS_S_FAILURE;
230  }
231 
232  free(*context_handle);
233  *context_handle = NULL;
234  *min = 0;
235 
236  return GSS_S_COMPLETE;
237 }
238 
241 {
242  if(min)
243  *min = 0;
244 
245  if(buffer && buffer->length) {
246  free(buffer->value);
247  buffer->length = 0;
248  }
249 
250  return GSS_S_COMPLETE;
251 }
252 
254  const gss_buffer_t input_name_buffer,
255  const gss_OID input_name_type,
256  gss_name_t *output_name)
257 {
258  char *name = NULL;
259 
260  if(!min)
261  return GSS_S_FAILURE;
262 
263  if(!input_name_buffer || !output_name) {
264  *min = GSS_INVALID_ARGS;
265  return GSS_S_FAILURE;
266  }
267 
268  name = strndup(input_name_buffer->value, input_name_buffer->length);
269  if(!name) {
270  *min = GSS_NO_MEMORY;
271  return GSS_S_FAILURE;
272  }
273 
274  *output_name = (gss_name_t) name;
275  *min = 0;
276 
277  return GSS_S_COMPLETE;
278 }
279 
281  gss_name_t *input_name)
282 {
283  if(min)
284  *min = 0;
285 
286  if(input_name)
287  free(*input_name);
288 
289  return GSS_S_COMPLETE;
290 }
291 
293  OM_uint32 status_value,
294  int status_type,
295  const gss_OID mech_type,
296  OM_uint32 *message_context,
297  gss_buffer_t status_string)
298 {
299  const char maj_str[] = "Stub GSS error";
300  if(min)
301  *min = 0;
302 
303  if(message_context)
304  *message_context = 0;
305 
306  if(status_string) {
307  status_string->value = NULL;
308  status_string->length = 0;
309 
310  if(status_value >= GSS_LAST)
311  return GSS_S_FAILURE;
312 
313  switch(status_type) {
314  case GSS_C_GSS_CODE:
315  status_string->value = strdup(maj_str);
316  break;
317  case GSS_C_MECH_CODE:
318  status_string->value = strdup(min_err_table[status_value]);
319  break;
320  default:
321  return GSS_S_FAILURE;
322  }
323 
324  if(status_string->value)
325  status_string->length = strlen(status_string->value);
326  else
327  return GSS_S_FAILURE;
328  }
329 
330  return GSS_S_COMPLETE;
331 }
332 
333 /* Stubs returning error */
334 
336  gss_const_name_t input_name,
337  gss_buffer_t output_name_buffer,
338  gss_OID *output_name_type)
339 {
340  return GSS_S_FAILURE;
341 }
342 
344  gss_const_ctx_id_t context_handle,
345  gss_name_t *src_name,
346  gss_name_t *targ_name,
347  OM_uint32 *lifetime_rec,
348  gss_OID *mech_type,
349  OM_uint32 *ctx_flags,
350  int *locally_initiated,
351  int *open_context)
352 {
353  return GSS_S_FAILURE;
354 }
355 
357  gss_const_ctx_id_t context_handle,
358  int conf_req_flag,
359  gss_qop_t qop_req,
360  const gss_buffer_t input_message_buffer,
361  int *conf_state,
362  gss_buffer_t output_message_buffer)
363 {
364  return GSS_S_FAILURE;
365 }
366 
368  gss_const_ctx_id_t context_handle,
369  const gss_buffer_t input_message_buffer,
370  gss_buffer_t output_message_buffer,
371  int *conf_state,
372  gss_qop_t *qop_state)
373 {
374  return GSS_S_FAILURE;
375 }
376 
378  gss_ctx_id_t context_handle,
379  int conf_req_flag,
380  int qop_req,
381  gss_buffer_t input_message_buffer,
382  int *conf_state,
383  gss_buffer_t output_message_buffer)
384 {
385  return GSS_S_FAILURE;
386 }
387 
389  gss_ctx_id_t context_handle,
390  gss_buffer_t input_message_buffer,
391  gss_buffer_t output_message_buffer,
392  int *conf_state,
393  int *qop_state)
394 {
395  return GSS_S_FAILURE;
396 }
397 
#define free(ptr)
Definition: curl_memory.h:130
#define GSS_S_FAILURE
Definition: stub_gssapi.h:33
OM_uint32 gss_release_buffer(OM_uint32 *min, gss_buffer_t buffer)
Definition: stub_gssapi.c:239
#define MAX_CREDS_LENGTH
Definition: stub_gssapi.c:31
#define getenv
Definition: setup-vms.h:52
#define GSS_S_CONTINUE_NEEDED
Definition: stub_gssapi.h:34
OM_uint32 gss_display_status(OM_uint32 *min, OM_uint32 status_value, int status_type, const gss_OID mech_type, OM_uint32 *message_context, gss_buffer_t status_string)
Definition: stub_gssapi.c:292
OM_uint32 gss_delete_sec_context(OM_uint32 *min, gss_ctx_id_t *context_handle, gss_buffer_t output_token)
Definition: stub_gssapi.c:220
OM_uint32 gss_qop_t
Definition: stub_gssapi.h:69
#define GSS_C_INDEFINITE
Definition: stub_gssapi.h:63
#define strdup(ptr)
Definition: curl_memory.h:122
char creds[MAX_CREDS_LENGTH]
Definition: stub_gssapi.c:61
OM_uint32 gss_display_name(OM_uint32 *min, gss_const_name_t input_name, gss_buffer_t output_name_buffer, gss_OID *output_name_type)
Definition: stub_gssapi.c:335
const struct gss_cred_id_t_desc_struct * gss_const_cred_id_t
Definition: stub_gssapi.h:78
#define malloc(size)
Definition: curl_memory.h:124
struct gss_name_t_desc_struct * gss_name_t
Definition: stub_gssapi.h:85
OM_uint32 gss_init_sec_context(OM_uint32 *min, gss_const_cred_id_t initiator_cred_handle, gss_ctx_id_t *context_handle, gss_const_name_t target_name, const gss_OID mech_type, OM_uint32 req_flags, OM_uint32 time_req, const gss_channel_bindings_t input_chan_bindings, const gss_buffer_t input_token, gss_OID *actual_mech_type, gss_buffer_t output_token, OM_uint32 *ret_flags, OM_uint32 *time_rec)
Definition: stub_gssapi.c:64
char buffer[]
Definition: unit1308.c:48
enum gss_ctx_id_t_desc_struct::@43 sent
min_err_code
Definition: stub_gssapi.c:34
OM_uint32 gss_import_name(OM_uint32 *min, const gss_buffer_t input_name_buffer, const gss_OID input_name_type, gss_name_t *output_name)
Definition: stub_gssapi.c:253
uint32_t OM_uint32
Definition: stub_gssapi.h:67
const char * min_err_table[]
Definition: stub_gssapi.c:45
OM_uint32 gss_release_name(OM_uint32 *min, gss_name_t *input_name)
Definition: stub_gssapi.c:280
OM_uint32 gss_unseal(OM_uint32 *min, gss_ctx_id_t context_handle, gss_buffer_t input_message_buffer, gss_buffer_t output_message_buffer, int *conf_state, int *qop_state)
Definition: stub_gssapi.c:388
OM_uint32 gss_unwrap(OM_uint32 *min, gss_const_ctx_id_t context_handle, const gss_buffer_t input_message_buffer, gss_buffer_t output_message_buffer, int *conf_state, gss_qop_t *qop_state)
Definition: stub_gssapi.c:367
OM_uint32 gss_inquire_context(OM_uint32 *min, gss_const_ctx_id_t context_handle, gss_name_t *src_name, gss_name_t *targ_name, OM_uint32 *lifetime_rec, gss_OID *mech_type, OM_uint32 *ctx_flags, int *locally_initiated, int *open_context)
Definition: stub_gssapi.c:343
#define APPROX_TOKEN_LEN
Definition: stub_gssapi.c:32
TFSIMD_FORCE_INLINE tfScalar length(const Quaternion &q)
#define GSS_C_MECH_CODE
Definition: stub_gssapi.h:51
OM_uint32 gss_seal(OM_uint32 *min, gss_ctx_id_t context_handle, int conf_req_flag, int qop_req, gss_buffer_t input_message_buffer, int *conf_state, gss_buffer_t output_message_buffer)
Definition: stub_gssapi.c:377
#define snprintf
Definition: curl_printf.h:42
const struct gss_name_t_desc_struct * gss_const_name_t
Definition: stub_gssapi.h:86
#define GSS_C_GSS_CODE
Definition: stub_gssapi.h:50
OM_uint32 gss_wrap(OM_uint32 *min, gss_const_ctx_id_t context_handle, int conf_req_flag, gss_qop_t qop_req, const gss_buffer_t input_message_buffer, int *conf_state, gss_buffer_t output_message_buffer)
Definition: stub_gssapi.c:356
const char * name
Definition: curl_sasl.c:54
struct gss_ctx_id_t_desc_struct * gss_ctx_id_t
Definition: stub_gssapi.h:81
#define calloc(nbelem, size)
Definition: curl_memory.h:126
#define GSS_S_COMPLETE
Definition: stub_gssapi.h:32


rc_tagdetect_client
Author(s): Monika Florek-Jasinska , Raphael Schaller
autogenerated on Sat Feb 13 2021 03:42:16