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