Bug Summary

File:lib/auth/srp_passwd.c
Location:line 230, column 16
Description:Although the value stored to 'idx' is used in the enclosing expression, the value is never actually read from 'idx'

Annotated Source Code

1/*
2 * Copyright (C) 2001-2012 Free Software Foundation, Inc.
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GnuTLS.
7 *
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
20 *
21 */
22
23/* Functions for operating in an SRP passwd file are included here */
24
25#include <gnutls_int.h>
26
27#ifdef ENABLE_SRP1
28
29#include "x509_b64.h"
30#include "gnutls_errors.h"
31#include <auth/srp_passwd.h>
32#include <auth/srp.h>
33#include "gnutls_auth.h"
34#include "gnutls_srp.h"
35#include "gnutls_dh.h"
36#include "debug.h"
37#include <gnutls_str.h>
38#include <gnutls_datumgnutls_datum_t.h>
39#include <gnutls_num.h>
40#include <random.h>
41
42static int _randomize_pwd_entry (SRP_PWD_ENTRY * entry);
43
44/* this function parses tpasswd.conf file. Format is:
45 * string(username):base64(v):base64(salt):int(index)
46 */
47static int
48pwd_put_values (SRP_PWD_ENTRY * entry, char *str)
49{
50 char *p;
51 int len, ret;
52 opaque *verifier;
53 size_t verifier_size;
54 int indx;
55
56 p = strrchr (str, ':'); /* we have index */
57 if (p == NULL((void*)0))
58 {
59 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",59); } while(0);
;
60 return GNUTLS_E_SRP_PWD_PARSING_ERROR-91;
61 }
62
63 *p = '\0';
64 p++;
65
66 indx = atoi (p);
67 if (indx == 0)
68 {
69 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",69); } while(0);
;
70 return GNUTLS_E_SRP_PWD_PARSING_ERROR-91;
71 }
72
73 /* now go for salt */
74 p = strrchr (str, ':'); /* we have salt */
75 if (p == NULL((void*)0))
76 {
77 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",77); } while(0);
;
78 return GNUTLS_E_SRP_PWD_PARSING_ERROR-91;
79 }
80
81 *p = '\0';
82 p++;
83
84 len = strlen (p);
85
86 entry->salt.size = _gnutls_sbase64_decode (p, len, &entry->salt.data);
87
88 if (entry->salt.size <= 0)
89 {
90 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",90); } while(0);
;
91 return GNUTLS_E_SRP_PWD_PARSING_ERROR-91;
92 }
93
94 /* now go for verifier */
95 p = strrchr (str, ':'); /* we have verifier */
96 if (p == NULL((void*)0))
97 {
98 _gnutls_free_datum (&entry->salt)_gnutls_free_datum_m(&entry->salt, gnutls_free);
99 return GNUTLS_E_SRP_PWD_PARSING_ERROR-91;
100 }
101
102 *p = '\0';
103 p++;
104
105 len = strlen (p);
106 ret = _gnutls_sbase64_decode (p, len, &verifier);
107 if (ret <= 0)
108 {
109 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",109); } while(0);
;
110 _gnutls_free_datum (&entry->salt)_gnutls_free_datum_m(&entry->salt, gnutls_free);
111 return GNUTLS_E_SRP_PWD_PARSING_ERROR-91;
112 }
113
114 verifier_size = ret;
115 entry->v.data = verifier;
116 entry->v.size = verifier_size;
117
118 /* now go for username */
119 *p = '\0';
120
121 entry->username = gnutls_strdup (str);
122 if (entry->username == NULL((void*)0))
123 {
124 _gnutls_free_datum (&entry->salt)_gnutls_free_datum_m(&entry->salt, gnutls_free);
125 _gnutls_free_datum (&entry->v)_gnutls_free_datum_m(&entry->v, gnutls_free);
126 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",126); } while(0);
;
127 return GNUTLS_E_MEMORY_ERROR-25;
128 }
129
130 return indx;
131}
132
133
134/* this function parses tpasswd.conf file. Format is:
135 * int(index):base64(n):int(g)
136 */
137static int
138pwd_put_values2 (SRP_PWD_ENTRY * entry, char *str)
139{
140 char *p;
141 int len;
142 opaque *tmp;
143 int ret;
144
145 p = strrchr (str, ':'); /* we have g */
146 if (p == NULL((void*)0))
147 {
148 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",148); } while(0);
;
149 return GNUTLS_E_SRP_PWD_PARSING_ERROR-91;
150 }
151
152 *p = '\0';
153 p++;
154
155 /* read the generator */
156 len = strlen (p);
157 if (p[len - 1] == '\n' || p[len - 1] == ' ')
158 len--;
159 ret = _gnutls_sbase64_decode (p, len, &tmp);
160
161 if (ret < 0)
162 {
163 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",163); } while(0);
;
164 return GNUTLS_E_SRP_PWD_PARSING_ERROR-91;
165 }
166
167 entry->g.data = tmp;
168 entry->g.size = ret;
169
170 /* now go for n - modulo */
171 p = strrchr (str, ':'); /* we have n */
172 if (p == NULL((void*)0))
173 {
174 _gnutls_free_datum (&entry->g)_gnutls_free_datum_m(&entry->g, gnutls_free);
175 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",175); } while(0);
;
176 return GNUTLS_E_SRP_PWD_PARSING_ERROR-91;
177 }
178
179 *p = '\0';
180 p++;
181
182 len = strlen (p);
183 ret = _gnutls_sbase64_decode (p, len, &tmp);
184
185 if (ret < 0)
186 {
187 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",187); } while(0);
;
188 _gnutls_free_datum (&entry->g)_gnutls_free_datum_m(&entry->g, gnutls_free);
189 return GNUTLS_E_SRP_PWD_PARSING_ERROR-91;
190 }
191
192 entry->n.data = tmp;
193 entry->n.size = ret;
194
195 return 0;
196}
197
198
199/* this function opens the tpasswd.conf file and reads the g and n
200 * values. They are put in the entry.
201 */
202static int
203pwd_read_conf (const char *pconf_file, SRP_PWD_ENTRY * entry, int idx)
204{
205 FILE *fd;
206 char line[2 * 1024];
207 unsigned i, len;
208 char indexstr[10];
209
210 snprintf (indexstr, sizeof(indexstr), "%u", (unsigned int)idx);
211
212 fd = fopen (pconf_file, "r");
213 if (fd == NULL((void*)0))
214 {
215 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",215); } while(0);
;
216 return GNUTLS_E_FILE_ERROR-64;
217 }
218
219 len = strlen (indexstr);
220 while (fgets (line, sizeof (line), fd) != NULL((void*)0))
221 {
222 /* move to first ':' */
223 i = 0;
224 while ((line[i] != ':') && (line[i] != '\0') && (i < sizeof (line)))
225 {
226 i++;
227 }
228 if (strncmp (indexstr, line, MAX (i, len)(((i)>(len))?(i):(len))) == 0)
229 {
230 if ((idx = pwd_put_values2 (entry, line)) >= 0)
Although the value stored to 'idx' is used in the enclosing expression, the value is never actually read from 'idx'
231 return 0;
232 else
233 {
234 return GNUTLS_E_SRP_PWD_ERROR-31;
235 }
236 }
237 }
238 return GNUTLS_E_SRP_PWD_ERROR-31;
239
240}
241
242int
243_gnutls_srp_pwd_read_entry (gnutls_session_t state, char *username,
244 SRP_PWD_ENTRY ** _entry)
245{
246 gnutls_srp_server_credentials_t cred;
247 FILE *fd;
248 char line[2 * 1024];
249 unsigned i, len;
250 int ret;
251 int idx, last_idx;
252 SRP_PWD_ENTRY *entry;
253
254 *_entry = gnutls_calloc (1, sizeof (SRP_PWD_ENTRY));
255 if (*_entry == NULL((void*)0))
256 {
257 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",257); } while(0);
;
258 return GNUTLS_E_MEMORY_ERROR-25;
259 }
260 entry = *_entry;
261
262 cred = (gnutls_srp_server_credentials_t)
263 _gnutls_get_cred (state->key, GNUTLS_CRD_SRP, NULL((void*)0));
264 if (cred == NULL((void*)0))
265 {
266 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",266); } while(0);
;
267 _gnutls_srp_entry_free (entry);
268 return GNUTLS_E_INSUFFICIENT_CREDENTIALS-32;
269 }
270
271 /* if the callback which sends the parameters is
272 * set, use it.
273 */
274 if (cred->pwd_callback != NULL((void*)0))
275 {
276 ret = cred->pwd_callback (state, username, &entry->salt,
277 &entry->v, &entry->g, &entry->n);
278
279 if (ret == 1)
280 { /* the user does not exist */
281 if (entry->g.size != 0 && entry->n.size != 0)
282 {
283 ret = _randomize_pwd_entry (entry);
284 if (ret < 0)
285 {
286 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",286); } while(0);
;
287 _gnutls_srp_entry_free (entry);
288 return ret;
289 }
290 return 0;
291 }
292 else
293 {
294 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",294); } while(0);
;
295 ret = -1; /* error in the callback */
296 }
297 }
298
299 if (ret < 0)
300 {
301 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",301); } while(0);
;
302 _gnutls_srp_entry_free (entry);
303 return GNUTLS_E_SRP_PWD_ERROR-31;
304 }
305
306 return 0;
307 }
308
309 /* The callback was not set. Proceed.
310 */
311
312 if (cred->password_file == NULL((void*)0))
313 {
314 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",314); } while(0);
;
315 return GNUTLS_E_SRP_PWD_ERROR-31;
316 }
317
318 /* Open the selected password file.
319 */
320 fd = fopen (cred->password_file, "r");
321 if (fd == NULL((void*)0))
322 {
323 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",323); } while(0);
;
324 _gnutls_srp_entry_free (entry);
325 return GNUTLS_E_SRP_PWD_ERROR-31;
326 }
327
328 last_idx = 1; /* a default value */
329
330 len = strlen (username);
331 while (fgets (line, sizeof (line), fd) != NULL((void*)0))
332 {
333 /* move to first ':' */
334 i = 0;
335 while ((line[i] != ':') && (line[i] != '\0') && (i < sizeof (line)))
336 {
337 i++;
338 }
339
340 if (strncmp (username, line, MAX (i, len)(((i)>(len))?(i):(len))) == 0)
341 {
342 if ((idx = pwd_put_values (entry, line)) >= 0)
343 {
344 /* Keep the last index in memory, so we can retrieve fake parameters (g,n)
345 * when the user does not exist.
346 */
347 /* XXX: last_idx will not be read as both if block branches return. */
348 last_idx = idx;
349 if (pwd_read_conf (cred->password_conf_file, entry, idx) == 0)
350 {
351 return 0;
352 }
353 else
354 {
355 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",355); } while(0);
;
356 _gnutls_srp_entry_free (entry);
357 return GNUTLS_E_SRP_PWD_ERROR-31;
358 }
359 }
360 else
361 {
362 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",362); } while(0);
;
363 _gnutls_srp_entry_free (entry);
364 return GNUTLS_E_SRP_PWD_ERROR-31;
365 }
366 }
367 }
368
369 /* user was not found. Fake him. Actually read the g,n values from
370 * the last index found and randomize the entry.
371 */
372 if (pwd_read_conf (cred->password_conf_file, entry, last_idx) == 0)
373 {
374 ret = _randomize_pwd_entry (entry);
375 if (ret < 0)
376 {
377 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",377); } while(0);
;
378 _gnutls_srp_entry_free (entry);
379 return ret;
380 }
381
382 return 0;
383 }
384
385 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",385); } while(0);
;
386 _gnutls_srp_entry_free (entry);
387 return GNUTLS_E_SRP_PWD_ERROR-31;
388
389}
390
391/* Randomizes the given password entry. It actually sets the verifier
392 * and the salt. Returns 0 on success.
393 */
394static int
395_randomize_pwd_entry (SRP_PWD_ENTRY * entry)
396{
397 unsigned char rnd;
398 int ret;
399
400 if (entry->g.size == 0 || entry->n.size == 0)
401 {
402 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",402); } while(0);
;
403 return GNUTLS_E_INTERNAL_ERROR-59;
404 }
405
406 ret = _gnutls_rnd (GNUTLS_RND_NONCE, &rnd, 1);
407 if (ret < 0)
408 {
409 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",409); } while(0);
;
410 return ret;
411 }
412
413 entry->salt.size = (rnd % 10) + 9;
414
415 entry->v.data = gnutls_malloc (20);
416 entry->v.size = 20;
417 if (entry->v.data == NULL((void*)0))
418 {
419 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",419); } while(0);
;
420 return GNUTLS_E_MEMORY_ERROR-25;
421 }
422
423 ret = _gnutls_rnd (GNUTLS_RND_RANDOM, entry->v.data, 20);
424 if (ret < 0)
425 {
426 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",426); } while(0);
;
427 return ret;
428 }
429
430 entry->salt.data = gnutls_malloc (entry->salt.size);
431 if (entry->salt.data == NULL((void*)0))
432 {
433 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",433); } while(0);
;
434 return GNUTLS_E_MEMORY_ERROR-25;
435 }
436
437 ret = _gnutls_rnd (GNUTLS_RND_NONCE, entry->salt.data, entry->salt.size);
438 if (ret < 0)
439 {
440 gnutls_assert ()do { if (__builtin_expect((_gnutls_log_level >= 2), 0)) _gnutls_log
( 2, "ASSERT: %s:%d\n", "srp_passwd.c",440); } while(0);
;
441 return ret;
442 }
443
444 return 0;
445}
446
447/* Free all the entry parameters, except if g and n are
448 * the static ones defined in gnutls.h
449 */
450void
451_gnutls_srp_entry_free (SRP_PWD_ENTRY * entry)
452{
453 _gnutls_free_datum (&entry->v)_gnutls_free_datum_m(&entry->v, gnutls_free);
454 _gnutls_free_datum (&entry->salt)_gnutls_free_datum_m(&entry->salt, gnutls_free);
455
456 if ((entry->g.data != gnutls_srp_1024_group_generator.data)
457 && (entry->g.data != gnutls_srp_3072_group_generator.data))
458 _gnutls_free_datum (&entry->g)_gnutls_free_datum_m(&entry->g, gnutls_free);
459
460 if (entry->n.data != gnutls_srp_1024_group_prime.data &&
461 entry->n.data != gnutls_srp_1536_group_prime.data &&
462 entry->n.data != gnutls_srp_2048_group_prime.data &&
463 entry->n.data != gnutls_srp_3072_group_prime.data &&
464 entry->n.data != gnutls_srp_4096_group_prime.data)
465 _gnutls_free_datum (&entry->n)_gnutls_free_datum_m(&entry->n, gnutls_free);
466
467 gnutls_free (entry->username);
468 gnutls_free (entry);
469}
470
471
472#endif /* ENABLE SRP */