1 /* 2 * Copyright 2002 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 8 /* 9 * lib/krb5/ccache/ser_rc.c 10 * 11 * Copyright 1995 by the Massachusetts Institute of Technology. 12 * All Rights Reserved. 13 * 14 * Export of this software from the United States of America may 15 * require a specific license from the United States Government. 16 * It is the responsibility of any person or organization contemplating 17 * export to obtain such a license before exporting. 18 * 19 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 20 * distribute this software and its documentation for any purpose and 21 * without fee is hereby granted, provided that the above copyright 22 * notice appear in all copies and that both that copyright notice and 23 * this permission notice appear in supporting documentation, and that 24 * the name of M.I.T. not be used in advertising or publicity pertaining 25 * to distribution of the software without specific, written prior 26 * permission. Furthermore if you modify this software you must label 27 * your software as modified software and not distribute it in such a 28 * fashion that it might be confused with the original M.I.T. software. 29 * M.I.T. makes no representations about the suitability of 30 * this software for any purpose. It is provided "as is" without express 31 * or implied warranty. 32 * 33 */ 34 35 /* 36 * ser_rcdfl.c - Serialize replay cache context. 37 */ 38 #include <k5-int.h> 39 40 /* 41 * Routines to deal with externalizing krb5_ccache. 42 * krb5_ccache_size(); 43 * krb5_ccache_externalize(); 44 * krb5_ccache_internalize(); 45 */ 46 static krb5_error_code krb5_ccache_size 47 KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *)); 48 static krb5_error_code krb5_ccache_externalize 49 KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *)); 50 static krb5_error_code krb5_ccache_internalize 51 KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *)); 52 53 /* 54 * Serialization entry for this type. 55 */ 56 static const krb5_ser_entry krb5_ccache_ser_entry = { 57 KV5M_CCACHE, /* Type */ 58 krb5_ccache_size, /* Sizer routine */ 59 krb5_ccache_externalize, /* Externalize routine */ 60 krb5_ccache_internalize /* Internalize routine */ 61 }; 62 63 /* 64 * krb5_ccache_size() - Determine the size required to externalize 65 * this krb5_ccache variant. 66 */ 67 static krb5_error_code 68 krb5_ccache_size(kcontext, arg, sizep) 69 krb5_context kcontext; 70 krb5_pointer arg; 71 size_t *sizep; 72 { 73 krb5_error_code kret; 74 krb5_ccache ccache; 75 size_t required; 76 77 kret = EINVAL; 78 if ((ccache = (krb5_ccache) arg) != NULL) { 79 /* 80 * Saving FILE: variants of krb5_ccache requires at minimum: 81 * krb5_int32 for KV5M_CCACHE 82 * krb5_int32 for length of ccache name. 83 * krb5_int32 for KV5M_CCACHE 84 */ 85 required = sizeof(krb5_int32) * 3; 86 if (ccache->ops && ccache->ops->prefix) 87 required += (strlen(ccache->ops->prefix)+1); 88 89 /* 90 * The ccache name is formed as follows: 91 * <prefix>:<name> 92 */ 93 required += strlen(krb5_rc_get_name(kcontext, ccache)); 94 95 kret = 0; 96 *sizep += required; 97 } 98 return(kret); 99 } 100 101 /* 102 * krb5_ccache_externalize() - Externalize the krb5_ccache. 103 */ 104 static krb5_error_code 105 krb5_ccache_externalize(kcontext, arg, buffer, lenremain) 106 krb5_context kcontext; 107 krb5_pointer arg; 108 krb5_octet **buffer; 109 size_t *lenremain; 110 { 111 krb5_error_code kret; 112 krb5_ccache ccache; 113 size_t required; 114 krb5_octet *bp; 115 size_t remain; 116 char *ccname; 117 size_t namelen; 118 char *fnamep; 119 120 required = 0; 121 bp = *buffer; 122 remain = *lenremain; 123 kret = EINVAL; 124 if ((ccache = (krb5_ccache) arg) != NULL) { 125 kret = ENOMEM; 126 if (!krb5_ccache_size(kcontext, arg, &required) && 127 (required <= remain)) { 128 /* Our identifier */ 129 (void) krb5_ser_pack_int32(KV5M_CCACHE, &bp, &remain); 130 131 /* Calculate the length of the name */ 132 namelen = (ccache->ops && ccache->ops->prefix) ? 133 strlen(ccache->ops->prefix)+1 : 0; 134 fnamep = krb5_rc_get_name(kcontext, ccache); 135 namelen += (strlen(fnamep)+1); 136 137 if ((ccname = (char *) malloc(namelen))) { 138 /* Format the ccache name. */ 139 if (ccache->ops && ccache->ops->prefix) 140 sprintf(ccname, "%s:%s", ccache->ops->prefix, fnamep); 141 else 142 strcpy(ccname, fnamep); 143 144 /* Put the length of the file name */ 145 (void) krb5_ser_pack_int32((krb5_int32) strlen(ccname), 146 &bp, &remain); 147 148 /* Put the name */ 149 (void) krb5_ser_pack_bytes((krb5_octet *) ccname, 150 strlen(ccname), 151 &bp, &remain); 152 153 /* Put the trailer */ 154 (void) krb5_ser_pack_int32(KV5M_CCACHE, &bp, &remain); 155 kret = 0; 156 *buffer = bp; 157 *lenremain = remain; 158 free(ccname); 159 } 160 } 161 } 162 return(kret); 163 } 164 165 /* 166 * krb5_ccache_internalize() - Internalize the krb5_ccache. 167 */ 168 static krb5_error_code 169 krb5_ccache_internalize(kcontext, argp, buffer, lenremain) 170 krb5_context kcontext; 171 krb5_pointer *argp; 172 krb5_octet **buffer; 173 size_t *lenremain; 174 { 175 krb5_error_code kret; 176 krb5_ccache ccache; 177 krb5_int32 ibuf; 178 krb5_octet *bp; 179 size_t remain; 180 char *ccname; 181 182 bp = *buffer; 183 remain = *lenremain; 184 kret = EINVAL; 185 /* Read our magic number */ 186 if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) 187 ibuf = 0; 188 if (ibuf == KV5M_CCACHE) { 189 kret = ENOMEM; 190 191 /* Get the length of the ccache name */ 192 kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); 193 194 if (!kret && 195 (ccname = (char *) malloc((size_t) (ibuf+1))) && 196 !(kret = krb5_ser_unpack_bytes((krb5_octet *) ccname, 197 (size_t) ibuf, 198 &bp, &remain))) { 199 ccname[ibuf] = '\0'; 200 if (!(kret = krb5_cc_resolve(kcontext, ccname, &ccache)) && 201 !(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)) && 202 (ibuf == KV5M_CCACHE)) { 203 *buffer = bp; 204 *lenremain = remain; 205 *argp = (krb5_pointer) ccache; 206 } 207 free(ccname); 208 } 209 } 210 return(kret); 211 } 212 213 /* 214 * Register the ccache serializer. 215 */ 216 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV 217 krb5_ser_ccache_init(kcontext) 218 krb5_context kcontext; 219 { 220 return(krb5_register_serializer(kcontext, &krb5_ccache_ser_entry)); 221 } 222