1   /*
   2    * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
   3    * Use is subject to license terms.
   4    */
   5   
   6 | #pragma ident        "@(#)g_imp_sec_context.c        1.19        04/09/08 SMI"
   6 | #pragma ident        "@(#)g_imp_sec_context.c        1.18        04/02/23 SMI"
   7   
   8   /*
   9    *  glue routine gss_export_sec_context
  10    */
  11   
  12   #include <mechglueP.h>
  13   #include <stdio.h>
  14   #include <errno.h>
  15   #include <stdlib.h>
  16   #include <string.h>
  17   
  18   OM_uint32
  19   gss_import_sec_context(minor_status,
  20                           interprocess_token,
  21                           context_handle)
  22   
  23   OM_uint32 *                minor_status;
  24   const gss_buffer_t        interprocess_token;
  25   gss_ctx_id_t                 *context_handle;
  26   
  27   {
  28 |         OM_uint32                length;
  28 |         OM_uint32                length = 0;
  29           OM_uint32                status;
  30           char                        *p;
  31           gss_union_ctx_id_t        ctx;
  32           gss_buffer_desc                token;
  33           gss_mechanism                mech;
  34   
  35 |         gss_initialize();
  36 | 
  35 |         if (minor_status == NULL)
  36 |                 return (GSS_S_CALL_INACCESSIBLE_WRITE);
  37           *minor_status = 0;
  38   
  39 |         if (interprocess_token->length == 0 || interprocess_token->value == 0)
  40 |                 return (GSS_S_DEFECTIVE_TOKEN);
  39 |         if (context_handle == NULL)
  40 |                 return (GSS_S_CALL_INACCESSIBLE_WRITE | GSS_S_NO_CONTEXT);
  41 +         *context_handle = GSS_C_NO_CONTEXT;
  42   
  43 +         if (GSS_EMPTY_BUFFER(interprocess_token))
  44 +                 return (GSS_S_CALL_INACCESSIBLE_READ | GSS_S_DEFECTIVE_TOKEN);
  45 + 
  46           status = GSS_S_FAILURE;
  47   
  48           ctx = (gss_union_ctx_id_t)malloc(sizeof (gss_union_ctx_id_desc));
  45 |         if (!ctx) {
  49 |         if (!ctx)
  46 -                 *minor_status = ENOMEM;
  50                   return (GSS_S_FAILURE);
  48 |         }
  51 | 
  52           ctx->mech_type = (gss_OID) malloc(sizeof (gss_OID_desc));
  53           if (!ctx->mech_type) {
  51 |                 *minor_status = ENOMEM;
  52 |                 goto error_out;
  54 |                 free(ctx);
  55 |                 return (GSS_S_FAILURE);
  56           }
  57 + 
  58 +         if (interprocess_token->length >= sizeof (OM_uint32)) {
  59                   p = interprocess_token->value;
  60                   length = (OM_uint32)*p++;
  61                   length = (OM_uint32)(length << 8) + *p++;
  62                   length = (OM_uint32)(length << 8) + *p++;
  63                   length = (OM_uint32)(length << 8) + *p++;
  64 +         }
  65   
  66 +         if (length == 0 ||
  67 +             length > (interprocess_token->length - sizeof (OM_uint32))) {
  68 +                 free(ctx);
  69 +                 return (GSS_S_CALL_BAD_STRUCTURE | GSS_S_DEFECTIVE_TOKEN);
  70 +         }
  71 + 
  72           ctx->mech_type->length = length;
  73           ctx->mech_type->elements = malloc(length);
  63 -                 *minor_status = ENOMEM;
  74           if (!ctx->mech_type->elements) {
  75                   goto error_out;
  76           }
  77           (void) memcpy(ctx->mech_type->elements, p, length);
  78           p += length;
  79   
  69 |         token.length = interprocess_token->length - 4 - length;
  80 |         token.length = interprocess_token->length - sizeof (OM_uint32) - length;
  81           token.value = p;
  82   
  83           /*
  84            * select the approprate underlying mechanism routine and
  85            * call it.
  86            */
  87   
  88           mech = __gss_get_mechanism(ctx->mech_type);
  89           if (!mech) {
  90                   status = GSS_S_BAD_MECH;
  91                   goto error_out;
  92           }
  93           if (!mech->gss_import_sec_context) {
  83 |                 status = GSS_S_BAD_BINDINGS;
  94 |                 status = GSS_S_UNAVAILABLE;
  95                   goto error_out;
  96           }
  97   
  98           status = mech->gss_import_sec_context(mech->context, minor_status,
  99                                           &token, &ctx->internal_ctx_id);
 100   
 101           if (status == GSS_S_COMPLETE) {
 102                   *context_handle = (gss_ctx_id_t)ctx;
 103                   return (GSS_S_COMPLETE);
 104           }
 105   
 106   error_out:
 107           if (ctx) {
 108                   if (ctx->mech_type) {
 109                           if (ctx->mech_type->elements)
 110                                   free(ctx->mech_type->elements);
 111                           free(ctx->mech_type);
 112                   }
 113                   free(ctx);
 114           }
 115           return (status);
 116   }

 ----Unchanged portion omitted----