diff options
Diffstat (limited to 'src/lib/gssapi/krb5/util_ctxsetup.c')
-rw-r--r-- | src/lib/gssapi/krb5/util_ctxsetup.c | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/src/lib/gssapi/krb5/util_ctxsetup.c b/src/lib/gssapi/krb5/util_ctxsetup.c new file mode 100644 index 000000000..0add6bf73 --- /dev/null +++ b/src/lib/gssapi/krb5/util_ctxsetup.c @@ -0,0 +1,208 @@ +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#include "gssapiP_krb5.h" + +/* from the token, flags is stored directly. nctypes/ctypes is + allocated and returns the length and list of ctypes in the token. + noptions/options lists all the options which the caller cares + about. Those which are present in the token are filled in; the + order and length are not changed. If an error is returned, the + option list is in an indeterminate state. */ + +OM_uint32 +kg2_parse_token(minor_status, ptr, token_length, flags, nctypes, ctypes, + noptions, options, kmsg, mic) + OM_uint32 *minor_status; + unsigned char *ptr; + int token_length; + krb5_ui_4 *flags; + int *nctypes; /* OUT */ + krb5_cksumtype **ctypes; /* OUT */ + int noptions; + struct kg2_option *options; /* INOUT */ + krb5_data *kmsg; + krb5_data *mic; +{ + int field_length, i; + int opt_id; + + *ctypes = 0; + + /* read the flags */ + + if (token_length < 4) + goto defective; + *flags = (ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]; + ptr += 4; + token_length -= 4; + + /* read out the token list */ + + if (token_length < 2) + goto defective; + field_length = (ptr[0]<<8) | ptr[1]; + ptr += 2; + token_length -= 2; + + *nctypes = field_length; + + if (*nctypes == 0) { + *minor_status = 0; + return(GSS_S_DEFECTIVE_TOKEN); + } + + if ((*ctypes = (krb5_cksumtype *) + malloc((*nctypes) * sizeof(krb5_cksumtype))) == NULL) { + *minor_status = ENOMEM; + return(GSS_S_FAILURE); + } + + for (i=0; i<field_length; i++) { + if (token_length < 4) + goto defective; + + (*ctypes)[i] = (krb5_cksumtype) ((ptr[0]<<24) | (ptr[1]<<16) | + (ptr[2]<<8) | ptr[3]); + ptr += 4; + token_length -= 4; + } + + do { + if (token_length < 4) + goto defective; + opt_id = (ptr[0]<<8) | ptr[1]; + field_length = (ptr[2]<<8) | ptr[3]; + ptr += 4; + token_length -= 4; + + if (token_length < field_length) + goto defective; + + for (i=0; i<noptions; i++) { + if (options[i].option_id = opt_id) { + options[i].length = field_length; + options[i].data = ptr; + } + break; + } + + ptr += field_length; + token_length -= field_length; + } while (opt_id); + + if (token_length < 2) + goto defective; + field_length = (ptr[0]<<8) | ptr[1]; + ptr += 2; + token_length -= 2; + + if (token_length < field_length) + goto defective; + + kmsg->length = field_length; + kmsg->data = ptr; + + ptr += field_length; + token_length -= field_length; + + /* if there's anything left, assume it's a mic. the mic isn't + necessarily present */ + + if (mic && token_length) { + if (token_length < 2) + goto defective; + field_length = (ptr[0]<<8) | ptr[1]; + ptr += 2; + token_length -= 2; + + if (token_length < field_length) + goto defective; + + mic->length = field_length; + mic->data = ptr; + + ptr += field_length; + token_length -= field_length; + } else if (mic) { + mic->length = 0; + mic->data = ptr; + } + + if (token_length) + goto defective; + + return(GSS_S_COMPLETE); + +defective: + if (*ctypes) + free(*ctypes); + + *minor_status = 0; + return(GSS_S_DEFECTIVE_TOKEN); +} + +/* nc1/c1 will be modified to contain the intersection of the + two lists. */ + +void +kg2_intersect_ctypes(nc1, c1, nc2, c2) + int *nc1; + krb5_cksumtype *c1; + int nc2; + const krb5_cksumtype *c2; +{ + int i, j, count; + krb5_cksumtype tmp; + + count = 0; + + for (i=0; i<*nc1; i++) { + /* first, check to make sure that c1[i] isn't a duplicate in c1 */ + for (j=0; j<i; j++) + if (c1[i] == c1[j]) + break; + if (j<i) + continue; + /* check if c1[i] is in c2. If it is, keep it by swapping + it into c1[count] and incrementing count. If count < i, then + that field has already been looked at and skipped as + not intersecting, which is ok. */ + + for (j=0; j<nc2; j++) + if (c1[i] == c2[j]) + break; + if ((j<nc2) && (count != i)) { + tmp = c1[count]; + c1[count] = c1[i]; + c1[i] = tmp; + } + count++; + } + + *nc1 = count; +} + |