1 #pragma ident "%Z%%M% %I% %E% SMI" 2 3 /* 4 * Copyright (C) 1998 by the FundsXpress, INC. 5 * 6 * All rights reserved. 7 * 8 * Export of this software from the United States of America may require 9 * a specific license from the United States Government. It is the 10 * responsibility of any person or organization contemplating export to 11 * obtain such a license before exporting. 12 * 13 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 14 * distribute this software and its documentation for any purpose and 15 * without fee is hereby granted, provided that the above copyright 16 * notice appear in all copies and that both that copyright notice and 17 * this permission notice appear in supporting documentation, and that 18 * the name of FundsXpress. not be used in advertising or publicity pertaining 19 * to distribution of the software without specific, written prior 20 * permission. FundsXpress makes no representations about the suitability of 21 * this software for any purpose. It is provided "as is" without express 22 * or implied warranty. 23 * 24 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 25 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 26 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 27 */ 28 29 #include <gssapiP_krb5.h> 30 31 /* from the token, flags is stored directly. nctypes/ctypes is 32 allocated and returns the length and list of ctypes in the token. 33 noptions/options lists all the options which the caller cares 34 about. Those which are present in the token are filled in; the 35 order and length are not changed. If an error is returned, the 36 option list is in an indeterminate state. */ 37 38 OM_uint32 39 kg2_parse_token(minor_status, ptr, token_length, flags, nctypes, ctypes, 40 noptions, options, kmsg, mic) 41 OM_uint32 *minor_status; 42 unsigned char *ptr; 43 int token_length; 44 krb5_ui_4 *flags; 45 int *nctypes; /* OUT */ 46 krb5_cksumtype **ctypes; /* OUT */ 47 int noptions; 48 struct kg2_option *options; /* INOUT */ 49 krb5_data *kmsg; 50 krb5_data *mic; 51 { 52 int field_length, i; 53 int opt_id; 54 55 *ctypes = 0; 56 57 /* read the flags */ 58 59 if (token_length < 4) 60 goto defective; 61 *flags = (ptr[0]<<24) | (ptr[1]<<16) | (ptr[2]<<8) | ptr[3]; 62 ptr += 4; 63 token_length -= 4; 64 65 /* read out the token list */ 66 67 if (token_length < 2) 68 goto defective; 69 field_length = (ptr[0]<<8) | ptr[1]; 70 ptr += 2; 71 token_length -= 2; 72 73 *nctypes = field_length; 74 75 if (*nctypes == 0) { 76 *minor_status = 0; 77 return(GSS_S_DEFECTIVE_TOKEN); 78 } 79 80 if ((*ctypes = (krb5_cksumtype *) 81 malloc((*nctypes) * sizeof(krb5_cksumtype))) == NULL) { 82 *minor_status = ENOMEM; 83 return(GSS_S_FAILURE); 84 } 85 86 for (i=0; i<field_length; i++) { 87 if (token_length < 4) 88 goto defective; 89 90 (*ctypes)[i] = (krb5_cksumtype) ((ptr[0]<<24) | (ptr[1]<<16) | 91 (ptr[2]<<8) | ptr[3]); 92 ptr += 4; 93 token_length -= 4; 94 } 95 96 do { 97 if (token_length < 4) 98 goto defective; 99 opt_id = (ptr[0]<<8) | ptr[1]; 100 field_length = (ptr[2]<<8) | ptr[3]; 101 ptr += 4; 102 token_length -= 4; 103 104 if (token_length < field_length) 105 goto defective; 106 107 for (i=0; i<noptions; i++) { 108 if (options[i].option_id = opt_id) { 109 options[i].length = field_length; 110 options[i].data = ptr; 111 break; 112 } 113 } 114 115 ptr += field_length; 116 token_length -= field_length; 117 } while (opt_id); 118 119 if (token_length < 2) 120 goto defective; 121 field_length = (ptr[0]<<8) | ptr[1]; 122 ptr += 2; 123 token_length -= 2; 124 125 if (token_length < field_length) 126 goto defective; 127 128 kmsg->length = field_length; 129 kmsg->data = (char *) ptr; 130 131 ptr += field_length; 132 token_length -= field_length; 133 134 /* if there's anything left, assume it's a mic. the mic isn't 135 necessarily present */ 136 137 if (mic && token_length) { 138 if (token_length < 2) 139 goto defective; 140 field_length = (ptr[0]<<8) | ptr[1]; 141 ptr += 2; 142 token_length -= 2; 143 144 if (token_length < field_length) 145 goto defective; 146 147 mic->length = field_length; 148 mic->data = (char *) ptr; 149 150 ptr += field_length; 151 token_length -= field_length; 152 } else if (mic) { 153 mic->length = 0; 154 mic->data = (char *) ptr; 155 } 156 157 if (token_length) 158 goto defective; 159 160 return(GSS_S_COMPLETE); 161 162 defective: 163 if (*ctypes) 164 free(*ctypes); 165 166 *minor_status = 0; 167 return(GSS_S_DEFECTIVE_TOKEN); 168 } 169 170 /* nc1/c1 will be modified to contain the intersection of the 171 two lists. */ 172 173 void 174 kg2_intersect_ctypes(nc1, c1, nc2, c2) 175 int *nc1; 176 krb5_cksumtype *c1; 177 int nc2; 178 const krb5_cksumtype *c2; 179 { 180 int i, j, count; 181 krb5_cksumtype tmp; 182 183 count = 0; 184 185 for (i=0; i<*nc1; i++) { 186 /* first, check to make sure that c1[i] isn't a duplicate in c1 */ 187 for (j=0; j<i; j++) 188 if (c1[i] == c1[j]) 189 break; 190 if (j<i) 191 continue; 192 /* check if c1[i] is in c2. If it is, keep it by swapping 193 it into c1[count] and incrementing count. If count < i, then 194 that field has already been looked at and skipped as 195 not intersecting, which is ok. */ 196 197 for (j=0; j<nc2; j++) 198 if (c1[i] == c2[j]) 199 break; 200 if ((j<nc2) && (count != i)) { 201 tmp = c1[count]; 202 c1[count] = c1[i]; 203 c1[i] = tmp; 204 } 205 count++; 206 } 207 208 *nc1 = count; 209 } 210 211