File: | xdm/xdmauth.c |
Location: | line 155, column 2 |
Description: | Potential leak of memory pointed to by 'xdmcpauth' |
1 | /* | |||
2 | ||||
3 | Copyright 1988, 1998 The Open Group | |||
4 | ||||
5 | Permission to use, copy, modify, distribute, and sell this software and its | |||
6 | documentation for any purpose is hereby granted without fee, provided that | |||
7 | the above copyright notice appear in all copies and that both that | |||
8 | copyright notice and this permission notice appear in supporting | |||
9 | documentation. | |||
10 | ||||
11 | The above copyright notice and this permission notice shall be included | |||
12 | in all copies or substantial portions of the Software. | |||
13 | ||||
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |||
15 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |||
17 | IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR | |||
18 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |||
19 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |||
20 | OTHER DEALINGS IN THE SOFTWARE. | |||
21 | ||||
22 | Except as contained in this notice, the name of The Open Group shall | |||
23 | not be used in advertising or otherwise to promote the sale, use or | |||
24 | other dealings in this Software without prior written authorization | |||
25 | from 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 | ||||
43 | static char auth_name[256]; | |||
44 | static int auth_name_len; | |||
45 | ||||
46 | static void | |||
47 | XdmPrintDataHex (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 | |||
58 | static void | |||
59 | XdmPrintArray8Hex (const char *s, ARRAY8Ptr a) | |||
60 | { | |||
61 | XdmPrintDataHex (s, (char *) a->data, a->length); | |||
62 | } | |||
63 | # endif | |||
64 | ||||
65 | void | |||
66 | XdmInitAuth (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 | ||||
83 | static Xauth * | |||
84 | XdmGetAuthHelper (unsigned short namelen, char *name, int includeRho) | |||
85 | { | |||
86 | Xauth *new; | |||
87 | new = malloc (sizeof (Xauth)); | |||
88 | ||||
89 | if (!new) | |||
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) | |||
97 | new->data_length = 16; | |||
98 | else | |||
99 | new->data_length = 8; | |||
100 | ||||
101 | new->data = malloc (new->data_length); | |||
102 | if (!new->data) | |||
103 | { | |||
104 | free (new); | |||
105 | return (Xauth *) 0; | |||
106 | } | |||
107 | new->name = malloc (namelen); | |||
108 | if (!new->name) | |||
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)) | |||
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 | ||||
132 | Xauth * | |||
133 | XdmGetAuth (unsigned short namelen, char *name) | |||
134 | { | |||
135 | return XdmGetAuthHelper (namelen, name, TRUE1); | |||
136 | } | |||
137 | ||||
138 | # ifdef XDMCP | |||
139 | ||||
140 | void | |||
141 | XdmGetXdmcpAuth (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); | |||
| ||||
149 | if (!xdmcpauth) | |||
150 | return; | |||
151 | fileauth = malloc (sizeof (Xauth)); | |||
152 | if (!fileauth) | |||
153 | { | |||
154 | XauDisposeAuth(xdmcpauth); | |||
155 | return; | |||
| ||||
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 | ||||
191 | static int | |||
192 | HexToBinary(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 | ||||
221 | static int | |||
222 | XdmGetKey(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*/ | |||
261 | int | |||
262 | XdmCheckAuthentication(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) */ |