Bug Summary

File:/dev/shm/scan_build/../sssd/src/sss_client/sssd_pac.c
Location:line 282, column 16
Description:Potential leak of memory pointed to by 'data.data'

Annotated Source Code

1/*
2 Authors:
3 Sumit Bose <sbose@redhat.com>
4
5 Copyright (C) 2011, 2012, 2013 Red Hat
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21/* A short documentation about authdata plugins can be found in
22 * http://http://k5wiki.kerberos.org/wiki/Projects/VerifyAuthData */
23
24#include <krb5/krb5.h>
25#include <errno(*__errno_location ()).h>
26
27#include "krb5_authdata_int.h"
28#include "sss_cli.h"
29
30
31struct sssd_context {
32 krb5_data data;
33};
34
35static krb5_error_code
36sssdpac_init(krb5_context kcontext, void **plugin_context)
37{
38 *plugin_context = NULL((void*)0);
39 return 0;
40}
41
42static void
43sssdpac_flags(krb5_context kcontext,
44 void *plugin_context,
45 krb5_authdatatype ad_type,
46 krb5_flags *flags)
47{
48 *flags = AD_USAGE_KDC_ISSUED0x08 | AD_USAGE_TGS_REQ0x02;
49}
50
51static void
52sssdpac_fini(krb5_context kcontext, void *plugin_context)
53{
54 return;
55}
56
57static krb5_error_code
58sssdpac_request_init(krb5_context kcontext,
59 krb5_authdata_context context,
60 void *plugin_context,
61 void **request_context)
62{
63 struct sssd_context *sssdctx;
64
65 sssdctx = (struct sssd_context *)calloc(1, sizeof(*sssdctx));
66 if (sssdctx == NULL((void*)0)) {
67 return ENOMEM12;
68 }
69
70 *request_context = sssdctx;
71
72 return 0;
73}
74
75static krb5_error_code
76sssdpac_import_authdata(krb5_context kcontext,
77 krb5_authdata_context context,
78 void *plugin_context,
79 void *request_context,
80 krb5_authdata **authdata,
81 krb5_boolean kdc_issued,
82 krb5_const_principal kdc_issuer)
83{
84 char *data = NULL((void*)0);
85 struct sssd_context *sssdctx = (struct sssd_context *)request_context;
86
87 if (authdata[0] == NULL((void*)0)) {
88 return EINVAL22;
89 }
90
91 if (authdata[0]->length > 0) {
92 data = malloc(sizeof(char) * authdata[0]->length);
93 if (data == NULL((void*)0)) {
94 return ENOMEM12;
95 }
96 memcpy(data, authdata[0]->contents, authdata[0]->length);
97 }
98
99 if (sssdctx->data.data != NULL((void*)0)) {
100 krb5_free_data_contents(kcontext, &sssdctx->data);
101 }
102
103 sssdctx->data.length = authdata[0]->length;
104 sssdctx->data.data = data;
105 return 0;
106}
107
108static void
109sssdpac_request_fini(krb5_context kcontext,
110 krb5_authdata_context context,
111 void *plugin_context,
112 void *request_context)
113{
114 struct sssd_context *sssdctx = (struct sssd_context *)request_context;
115
116 if (sssdctx != NULL((void*)0)) {
117 if (sssdctx->data.data != NULL((void*)0)) {
118 krb5_free_data_contents(kcontext, &sssdctx->data);
119 }
120
121 free(sssdctx);
122 }
123}
124
125static krb5_error_code sssdpac_verify(krb5_context kcontext,
126 krb5_authdata_context context,
127 void *plugin_context,
128 void *request_context,
129 const krb5_auth_context *auth_context,
130 const krb5_keyblock *key,
131 const krb5_ap_req *req)
132{
133 krb5_error_code kerr;
134 int ret;
135 krb5_pac pac;
136 struct sssd_context *sssdctx = (struct sssd_context *)request_context;
137 struct sss_cli_req_data sss_data;
138 int errnop;
139
140 if (sssdctx == NULL((void*)0) || sssdctx->data.data == NULL((void*)0)) {
141 return EINVAL22;
142 }
143
144 kerr = krb5_pac_parse(kcontext, sssdctx->data.data,
145 sssdctx->data.length, &pac);
146 if (kerr != 0) {
147 return EINVAL22;
148 }
149
150 kerr = krb5_pac_verify(kcontext, pac,
151 req->ticket->enc_part2->times.authtime,
152 req->ticket->enc_part2->client, key, NULL((void*)0));
153 if (kerr != 0) {
154 /* The krb5 documentation says:
155 * A checksum mismatch can occur if the PAC was copied from a
156 * cross-realm TGT by an ignorant KDC; also Apple Mac OS X Server
157 * Open Directory (as of 10.6) generates PACs with no server checksum
158 * at all. One should consider not failing the whole authentication
159 * because of this reason, but, instead, treating the ticket as
160 * if it did not contain a PAC or marking the PAC information as
161 * non-verified.
162 */
163 return 0;
164 }
165
166 sss_data.len = sssdctx->data.length;
167 sss_data.data = sssdctx->data.data;
168
169 ret = sss_pac_make_request(SSS_PAC_ADD_PAC_USER, &sss_data,
170 NULL((void*)0), NULL((void*)0), &errnop);
171 if (ret != 0) {
172 /* Ignore the error */
173 }
174
175 return 0;
176}
177
178static krb5_error_code
179sssdpac_size(krb5_context kcontext,
180 krb5_authdata_context context,
181 void *plugin_context,
182 void *request_context,
183 size_t *sizep)
184{
185 struct sssd_context *sssdctx = (struct sssd_context *)request_context;
186
187 *sizep += sizeof(krb5_int32);
188
189 *sizep += sssdctx->data.length;
190
191 *sizep += sizeof(krb5_int32);
192
193 return 0;
194}
195
196static krb5_error_code
197sssdpac_externalize(krb5_context kcontext,
198 krb5_authdata_context context,
199 void *plugin_context,
200 void *request_context,
201 krb5_octet **buffer,
202 size_t *lenremain)
203{
204 krb5_error_code code = 0;
205 struct sssd_context *sssdctx = (struct sssd_context *)request_context;
206 size_t required = 0;
207 krb5_octet *bp;
208 size_t remain;
209
210 bp = *buffer;
211 remain = *lenremain;
212
213 if (sssdctx->data.data != NULL((void*)0)) {
214 sssdpac_size(kcontext, context, plugin_context,
215 request_context, &required);
216
217 if (required <= remain) {
218 krb5_ser_pack_int32((krb5_int32)sssdctx->data.length,
219 &bp, &remain);
220 krb5_ser_pack_bytes((krb5_octet *)sssdctx->data.data,
221 (size_t)sssdctx->data.length,
222 &bp, &remain);
223 krb5_ser_pack_int32(0,
224 &bp, &remain);
225 } else {
226 code = ENOMEM12;
227 }
228 } else {
229 krb5_ser_pack_int32(0, &bp, &remain); /* length */
230 krb5_ser_pack_int32(0, &bp, &remain); /* verified */
231 }
232
233 *buffer = bp;
234 *lenremain = remain;
235
236 return code;
237}
238
239static krb5_error_code
240sssdpac_internalize(krb5_context kcontext,
241 krb5_authdata_context context,
242 void *plugin_context,
243 void *request_context,
244 krb5_octet **buffer,
245 size_t *lenremain)
246{
247 struct sssd_context *sssdctx = (struct sssd_context *)request_context;
248 krb5_error_code code;
249 krb5_int32 ibuf;
250 krb5_octet *bp;
251 size_t remain;
252 krb5_data data;
253
254 bp = *buffer;
255 remain = *lenremain;
256
257 /* length */
258 code = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
259 if (code != 0) {
1
Assuming 'code' is equal to 0
2
Taking false branch
260 return code;
261 }
262
263 if (ibuf != 0) {
3
Assuming 'ibuf' is not equal to 0
4
Taking true branch
264
265 data.length = ibuf;
266 data.data = malloc(sizeof(char) * ibuf);
5
Memory is allocated
267 if (data.data == NULL((void*)0)) {
6
Taking false branch
268 return ENOMEM12;
269 }
270 memcpy(data.data, bp, ibuf);
271
272 bp += ibuf;
273 remain -= ibuf;
274 } else {
275 data.length = 0;
276 data.data = NULL((void*)0);
277 }
278
279 /* verified */
280 code = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
281 if (code != 0) {
7
Assuming 'code' is not equal to 0
8
Taking true branch
282 return code;
9
Potential leak of memory pointed to by 'data.data'
283 }
284
285 if (sssdctx->data.data != NULL((void*)0)) {
286 krb5_free_data_contents(kcontext, &sssdctx->data);
287 }
288
289 sssdctx->data.length = data.length;
290 sssdctx->data.data = data.data;
291
292 *buffer = bp;
293 *lenremain = remain;
294
295 return 0;
296}
297
298static krb5_authdatatype sssdpac_ad_types[] = { KRB5_AUTHDATA_WIN2K_PAC128, 0 };
299
300krb5plugin_authdata_client_ftable_v0 authdata_client_0 = {
301 ((void *)((uintptr_t)("sssd_sssdpac"))),
302 sssdpac_ad_types,
303 sssdpac_init,
304 sssdpac_fini,
305 sssdpac_flags,
306 sssdpac_request_init,
307 sssdpac_request_fini,
308 NULL((void*)0),
309 NULL((void*)0),
310 NULL((void*)0),
311 NULL((void*)0),
312 NULL((void*)0),
313 sssdpac_import_authdata,
314 NULL((void*)0),
315 NULL((void*)0),
316 sssdpac_verify,
317 sssdpac_size,
318 sssdpac_externalize,
319 sssdpac_internalize,
320 NULL((void*)0)
321};