k5encode.c revision 27702724
1/* $Xorg: k5encode.c,v 1.4 2001/02/09 02:03:42 xorgcvs Exp $ */ 2 3/* 4 5Copyright 1993, 1994, 1998 The Open Group 6 7Permission to use, copy, modify, distribute, and sell this software and its 8documentation for any purpose is hereby granted without fee, provided that 9the above copyright notice appear in all copies and that both that 10copyright notice and this permission notice appear in supporting 11documentation. 12 13The above copyright notice and this permission notice shall be included in 14all copies or substantial portions of the Software. 15 16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 20AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 23Except as contained in this notice, the name of The Open Group shall not be 24used in advertising or otherwise to promote the sale, use or other dealings 25in this Software without prior written authorization from The Open Group. 26 27*/ 28 29/* 30 * functions to encode/decode Kerberos V5 principals 31 * into something that can be reasonable spewed over 32 * the wire 33 * 34 * Author: Tom Yu <tlyu@MIT.EDU> 35 * 36 * Still needs to be fixed up wrt signed/unsigned lengths, but we'll worry 37 * about that later. 38 */ 39 40#ifdef HAVE_CONFIG_H 41#include <config.h> 42#endif 43#include <krb5/krb5.h> 44/* 9/93: krb5.h leaks some symbols */ 45#undef BITS32 46#undef xfree 47 48#include <X11/X.h> 49#include <X11/Xos.h> 50#include <X11/Xmd.h> 51#include <X11/Xfuncs.h> 52 53/* 54 * XauKrb5Encode 55 * 56 * this function encodes the principal passed to it in a format that can 57 * easily be dealt with by stuffing it into an X packet. Encoding is as 58 * follows: 59 * length count of the realm name 60 * realm 61 * component count 62 * length of component 63 * actual principal component 64 * etc.... 65 * 66 * Note that this function allocates a hunk of memory, which must be 67 * freed to avoid nasty memory leak type things. All counts are 68 * byte-swapped if needed. (except for the total length returned) 69 * 70 * nevermind.... stuffing the encoded packet in net byte order just to 71 * always do the right thing. Don't have to frob with alignment that way. 72 */ 73int 74XauKrb5Encode(princ, outbuf) 75 krb5_principal princ; /* principal to encode */ 76 krb5_data *outbuf; /* output buffer */ 77{ 78 CARD16 i, numparts, totlen = 0, plen, rlen; 79 char *cp, *pdata; 80 81 rlen = krb5_princ_realm(princ)->length; 82 numparts = krb5_princ_size(princ); 83 totlen = 2 + rlen + 2; /* include room for realm length 84 and component count */ 85 for (i = 0; i < numparts; i++) 86 totlen += krb5_princ_component(princ, i)->length + 2; 87 /* add 2 bytes each time for length */ 88 if ((outbuf->data = (char *)malloc(totlen)) == NULL) 89 return -1; 90 cp = outbuf->data; 91 *cp++ = (char)((int)(0xff00 & rlen) >> 8); 92 *cp++ = (char)(0x00ff & rlen); 93 memcpy(cp, krb5_princ_realm(princ)->data, rlen); 94 cp += rlen; 95 *cp++ = (char)((int)(0xff00 & numparts) >> 8); 96 *cp++ = (char)(0x00ff & numparts); 97 for (i = 0; i < numparts; i++) 98 { 99 plen = krb5_princ_component(princ, i)->length; 100 pdata = krb5_princ_component(princ, i)->data; 101 *cp++ = (char)((int)(0xff00 & plen) >> 8); 102 *cp++ = (char)(0x00ff & plen); 103 memcpy(cp, pdata, plen); 104 cp += plen; 105 } 106 outbuf->length = totlen; 107 return 0; 108} 109 110/* 111 * XauKrb5Decode 112 * 113 * This function essentially reverses what XauKrb5Encode does. 114 * return value: 0 if okay, -1 if malloc fails, -2 if inbuf format bad 115 */ 116int 117XauKrb5Decode(inbuf, princ) 118 krb5_data inbuf; 119 krb5_principal *princ; 120{ 121 CARD16 i, numparts, plen, rlen; 122 CARD8 *cp, *pdata; 123 124 if (inbuf.length < 4) 125 { 126 return -2; 127 } 128 *princ = (krb5_principal)malloc(sizeof (krb5_principal_data)); 129 if (*princ == NULL) 130 return -1; 131 bzero(*princ, sizeof (krb5_principal_data)); 132 cp = (CARD8 *)inbuf.data; 133 rlen = *cp++ << 8; 134 rlen |= *cp++; 135 if (inbuf.length < 4 + (int)rlen + 2) 136 { 137 krb5_free_principal(*princ); 138 return -2; 139 } 140 krb5_princ_realm(*princ)->data = (char *)malloc(rlen); 141 if (krb5_princ_realm(*princ)->data == NULL) 142 { 143 krb5_free_principal(*princ); 144 return -1; 145 } 146 krb5_princ_realm(*princ)->length = rlen; 147 memcpy(krb5_princ_realm(*princ)->data, cp, rlen); 148 cp += rlen; 149 numparts = *cp++ << 8; 150 numparts |= *cp++; 151 krb5_princ_name(*princ) = 152 (krb5_data *)malloc(numparts * sizeof (krb5_data)); 153 if (krb5_princ_name(*princ) == NULL) 154 { 155 krb5_free_principal(*princ); 156 return -1; 157 } 158 krb5_princ_size(*princ) = 0; 159 for (i = 0; i < numparts; i++) 160 { 161 if (cp + 2 > (CARD8 *)inbuf.data + inbuf.length) 162 { 163 krb5_free_principal(*princ); 164 return -2; 165 } 166 plen = *cp++ << 8; 167 plen |= *cp++; 168 if (cp + plen > (CARD8 *)inbuf.data + inbuf.length) 169 { 170 krb5_free_principal(*princ); 171 return -2; 172 } 173 pdata = (CARD8 *)malloc(plen); 174 if (pdata == NULL) 175 { 176 krb5_free_principal(*princ); 177 return -1; 178 } 179 krb5_princ_component(*princ, i)->data = (char *)pdata; 180 krb5_princ_component(*princ, i)->length = plen; 181 memcpy(pdata, cp, plen); 182 cp += plen; 183 krb5_princ_size(*princ)++; 184 } 185 return 0; 186} 187