+Thu Feb 29 11:32:16 1996 Theodore Y. Ts'o <tytso@dcl>
+
+ * g_glue.c (__gss_get_mech_type): Fix code to properly parse token
+ headers. It was working only by serendipity....
+
+ * g_accept_sec_context.c (gss_accept_sec_context): Add error
+ checking and memory cleanup. Make gss_accept_sec_context
+ work for mechanisms that use multiple token roundtrips.
+
Wed Feb 28 20:33:47 1996 Theodore Y. Ts'o <tytso@dcl>
* mglueP.h: For MS-DOS, add #include of malloc.h
#include <stdlib.h>
#endif
#include <string.h>
+#include <errno.h>
OM_uint32 INTERFACE
gss_accept_sec_context (minor_status,
gss_OID_desc token_mech_type_desc;
gss_OID token_mech_type = &token_mech_type_desc;
gss_mechanism mech;
- int i;
gss_initialize();
*/
if(*context_handle == GSS_C_NO_CONTEXT) {
+
+ /* Get the token mech type */
+ status = __gss_get_mech_type(token_mech_type, input_token_buffer);
+ if (status)
+ return status;
+ status = GSS_S_FAILURE;
union_ctx_id = (gss_union_ctx_id_t)
malloc(sizeof(gss_union_ctx_id_desc));
-
- union_ctx_id->mech_type = (gss_OID)
- malloc(sizeof(gss_OID_desc));
-
- /*
- * get the token mech type, create the context id mech type space
- * and copy in the OID
- */
-
- __gss_get_mech_type(&token_mech_type, input_token_buffer);
-
+ if (!union_ctx_id) {
+ *minor_status = ENOMEM;
+ goto error_out;
+ }
+
+ union_ctx_id->mech_type = (gss_OID) malloc(sizeof(gss_OID_desc));
+ if (!union_ctx_id->mech_type) {
+ *minor_status = ENOMEM;
+ goto error_out;
+ }
+
union_ctx_id->mech_type->elements = (void *)
malloc(token_mech_type->length);
+ if (!union_ctx_id->mech_type->elements) {
+ *minor_status = ENOMEM;
+ goto error_out;
+ }
union_ctx_id->mech_type->length = token_mech_type->length;
memcpy(union_ctx_id->mech_type->elements,
/* copy the supplied context handle */
union_ctx_id->internal_ctx_id = *context_handle;
- } else
+ } else {
union_ctx_id = *context_handle;
+ token_mech_type = union_ctx_id->mech_type;
+ }
/*
* get the appropriate cred handle from the union cred struct.
time_rec,
delegated_cred_handle);
+ /* If there's more work to do, keep going... */
+ if (status == GSS_S_CONTINUE_NEEDED)
+ return GSS_S_CONTINUE_NEEDED;
+
/* if the call failed, return with failure */
-
- if(status != GSS_S_COMPLETE
- &&
- status != GSS_S_CONTINUE_NEEDED)
- return(status);
+ if (status != GSS_S_COMPLETE)
+ goto error_out;
/*
* if src_name is non-NULL,
}
return(GSS_S_BAD_MECH);
+
+error_out:
+ if (union_ctx_id) {
+ if (union_ctx_id->mech_type) {
+ if (union_ctx_id->mech_type->elements)
+ free(union_ctx_id->mech_type->elements);
+ free(union_ctx_id->mech_type);
+ }
+ free(union_ctx_id);
+ }
+ return (status);
}
*/
OM_uint32 __gss_get_mech_type(OID, token)
-
-gss_OID * OID;
-gss_buffer_t token;
-
+ gss_OID OID;
+ gss_buffer_t token;
{
unsigned char * buffer_ptr;
+ int length;
/*
* This routine reads the prefix of "token" in order to determine
* <length> - assume only one byte, hence OID length < 127
* <mech OID bytes>
*
- * The routine returns a pointer to the OID value. The return code is
- * the length of the OID, if successful; otherwise it is 0.
+ * The routine fills in the OID value and returns an error as necessary.
*/
- if (OID == NULL || *OID == GSS_C_NULL_OID)
- return (0);
-
- /* if the token is a null pointer, return a zero length OID */
-
- if(token == NULL) {
- (*OID)->length = 0;
- (*OID)->elements = NULL;
- return (0);
- }
+ if (token == NULL)
+ return (GSS_S_DEFECTIVE_TOKEN);
/* Skip past the APP/Sequnce byte and the token length */
buffer_ptr = (unsigned char *) token->value;
+
+ if (*(buffer_ptr++) != 0x60)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ length = *buffer_ptr++;
+ if (length & 0x80) {
+ if ((length & 0x7f) > 4)
+ return (GSS_S_DEFECTIVE_TOKEN);
+ buffer_ptr += length & 0x7f;
+ }
- while(*(++buffer_ptr) & (1<<7))
- continue;
-
- /* increment buffer_ptr to point to the OID and return its length */
+ if (*(buffer_ptr++) != 0x06)
+ return (GSS_S_DEFECTIVE_TOKEN);
- (*OID)->length = (OM_uint32) *(buffer_ptr+3);
- (*OID)->elements = (void *) (buffer_ptr+4);
- return ((*OID)->length);
+ OID->length = (OM_uint32) *(buffer_ptr++);
+ OID->elements = (void *) buffer_ptr;
+ return (GSS_S_COMPLETE);
}
gss_mechanism __gss_get_mechanism
PROTOTYPE((gss_OID));
OM_uint32 __gss_get_mech_type
-PROTOTYPE((gss_OID *, gss_buffer_t));
+PROTOTYPE((gss_OID, gss_buffer_t));
OM_uint32 __gss_import_internal_name
PROTOTYPE((OM_uint32 *, gss_OID, gss_union_name_t,
gss_name_t *));