Bug Summary

File:xdm/xdmauth.c
Location:line 155, column 2
Description:Potential leak of memory pointed to by 'xdmcpauth'

Annotated Source Code

1/*
2
3Copyright 1988, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included
12in all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall
23not be used in advertising or otherwise to promote the sale, use or
24other dealings in this Software without prior written authorization
25from The Open Group.
26
27*/
28/*
29 * xdm - display manager daemon
30 * Author: Keith Packard, MIT X Consortium
31 *
32 * xdmauth
33 *
34 * generate authorization data for XDM-AUTHORIZATION-1 as per XDMCP spec
35 */
36
37#include "dm.h"
38#include "dm_auth.h"
39#include "dm_error.h"
40
41#ifdef HASXDMAUTH1
42
43static char auth_name[256];
44static int auth_name_len;
45
46static void
47XdmPrintDataHex (const char *s, const char *a, int l)
48{
49 int i;
50
51 Debug ("%s", s);
52 for (i = 0; i < l; i++)
53 Debug (" %02x", a[i] & 0xff);
54 Debug ("\n");
55}
56
57# ifdef XDMCP
58static void
59XdmPrintArray8Hex (const char *s, ARRAY8Ptr a)
60{
61 XdmPrintDataHex (s, (char *) a->data, a->length);
62}
63# endif
64
65void
66XdmInitAuth (unsigned short name_len, char *name)
67{
68 if (name_len > 256)
69 name_len = 256;
70 auth_name_len = name_len;
71 memmove( auth_name, name, name_len)__builtin___memmove_chk (auth_name, name, name_len, __builtin_object_size
(auth_name, 0))
;
72}
73
74/*
75 * Generate authorization for XDM-AUTHORIZATION-1
76 *
77 * When being used with XDMCP, 8 bytes are generated for the session key
78 * (sigma), as the random number (rho) is already shared between xdm and
79 * the server. Otherwise, we'll prepend a random number to pass in the file
80 * between xdm and the server (16 bytes total)
81 */
82
83static Xauth *
84XdmGetAuthHelper (unsigned short namelen, char *name, int includeRho)
85{
86 Xauth *new;
87 new = malloc (sizeof (Xauth));
2
Memory is allocated
88
89 if (!new)
3
Assuming 'new' is non-null
4
Taking false branch
90 return (Xauth *) 0;
91 new->family = FamilyWild(65535);
92 new->address_length = 0;
93 new->address = NULL((void*)0);
94 new->number_length = 0;
95 new->number = NULL((void*)0);
96 if (includeRho)
5
Taking false branch
97 new->data_length = 16;
98 else
99 new->data_length = 8;
100
101 new->data = malloc (new->data_length);
102 if (!new->data)
6
Taking false branch
103 {
104 free (new);
105 return (Xauth *) 0;
106 }
107 new->name = malloc (namelen);
108 if (!new->name)
7
Taking false branch
109 {
110 free (new->data);
111 free (new);
112 return (Xauth *) 0;
113 }
114 memmove( (char *)new->name, name, namelen)__builtin___memmove_chk ((char *)new->name, name, namelen,
__builtin_object_size ((char *)new->name, 0))
;
115 new->name_length = namelen;
116 if (!GenerateAuthData ((char *)new->data, new->data_length))
8
Taking false branch
117 {
118 free (new->name);
119 free (new->data);
120 free (new);
121 return (Xauth *) 0;
122 }
123 /*
124 * set the first byte of the session key to zero as it
125 * is a DES key and only uses 56 bits
126 */
127 ((char *)new->data)[new->data_length - 8] = '\0';
128 XdmPrintDataHex ("Local server auth", (char *)new->data, new->data_length);
129 return new;
130}
131
132Xauth *
133XdmGetAuth (unsigned short namelen, char *name)
134{
135 return XdmGetAuthHelper (namelen, name, TRUE1);
136}
137
138# ifdef XDMCP
139
140void
141XdmGetXdmcpAuth (struct protoDisplay *pdpy,
142 unsigned short authorizationNameLen, char *authorizationName)
143{
144 Xauth *fileauth, *xdmcpauth;
145
146 if (pdpy->fileAuthorization && pdpy->xdmcpAuthorization)
147 return;
148 xdmcpauth = XdmGetAuthHelper (authorizationNameLen, authorizationName, FALSE0);
1
Calling 'XdmGetAuthHelper'
9
Returned allocated memory
149 if (!xdmcpauth)
10
Taking false branch
150 return;
151 fileauth = malloc (sizeof (Xauth));
152 if (!fileauth)
11
Assuming 'fileauth' is null
12
Taking true branch
153 {
154 XauDisposeAuth(xdmcpauth);
155 return;
13
Potential leak of memory pointed to by 'xdmcpauth'
156 }
157 /* build the file auth from the XDMCP auth */
158 *fileauth = *xdmcpauth;
159 fileauth->name = malloc (xdmcpauth->name_length);
160 fileauth->data = malloc (16);
161 fileauth->data_length = 16;
162 if (!fileauth->name || !fileauth->data)
163 {
164 XauDisposeAuth (xdmcpauth);
165 free (fileauth->name);
166 free (fileauth->data);
167 free (fileauth);
168 return;
169 }
170 /*
171 * for the file authorization, prepend the random number (rho)
172 * which is simply the number we've been passing back and
173 * forth via XDMCP
174 */
175 memmove( fileauth->name, xdmcpauth->name, xdmcpauth->name_length)__builtin___memmove_chk (fileauth->name, xdmcpauth->name
, xdmcpauth->name_length, __builtin_object_size (fileauth->
name, 0))
;
176 memmove( fileauth->data, pdpy->authenticationData.data, 8)__builtin___memmove_chk (fileauth->data, pdpy->authenticationData
.data, 8, __builtin_object_size (fileauth->data, 0))
;
177 memmove( fileauth->data + 8, xdmcpauth->data, 8)__builtin___memmove_chk (fileauth->data + 8, xdmcpauth->
data, 8, __builtin_object_size (fileauth->data + 8, 0))
;
178 XdmPrintDataHex ("Accept packet auth", xdmcpauth->data, xdmcpauth->data_length);
179 XdmPrintDataHex ("Auth file auth", fileauth->data, fileauth->data_length);
180 /* encrypt the session key for its trip back to the server */
181 XdmcpWrap ((unsigned char *)xdmcpauth->data, (unsigned char *)&pdpy->key,
182 (unsigned char *)xdmcpauth->data, 8);
183 pdpy->fileAuthorization = fileauth;
184 pdpy->xdmcpAuthorization = xdmcpauth;
185}
186
187# define atox(c)('0' <= c && c <= '9' ? c - '0' : 'a' <= c &&
c <= 'f' ? c - 'a' + 10 : 'A' <= c && c <= 'F'
? c - 'A' + 10 : -1)
('0' <= c && c <= '9' ? c - '0' : \
188 'a' <= c && c <= 'f' ? c - 'a' + 10 : \
189 'A' <= c && c <= 'F' ? c - 'A' + 10 : -1)
190
191static int
192HexToBinary(char *key)
193{
194 char *out, *in;
195 int top, bottom;
196
197 in = key + 2;
198 out= key;
199 while (in[0] && in[1])
200 {
201 top = atox(in[0])('0' <= in[0] && in[0] <= '9' ? in[0] - '0' : 'a'
<= in[0] && in[0] <= 'f' ? in[0] - 'a' + 10 : 'A'
<= in[0] && in[0] <= 'F' ? in[0] - 'A' + 10 : -
1)
;
202 if (top == -1)
203 return 0;
204 bottom = atox(in[1])('0' <= in[1] && in[1] <= '9' ? in[1] - '0' : 'a'
<= in[1] && in[1] <= 'f' ? in[1] - 'a' + 10 : 'A'
<= in[1] && in[1] <= 'F' ? in[1] - 'A' + 10 : -
1)
;
205 if (bottom == -1)
206 return 0;
207 *out++ = (top << 4) | bottom;
208 in += 2;
209 }
210 if (in[0])
211 return 0;
212 *out++ = '\0';
213 return 1;
214}
215
216/*
217 * Search the Keys file for the entry matching this display. This
218 * routine accepts either plain ascii strings for keys, or hex-encoded numbers
219 */
220
221static int
222XdmGetKey(struct protoDisplay *pdpy, ARRAY8Ptr displayID)
223{
224 FILE *keys;
225 char line[1024], id[1024], key[1024];
226 int keylen;
227
228 Debug ("Lookup key for %*.*s\n", displayID->length, displayID->length, displayID->data);
229 keys = fopen (keyFile, "r");
230 if (!keys)
231 return FALSE0;
232 while (fgets (line, sizeof (line) - 1, keys))
233 {
234 if (line[0] == '#' || sscanf (line, "%s %s", id, key) != 2)
235 continue;
236 bzero(line, sizeof(line))__builtin___memset_chk (line, 0, sizeof(line), __builtin_object_size
(line, 0))
;
237 Debug ("Key entry for \"%s\" %ld bytes\n", id, strlen(key));
238 if (strlen (id) == displayID->length &&
239 !strncmp (id, (char *)displayID->data, displayID->length))
240 {
241 if (!strncmp (key, "0x", 2) || !strncmp (key, "0X", 2))
242 if (!HexToBinary (key))
243 break;
244 keylen = strlen (key);
245 while (keylen < 7)
246 key[keylen++] = '\0';
247 pdpy->key.data[0] = '\0';
248 memmove( pdpy->key.data + 1, key, 7)__builtin___memmove_chk (pdpy->key.data + 1, key, 7, __builtin_object_size
(pdpy->key.data + 1, 0))
;
249 bzero(key, sizeof(key))__builtin___memset_chk (key, 0, sizeof(key), __builtin_object_size
(key, 0))
;
250 fclose (keys);
251 return TRUE1;
252 }
253 }
254 bzero(line, sizeof(line))__builtin___memset_chk (line, 0, sizeof(line), __builtin_object_size
(line, 0))
;
255 bzero(key, sizeof(key))__builtin___memset_chk (key, 0, sizeof(key), __builtin_object_size
(key, 0))
;
256 fclose (keys);
257 return FALSE0;
258}
259
260/*ARGSUSED*/
261int
262XdmCheckAuthentication(struct protoDisplay *pdpy, ARRAY8Ptr displayID,
263 ARRAY8Ptr authenticationName, ARRAY8Ptr authenticationData)
264{
265 XdmAuthKeyPtr incoming;
266
267 if (!XdmGetKey (pdpy, displayID))
268 return FALSE0;
269 if (authenticationData->length != 8)
270 return FALSE0;
271 XdmcpUnwrap (authenticationData->data, (unsigned char *)&pdpy->key,
272 authenticationData->data, 8);
273 XdmPrintArray8Hex ("Request packet auth", authenticationData);
274 if (!XdmcpCopyARRAY8(authenticationData, &pdpy->authenticationData))
275 return FALSE0;
276 incoming = (XdmAuthKeyPtr) authenticationData->data;
277 XdmcpIncrementKey (incoming);
278 XdmcpWrap (authenticationData->data, (unsigned char *)&pdpy->key,
279 authenticationData->data, 8);
280 return TRUE1;
281}
282
283# endif /* XDMCP */
284#endif /* HASXDMAUTH (covering the entire file) */