127702724Smrg/* $Xorg: k5encode.c,v 1.4 2001/02/09 02:03:42 xorgcvs Exp $ */ 227702724Smrg 327702724Smrg/* 427702724Smrg 527702724SmrgCopyright 1993, 1994, 1998 The Open Group 627702724Smrg 727702724SmrgPermission to use, copy, modify, distribute, and sell this software and its 827702724Smrgdocumentation for any purpose is hereby granted without fee, provided that 927702724Smrgthe above copyright notice appear in all copies and that both that 1027702724Smrgcopyright notice and this permission notice appear in supporting 1127702724Smrgdocumentation. 1227702724Smrg 1327702724SmrgThe above copyright notice and this permission notice shall be included in 1427702724Smrgall copies or substantial portions of the Software. 1527702724Smrg 1627702724SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1727702724SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1827702724SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1927702724SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 2027702724SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 2127702724SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2227702724Smrg 2327702724SmrgExcept as contained in this notice, the name of The Open Group shall not be 2427702724Smrgused in advertising or otherwise to promote the sale, use or other dealings 2527702724Smrgin this Software without prior written authorization from The Open Group. 2627702724Smrg 2727702724Smrg*/ 2827702724Smrg 2927702724Smrg/* 3027702724Smrg * functions to encode/decode Kerberos V5 principals 3127702724Smrg * into something that can be reasonable spewed over 3227702724Smrg * the wire 3327702724Smrg * 3427702724Smrg * Author: Tom Yu <tlyu@MIT.EDU> 3527702724Smrg * 3627702724Smrg * Still needs to be fixed up wrt signed/unsigned lengths, but we'll worry 3727702724Smrg * about that later. 3827702724Smrg */ 3927702724Smrg 4027702724Smrg#ifdef HAVE_CONFIG_H 4127702724Smrg#include <config.h> 4227702724Smrg#endif 4327702724Smrg#include <krb5/krb5.h> 4427702724Smrg/* 9/93: krb5.h leaks some symbols */ 4527702724Smrg#undef BITS32 4627702724Smrg#undef xfree 4727702724Smrg 4827702724Smrg#include <X11/X.h> 4927702724Smrg#include <X11/Xos.h> 5027702724Smrg#include <X11/Xmd.h> 5127702724Smrg#include <X11/Xfuncs.h> 5227702724Smrg 5327702724Smrg/* 5427702724Smrg * XauKrb5Encode 5527702724Smrg * 5627702724Smrg * this function encodes the principal passed to it in a format that can 5727702724Smrg * easily be dealt with by stuffing it into an X packet. Encoding is as 5827702724Smrg * follows: 5927702724Smrg * length count of the realm name 6027702724Smrg * realm 6127702724Smrg * component count 6227702724Smrg * length of component 6327702724Smrg * actual principal component 6427702724Smrg * etc.... 6527702724Smrg * 6627702724Smrg * Note that this function allocates a hunk of memory, which must be 6727702724Smrg * freed to avoid nasty memory leak type things. All counts are 6827702724Smrg * byte-swapped if needed. (except for the total length returned) 6927702724Smrg * 7027702724Smrg * nevermind.... stuffing the encoded packet in net byte order just to 7127702724Smrg * always do the right thing. Don't have to frob with alignment that way. 7227702724Smrg */ 7327702724Smrgint 7427702724SmrgXauKrb5Encode(princ, outbuf) 7527702724Smrg krb5_principal princ; /* principal to encode */ 7627702724Smrg krb5_data *outbuf; /* output buffer */ 7727702724Smrg{ 7827702724Smrg CARD16 i, numparts, totlen = 0, plen, rlen; 7927702724Smrg char *cp, *pdata; 8027702724Smrg 8127702724Smrg rlen = krb5_princ_realm(princ)->length; 8227702724Smrg numparts = krb5_princ_size(princ); 8327702724Smrg totlen = 2 + rlen + 2; /* include room for realm length 8427702724Smrg and component count */ 8527702724Smrg for (i = 0; i < numparts; i++) 8627702724Smrg totlen += krb5_princ_component(princ, i)->length + 2; 8727702724Smrg /* add 2 bytes each time for length */ 8827702724Smrg if ((outbuf->data = (char *)malloc(totlen)) == NULL) 8927702724Smrg return -1; 9027702724Smrg cp = outbuf->data; 9127702724Smrg *cp++ = (char)((int)(0xff00 & rlen) >> 8); 9227702724Smrg *cp++ = (char)(0x00ff & rlen); 9327702724Smrg memcpy(cp, krb5_princ_realm(princ)->data, rlen); 9427702724Smrg cp += rlen; 9527702724Smrg *cp++ = (char)((int)(0xff00 & numparts) >> 8); 9627702724Smrg *cp++ = (char)(0x00ff & numparts); 9727702724Smrg for (i = 0; i < numparts; i++) 9827702724Smrg { 9927702724Smrg plen = krb5_princ_component(princ, i)->length; 10027702724Smrg pdata = krb5_princ_component(princ, i)->data; 10127702724Smrg *cp++ = (char)((int)(0xff00 & plen) >> 8); 10227702724Smrg *cp++ = (char)(0x00ff & plen); 10327702724Smrg memcpy(cp, pdata, plen); 10427702724Smrg cp += plen; 10527702724Smrg } 10627702724Smrg outbuf->length = totlen; 10727702724Smrg return 0; 10827702724Smrg} 10927702724Smrg 11027702724Smrg/* 11127702724Smrg * XauKrb5Decode 11227702724Smrg * 11327702724Smrg * This function essentially reverses what XauKrb5Encode does. 11427702724Smrg * return value: 0 if okay, -1 if malloc fails, -2 if inbuf format bad 11527702724Smrg */ 11627702724Smrgint 11727702724SmrgXauKrb5Decode(inbuf, princ) 11827702724Smrg krb5_data inbuf; 11927702724Smrg krb5_principal *princ; 12027702724Smrg{ 12127702724Smrg CARD16 i, numparts, plen, rlen; 12227702724Smrg CARD8 *cp, *pdata; 12327702724Smrg 12427702724Smrg if (inbuf.length < 4) 12527702724Smrg { 12627702724Smrg return -2; 12727702724Smrg } 12827702724Smrg *princ = (krb5_principal)malloc(sizeof (krb5_principal_data)); 12927702724Smrg if (*princ == NULL) 13027702724Smrg return -1; 13127702724Smrg bzero(*princ, sizeof (krb5_principal_data)); 13227702724Smrg cp = (CARD8 *)inbuf.data; 13327702724Smrg rlen = *cp++ << 8; 13427702724Smrg rlen |= *cp++; 13527702724Smrg if (inbuf.length < 4 + (int)rlen + 2) 13627702724Smrg { 13727702724Smrg krb5_free_principal(*princ); 13827702724Smrg return -2; 13927702724Smrg } 14027702724Smrg krb5_princ_realm(*princ)->data = (char *)malloc(rlen); 14127702724Smrg if (krb5_princ_realm(*princ)->data == NULL) 14227702724Smrg { 14327702724Smrg krb5_free_principal(*princ); 14427702724Smrg return -1; 14527702724Smrg } 14627702724Smrg krb5_princ_realm(*princ)->length = rlen; 14727702724Smrg memcpy(krb5_princ_realm(*princ)->data, cp, rlen); 14827702724Smrg cp += rlen; 14927702724Smrg numparts = *cp++ << 8; 15027702724Smrg numparts |= *cp++; 15127702724Smrg krb5_princ_name(*princ) = 15227702724Smrg (krb5_data *)malloc(numparts * sizeof (krb5_data)); 15327702724Smrg if (krb5_princ_name(*princ) == NULL) 15427702724Smrg { 15527702724Smrg krb5_free_principal(*princ); 15627702724Smrg return -1; 15727702724Smrg } 15827702724Smrg krb5_princ_size(*princ) = 0; 15927702724Smrg for (i = 0; i < numparts; i++) 16027702724Smrg { 16127702724Smrg if (cp + 2 > (CARD8 *)inbuf.data + inbuf.length) 16227702724Smrg { 16327702724Smrg krb5_free_principal(*princ); 16427702724Smrg return -2; 16527702724Smrg } 16627702724Smrg plen = *cp++ << 8; 16727702724Smrg plen |= *cp++; 16827702724Smrg if (cp + plen > (CARD8 *)inbuf.data + inbuf.length) 16927702724Smrg { 17027702724Smrg krb5_free_principal(*princ); 17127702724Smrg return -2; 17227702724Smrg } 17327702724Smrg pdata = (CARD8 *)malloc(plen); 17427702724Smrg if (pdata == NULL) 17527702724Smrg { 17627702724Smrg krb5_free_principal(*princ); 17727702724Smrg return -1; 17827702724Smrg } 17927702724Smrg krb5_princ_component(*princ, i)->data = (char *)pdata; 18027702724Smrg krb5_princ_component(*princ, i)->length = plen; 18127702724Smrg memcpy(pdata, cp, plen); 18227702724Smrg cp += plen; 18327702724Smrg krb5_princ_size(*princ)++; 18427702724Smrg } 18527702724Smrg return 0; 18627702724Smrg} 187