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