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