1 #pragma ident "%Z%%M% %I% %E% SMI" 2 /* 3 * lib/krb5/krb/ser_addr.c 4 * 5 * Copyright 1995 by the Massachusetts Institute of Technology. 6 * All Rights Reserved. 7 * 8 * Export of this software from the United States of America may 9 * require a specific license from the United States Government. 10 * It is the responsibility of any person or organization contemplating 11 * export to 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 M.I.T. not be used in advertising or publicity pertaining 19 * to distribution of the software without specific, written prior 20 * permission. M.I.T. 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 */ 25 26 /* 27 * ser_addr.c - Serialize a krb5_address structure. 28 */ 29 #include <k5-int.h> 30 31 /* 32 * Routines to deal with externalizing the krb5_address: 33 * krb5_address_size(); 34 * krb5_address_externalize(); 35 * krb5_address_internalize(); 36 */ 37 static krb5_error_code krb5_address_size 38 KRB5_PROTOTYPE((krb5_context, krb5_pointer, size_t *)); 39 static krb5_error_code krb5_address_externalize 40 KRB5_PROTOTYPE((krb5_context, krb5_pointer, krb5_octet **, size_t *)); 41 static krb5_error_code krb5_address_internalize 42 KRB5_PROTOTYPE((krb5_context,krb5_pointer *, krb5_octet **, size_t *)); 43 44 /* Local data */ 45 static const krb5_ser_entry krb5_address_ser_entry = { 46 KV5M_ADDRESS, /* Type */ 47 krb5_address_size, /* Sizer routine */ 48 krb5_address_externalize, /* Externalize routine */ 49 krb5_address_internalize /* Internalize routine */ 50 }; 51 52 /* 53 * krb5_address_size() - Determine the size required to externalize 54 * the krb5_address. 55 */ 56 /*ARGSUSED*/ 57 static krb5_error_code 58 krb5_address_size(kcontext, arg, sizep) 59 krb5_context kcontext; 60 krb5_pointer arg; 61 size_t *sizep; 62 { 63 krb5_error_code kret; 64 krb5_address *address; 65 66 /* 67 * krb5_address requires: 68 * krb5_int32 for KV5M_ADDRESS 69 * krb5_int32 for addrtype 70 * krb5_int32 for length 71 * address->length for contents 72 * krb5_int32 for KV5M_ADDRESS 73 */ 74 kret = EINVAL; 75 address = (krb5_address *) arg; 76 if (address) { 77 *sizep += (sizeof(krb5_int32) + 78 sizeof(krb5_int32) + 79 sizeof(krb5_int32) + 80 sizeof(krb5_int32) + 81 (size_t) address->length); 82 kret = 0; 83 } 84 return(kret); 85 } 86 87 /* 88 * krb5_address_externalize() - Externalize the krb5_address. 89 */ 90 static krb5_error_code 91 krb5_address_externalize(kcontext, arg, buffer, lenremain) 92 krb5_context kcontext; 93 krb5_pointer arg; 94 krb5_octet **buffer; 95 size_t *lenremain; 96 { 97 krb5_error_code kret; 98 krb5_address *address; 99 size_t required; 100 krb5_octet *bp; 101 size_t remain; 102 103 required = 0; 104 bp = *buffer; 105 remain = *lenremain; 106 kret = EINVAL; 107 address = (krb5_address *) arg; 108 if (address) { 109 kret = ENOMEM; 110 if (!krb5_address_size(kcontext, arg, &required) && 111 (required <= remain)) { 112 /* Our identifier */ 113 (void) krb5_ser_pack_int32(KV5M_ADDRESS, &bp, &remain); 114 115 /* Our addrtype */ 116 (void) krb5_ser_pack_int32((krb5_int32) address->addrtype, 117 &bp, &remain); 118 119 /* Our length */ 120 (void) krb5_ser_pack_int32((krb5_int32) address->length, 121 &bp, &remain); 122 123 /* Our contents */ 124 (void) krb5_ser_pack_bytes(address->contents, 125 (size_t) address->length, 126 &bp, &remain); 127 128 /* Finally, our trailer */ 129 (void) krb5_ser_pack_int32(KV5M_ADDRESS, &bp, &remain); 130 131 kret = 0; 132 *buffer = bp; 133 *lenremain = remain; 134 } 135 } 136 return(kret); 137 } 138 139 /* 140 * krb5_address_internalize() - Internalize the krb5_address. 141 */ 142 143 /*ARGSUSED*/ 144 static krb5_error_code 145 krb5_address_internalize(kcontext, argp, buffer, lenremain) 146 krb5_context kcontext; 147 krb5_pointer *argp; 148 krb5_octet **buffer; 149 size_t *lenremain; 150 { 151 krb5_error_code kret; 152 krb5_address *address; 153 krb5_int32 ibuf; 154 krb5_octet *bp; 155 size_t remain; 156 157 bp = *buffer; 158 remain = *lenremain; 159 kret = EINVAL; 160 /* Read our magic number */ 161 if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) 162 ibuf = 0; 163 if (ibuf == KV5M_ADDRESS) { 164 kret = ENOMEM; 165 166 /* Get a address */ 167 if ((remain >= (2*sizeof(krb5_int32))) && 168 (address = (krb5_address *) MALLOC(sizeof(krb5_address)))) { 169 (void) memset(address, 0, sizeof(krb5_address)); 170 171 address->magic = KV5M_ADDRESS; 172 173 /* Get the addrtype */ 174 (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); 175 address->addrtype = (krb5_addrtype) ibuf; 176 177 /* Get the length */ 178 (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain); 179 address->length = (int) ibuf; 180 181 /* Get the string */ 182 address->contents = (krb5_octet *) MALLOC((size_t) (ibuf)); 183 if ((address->contents) && 184 !(kret = krb5_ser_unpack_bytes(address->contents, 185 (size_t) ibuf, 186 &bp, &remain))) { 187 /* Get the trailer */ 188 if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) 189 ibuf = 0; 190 191 if (!kret && (ibuf == KV5M_ADDRESS)) { 192 address->magic = KV5M_ADDRESS; 193 *buffer = bp; 194 *lenremain = remain; 195 *argp = (krb5_pointer) address; 196 } 197 else 198 kret = EINVAL; 199 } 200 if (kret) { 201 if (address->contents) 202 FREE(address->contents, address->length); 203 FREE(address, sizeof (krb5_address)); 204 } 205 } 206 } 207 return(kret); 208 } 209 210 /* 211 * Register the address serializer. 212 */ 213 krb5_error_code 214 krb5_ser_address_init(kcontext) 215 krb5_context kcontext; 216 { 217 return(krb5_register_serializer(kcontext, &krb5_address_ser_entry)); 218 } 219