Bug Summary

File:lib/keytab.c
Warning:line 223, column 4
Value stored to 'pos' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name keytab.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/builds/gsasl/shishi/lib -resource-dir /usr/lib64/clang/14.0.0 -D HAVE_CONFIG_H -I . -I .. -I ./gl -I ./gl -D LOCALEDIR="/usr/local/share/locale" -D SYSTEMCFGFILE="/usr/local/etc/shishi/shishi.conf" -D SKELCFGFILE="/usr/local/etc/shishi/shishi.skel" -D HOSTKEYSFILE="/usr/local/etc/shishi/shishi.keys" -D PIC -internal-isystem /usr/lib64/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/builds/gsasl/shishi/lib -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/gsasl/shishi/clang-analyzer/2022-08-08-065803-50050-1 -x c keytab.c
1/* keys.c --- Functions for reading /etc/krb5.keytab style key files.
2 * Copyright (C) 2002-2022 Simon Josefsson
3 *
4 * This file is part of Shishi.
5 *
6 * Shishi is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Shishi is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, see http://www.gnu.org/licenses or write
18 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19 * Floor, Boston, MA 02110-1301, USA
20 *
21 */
22
23#include "internal.h"
24
25/* Get _shishi_hexprint, etc. */
26#include "utils.h"
27
28/**
29 * shishi_keys_add_keytab_mem:
30 * @handle: shishi handle as allocated by shishi_init().
31 * @data: constant memory buffer with keytab of @len size.
32 * @len: size of memory buffer with keytab data.
33 * @keys: allocated key set to store keys in.
34 *
35 * Read keys from a MIT keytab data structure, and add them to the key
36 * set.
37 *
38 * The format of keytab's is proprietary, and this function support
39 * the 0x0501 and 0x0502 formats. See the section The MIT Kerberos
40 * Keytab Binary File Format in the Shishi manual for a description of
41 * the reverse-engineered format.
42 *
43 * Returns: Returns %SHISHI_KEYTAB_ERROR if the data does not
44 * represent a valid keytab structure, and %SHISHI_OK on success.
45 **/
46int
47shishi_keys_add_keytab_mem (Shishi * handle,
48 const char *data, size_t len, Shishi_keys * keys)
49{
50 int rc;
51 uint16_t file_format_version;
52 size_t entrystartpos;
53 uint16_t num_components; /* sub 1 if version 0x501 */
54 size_t i;
55 Shishi_key *key;
56
57 if (VERBOSENOISE (handle)(handle->verbose & (1<<1)))
58 {
59 printf ("keytab len %zu (0x%zx)\n", len, len);
60 _shishi_hexprint (data, len);
61 }
62
63 /* Check file format. */
64 file_format_version = (data[0] << 8) | data[1];
65
66 if (VERBOSENOISE (handle)(handle->verbose & (1<<1)))
67 printf ("keytab file_format_version %04X\n", file_format_version);
68
69 if (file_format_version != 0x0501 && file_format_version != 0x0502)
70 return SHISHI_KEYTAB_ERROR;
71
72 /* Check file integrity first, to avoid error-checking below. */
73 entrystartpos = 2;
74 while (entrystartpos < len)
75 {
76 int32_t size = data[entrystartpos] << 24 | data[entrystartpos + 1] << 16
77 | data[entrystartpos + 2] << 8 | data[entrystartpos + 3];
78 entrystartpos += 4;
79
80 if (VERBOSENOISE (handle)(handle->verbose & (1<<1)))
81 {
82 printf ("keytab size %d (%x)\n", size, (unsigned) size);
83 printf ("keytab pos %zu < %zu\n", entrystartpos + size, len);
84 }
85
86 if (entrystartpos + size > len)
87 return SHISHI_KEYTAB_ERROR;
88
89 /* Go to next entry... */
90 entrystartpos += size;
91 }
92 if (entrystartpos != len)
93 return SHISHI_KEYTAB_ERROR;
94
95 rc = shishi_key (handle, &key);
96 if (rc != SHISHI_OK)
97 return rc;
98
99 entrystartpos = 2;
100 while (entrystartpos < len)
101 {
102 size_t pos = entrystartpos;
103 uint16_t size = data[pos] << 24 | data[pos + 1] << 16
104 | data[pos + 2] << 8 | data[pos + 3];
105 pos += 4;
106
107 if (VERBOSENOISE (handle)(handle->verbose & (1<<1)))
108 printf ("keytab size %d (%x)\n", size, size);
109
110 /* Num_components */
111 num_components = data[pos] << 8 | data[pos + 1];
112 pos += 2;
113
114 if (file_format_version == 0x0501)
115 num_components--;
116
117 /* Realm */
118 {
119 uint16_t realmlen = data[pos] << 8 | data[pos + 1];
120 char *realm = xstrndup (&data[pos + 2], realmlen);
121
122 pos += 2 + realmlen;
123
124 shishi_key_realm_set (key, realm);
125 free (realm);
126 }
127
128 /* Principal components. */
129 {
130 char *name = NULL((void*)0);
131 size_t namelen = 0;
132
133 for (i = 0; i < num_components; i++)
134 {
135 size_t l;
136
137 l = data[pos] << 8 | data[pos + 1];
138 pos += 2;
139
140 name = xrealloc (name, namelen + l + 1);
141 memcpy (name + namelen, &data[pos], l);
142 name[namelen + l] = '/';
143
144 namelen += l + 1;
145 pos += l;
146
147 }
148 name[namelen - 1] = '\0';
149 shishi_key_principal_set (key, name);
150 free (name);
151 }
152
153 /* Name_type */
154 {
155 uint32_t name_type /* not present if version 0x501 */
156 = data[pos] << 24 | data[pos + 1] << 16
157 | data[pos + 2] << 8 | data[pos + 3];
158 pos += 4;
159
160 if (VERBOSENOISE (handle)(handle->verbose & (1<<1)))
161 printf ("keytab nametype %" PRIu32"u" " (0x%08x)\n", name_type,
162 name_type);
163 }
164
165 /* Timestamp */
166 {
167 uint32_t timestamp =
168 ((data[pos] << 24) & 0xFF000000)
169 | ((data[pos + 1] << 16) & 0xFF0000)
170 | ((data[pos + 2] << 8) & 0xFF00) | ((data[pos + 3] & 0xFF));
171 time_t t = timestamp;
172 pos += 4;
173
174 if (VERBOSENOISE (handle)(handle->verbose & (1<<1)))
175 printf ("keytab timestamp %s (0x%08x)\n",
176 shishi_generalize_time (handle, timestamp), timestamp);
177
178 shishi_key_timestamp_set (key, t);
179 }
180
181 /* keyvno8 */
182 {
183 uint8_t vno8 = data[pos++];
184
185 if (VERBOSENOISE (handle)(handle->verbose & (1<<1)))
186 printf ("keytab kvno8 %d (0x%02x)\n", vno8, vno8);
187
188 shishi_key_version_set (key, vno8);
189 }
190
191 /* key, keytype */
192 {
193 uint32_t keytype = data[pos] << 8 | data[pos + 1];
194 pos += 2;
195
196 if (VERBOSENOISE (handle)(handle->verbose & (1<<1)))
197 printf ("keytab keytype %" PRIu32"u" " (0x%x)\n", keytype, keytype);
198
199 shishi_key_type_set (key, keytype);
200 }
201
202 /* key, length and data */
203 {
204 uint16_t keylen = data[pos] << 8 | data[pos + 1];
205 pos += 2;
206
207 if (VERBOSENOISE (handle)(handle->verbose & (1<<1)))
208 printf ("keytab keylen %d (0x%x) eq? %zu\n", keylen, keylen,
209 shishi_key_length (key));
210
211 if (VERBOSENOISE (handle)(handle->verbose & (1<<1)))
212 _shishi_hexprint (data + pos, keylen);
213
214 shishi_key_value_set (key, data + pos);
215 pos += keylen;
216 }
217
218 if (pos - entrystartpos < (size_t) size + 4)
219 {
220 uint32_t vno /* only present if >= 4 bytes left in entry */
221 = data[pos] << 24 | data[pos + 1] << 16
222 | data[pos + 2] << 8 | data[pos + 3];
223 pos += 4;
Value stored to 'pos' is never read
224
225 if (VERBOSENOISE (handle)(handle->verbose & (1<<1)))
226 printf ("keytab kvno %" PRIu32"u" " (0x%08x)\n", vno, vno);
227
228 shishi_key_version_set (key, vno);
229 }
230
231 if (VERBOSECRYPTONOISE (handle)(handle->verbose & (1<<4)))
232 shishi_key_print (handle, stdoutstdout, key);
233
234 rc = shishi_keys_add (keys, key);
235 if (rc != SHISHI_OK)
236 goto done;
237
238 /* Go to next entry... */
239 entrystartpos += size + 4;
240 }
241
242 rc = SHISHI_OK;
243
244done:
245 shishi_key_done (key);
246
247 return rc;
248}
249
250/**
251 * shishi_keys_add_keytab_file:
252 * @handle: shishi handle as allocated by shishi_init().
253 * @filename: name of file to read.
254 * @keys: allocated key set to store keys in.
255 *
256 * Read keys from a MIT keytab data structure from a file, and add the
257 * keys to the key set.
258 *
259 * The format of keytab's is proprietary, and this function support
260 * the 0x0501 and 0x0502 formats. See the section The MIT Kerberos
261 * Keytab Binary File Format in the Shishi manual for a description of
262 * the reverse-engineered format.
263 *
264 * Returns: Returns %SHISHI_IO_ERROR if the file cannot be read,
265 * %SHISHI_KEYTAB_ERROR if the data cannot be parsed as a valid keytab
266 * structure, and %SHISHI_OK on success.
267 **/
268int
269shishi_keys_add_keytab_file (Shishi * handle,
270 const char *filename, Shishi_keys * keys)
271{
272 size_t len;
273 char *keytab = read_file (filename, RF_BINARY0x1, &len);
274 int rc;
275
276 if (!keytab)
277 return SHISHI_IO_ERROR;
278
279 rc = shishi_keys_add_keytab_mem (handle, keytab, len, keys);
280
281 free (keytab);
282
283 return rc;
284}
285
286/**
287 * shishi_keys_from_keytab_mem:
288 * @handle: shishi handle as allocated by shishi_init().
289 * @data: constant memory buffer with keytab of @len size.
290 * @len: size of memory buffer with keytab data.
291 * @outkeys: pointer to key set that will be allocated and populated,
292 * must be deallocated by caller on succes.
293 *
294 * Create a new key set populated with keys from a MIT keytab data
295 * structure read from a memory block.
296 *
297 * The format of keytab's is proprietary, and this function support
298 * the 0x0501 and 0x0502 formats. See the section The MIT Kerberos
299 * Keytab Binary File Format in the Shishi manual for a description of
300 * the reverse-engineered format.
301 *
302 * Returns: Returns %SHISHI_KEYTAB_ERROR if the data does not
303 * represent a valid keytab structure, and %SHISHI_OK on success.
304 **/
305int
306shishi_keys_from_keytab_mem (Shishi * handle,
307 const char *data, size_t len,
308 Shishi_keys ** outkeys)
309{
310 int rc;
311
312 rc = shishi_keys (handle, outkeys);
313 if (rc != SHISHI_OK)
314 return rc;
315
316 rc = shishi_keys_add_keytab_mem (handle, data, len, *outkeys);
317 if (rc != SHISHI_OK)
318 {
319 shishi_keys_done (outkeys);
320 return rc;
321 }
322
323 return SHISHI_OK;
324}
325
326/**
327 * shishi_keys_from_keytab_file:
328 * @handle: shishi handle as allocated by shishi_init().
329 * @filename: name of file to read.
330 * @outkeys: pointer to key set that will be allocated and populated,
331 * must be deallocated by caller on succes.
332 *
333 * Create a new key set populated with keys from a MIT keytab data
334 * structure read from a file.
335 *
336 * The format of keytab's is proprietary, and this function support
337 * the 0x0501 and 0x0502 formats. See the section The MIT Kerberos
338 * Keytab Binary File Format in the Shishi manual for a description of
339 * the reverse-engineered format.
340 *
341 * Returns: Returns %SHISHI_IO_ERROR if the file cannot be read,
342 * %SHISHI_KEYTAB_ERROR if the data cannot be parsed as a valid keytab
343 * structure, and %SHISHI_OK on success.
344 **/
345int
346shishi_keys_from_keytab_file (Shishi * handle,
347 const char *filename, Shishi_keys ** outkeys)
348{
349 int rc;
350
351 rc = shishi_keys (handle, outkeys);
352 if (rc != SHISHI_OK)
353 return rc;
354
355 rc = shishi_keys_add_keytab_file (handle, filename, *outkeys);
356 if (rc != SHISHI_OK)
357 {
358 shishi_keys_done (outkeys);
359 return rc;
360 }
361
362 return SHISHI_OK;
363}
364
365static int
366key_to_keytab_entry (Shishi * handle,
367 const Shishi_key * key, char **out, size_t *len)
368{
369 uint16_t num_components = 0;
370 const char *realm = shishi_key_realm (key);
371 size_t realmlen = strlen (realm);
372 const char *principal = shishi_key_principal (key);
373 uint32_t name_type = SHISHI_NT_PRINCIPAL;
374 time_t timestamp = shishi_key_timestamp (key);
375 uint32_t version = shishi_key_version (key);
376 uint16_t key_type = shishi_key_type (key);
377 size_t key_length = shishi_key_length (key);
378 const char *key_value = shishi_key_value (key);
379 char *tmpname;
380 const char **namebuf;
381 char *tokptr = NULL((void*)0);
382 char *p;
383 size_t i;
384
385 if (realmlen > UINT16_MAX(65535))
386 return SHISHI_KEYTAB_ERROR;
387
388 if (key_length > UINT16_MAX(65535))
389 return SHISHI_KEYTAB_ERROR;
390
391 /* Reserve room for size, num_components, realm.length, realm,
392 name_type, timestamp, vno8, keyblock.type, keyblock.data.length,
393 keyblock.data, and version. */
394 *len = 4 + 2 + 2 + realmlen + 4 + 4 + 1 + 2 + 2 + key_length + 4;
395
396 tmpname = xstrdup (principal);
397 namebuf = xmalloc (sizeof (*namebuf));
398 for (num_components = 0; (namebuf[num_components] =
399 strtok_r (num_components == 0 ? tmpname
400 : NULL((void*)0), "/", &tokptr));
401 num_components++)
402 {
403 size_t length = strlen (namebuf[num_components]);
404
405 if (length > UINT16_MAX(65535))
406 return SHISHI_KEYTAB_ERROR;
407 *len += 2 + length;
408
409 namebuf = xrealloc (namebuf, (num_components + 2) * sizeof (*namebuf));
410 }
411
412 *out = xmalloc (*len);
413 p = *out;
414
415 /* Write size. */
416 p[0] = ((*len - 4) >> 24) & 0xFF;
417 p[1] = ((*len - 4) >> 16) & 0xFF;
418 p[2] = ((*len - 4) >> 8) & 0xFF;
419 p[3] = (*len - 4) & 0xFF;
420 p += 4;
421
422 /* Write num_components. */
423 p[0] = (num_components >> 8) & 0xFF;
424 p[1] = num_components & 0xFF;
425 p += 2;
426
427 /* Write realm.length and realm.data. */
428 p[0] = (realmlen >> 8) & 0xFF;
429 p[1] = realmlen & 0xFF;
430 p += 2;
431 memcpy (p, realm, realmlen);
432 p += realmlen;
433
434 for (i = 0; i < num_components; i++)
435 {
436 uint16_t length = strlen (namebuf[i]);
437 p[0] = (length >> 8) & 0xFF;
438 p[1] = length & 0xFF;
439 p += 2;
440 memcpy (p, namebuf[i], length);
441 p += length;
442 }
443
444 /* Name type */
445 p[0] = (name_type >> 24) & 0xFF;
446 p[1] = (name_type >> 16) & 0xFF;
447 p[2] = (name_type >> 8) & 0xFF;
448 p[3] = name_type & 0xFF;
449 p += 4;
450
451 /* Timestamp */
452 p[0] = (timestamp >> 24) & 0xFF;
453 p[1] = (timestamp >> 16) & 0xFF;
454 p[2] = (timestamp >> 8) & 0xFF;
455 p[3] = timestamp & 0xFF;
456 p += 4;
457
458 /* Version */
459 if (version < 256)
460 p[0] = version & 0xFF;
461 else
462 p[0] = 0; /* use vno */
463 p += 1;
464
465 /* Key */
466 p[0] = (key_type >> 8) & 0xFF;
467 p[1] = key_type & 0xFF;
468 p += 2;
469
470 p[0] = (key_length >> 8) & 0xFF;
471 p[1] = key_length & 0xFF;
472 p += 2;
473 memcpy (p, key_value, key_length);
474 p += key_length;
475
476 /* Version */
477 p[0] = (version >> 24) & 0xFF;
478 p[1] = (version >> 16) & 0xFF;
479 p[2] = (version >> 8) & 0xFF;
480 p[3] = version & 0xFF;
481
482 free (tmpname);
483 free (namebuf);
484
485 return SHISHI_OK;
486}
487
488/**
489 * shishi_keys_to_keytab_mem:
490 * @handle: shishi handle as allocated by shishi_init().
491 * @keys: key set to convert to keytab format.
492 * @out: constant memory buffer with keytab of @len size.
493 * @len: size of memory buffer with keytab data.
494 *
495 * Write keys to a MIT keytab data structure.
496 *
497 * The format of keytab's is proprietary, and this function writes the
498 * 0x0502 format. See the section The MIT Kerberos Keytab Binary File
499 * Format in the Shishi manual for a description of the
500 * reverse-engineered format.
501 *
502 * Returns: On success %SHISHI_OK is returned, otherwise an error
503 * code.
504 *
505 * Since: 0.0.42
506 **/
507int
508shishi_keys_to_keytab_mem (Shishi * handle,
509 Shishi_keys * keys, char **out, size_t *len)
510{
511 int rc;
512 const Shishi_key *key;
513 int keyno = 0;
514
515 *out = xmalloc (2);
516 *len = 2;
517
518 /* Write file format version. */
519 (*out)[0] = '\x05';
520 (*out)[1] = '\x02';
521
522 while ((key = shishi_keys_nth (keys, keyno++)) != NULL((void*)0))
523 {
524 char *tmp = NULL((void*)0);
525 size_t tmplen = 0;
526
527 rc = key_to_keytab_entry (handle, key, &tmp, &tmplen);
528 if (rc != SHISHI_OK)
529 {
530 free (*out);
531 return rc;
532 }
533
534 *out = xrealloc (*out, *len + tmplen);
535 memcpy (*out + *len, tmp, tmplen);
536 *len += tmplen;
537 free (tmp);
538 }
539
540 if (VERBOSENOISE (handle)(handle->verbose & (1<<1)))
541 {
542 printf ("keys_to_keytab len %zu (0x%zx)\n", *len, *len);
543 _shishi_hexprint (*out, *len);
544 }
545
546 return rc;
547}
548
549static int
550write_binary_file (const char *filename, const char *data, size_t length)
551{
552 FILE *fh;
553 size_t written;
554
555 fh = fopen (filename, "wb");
556 if (!fh)
557 return SHISHI_FOPEN_ERROR;
558
559 written = fwrite (data, 1, length, fh);
560 if (written != length)
561 return SHISHI_IO_ERROR;
562
563 return SHISHI_OK;
564}
565
566/**
567 * shishi_keys_to_keytab_file:
568 * @handle: shishi handle as allocated by shishi_init().
569 * @keys: keyset to write.
570 * @filename: name of file to write.
571 *
572 * Write keys to a MIT keytab data structure.
573 *
574 * The format of keytab's is proprietary, and this function writes the
575 * 0x0502 format. See the section The MIT Kerberos Keytab Binary File
576 * Format in the Shishi manual for a description of the
577 * reverse-engineered format.
578 *
579 * Returns: %SHISHI_FOPEN_ERROR if there is a problem opening
580 * @filename for writing, %SHISHI_IO_ERROR if there is problem
581 * writing the file, and %SHISHI_OK on success.
582 *
583 * Since: 0.0.42
584 **/
585int
586shishi_keys_to_keytab_file (Shishi * handle,
587 Shishi_keys * keys, const char *filename)
588{
589 int rc;
590 char *data;
591 size_t len;
592
593 rc = shishi_keys_to_keytab_mem (handle, keys, &data, &len);
594 if (rc != SHISHI_OK)
595 return rc;
596
597 rc = write_binary_file (filename, data, len);
598 if (rc != SHISHI_OK)
599 return rc;
600
601 return SHISHI_OK;
602}