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