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