Annotation of embedaddon/curl/tests/libtest/stub_gssapi.c, revision 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>