1 /* keytab.c --- Read MIT style Kerberos hostkey files.
2 * Copyright (C) 2006, 2007 Simon Josefsson
4 * This file is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation; either version 2 of the License,
7 * or (at your option) any later version.
9 * This file is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this file; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 /* See keytab.txt for a description of the file format.
28 get_uint8 (const char **data
, size_t * len
, uint8_t * i
)
30 const char *p
= *data
;
40 get_uint16 (const char **data
, size_t * len
, uint16_t * i
)
42 const char *p
= *data
;
45 *i
= p
[0] << 8 | p
[1];
52 get_uint32 (const char **data
, size_t * len
, uint32_t * i
)
54 const char *p
= *data
;
57 *i
= ((p
[0] << 24) & 0xFF000000)
58 | ((p
[1] << 16) & 0xFF0000) | ((p
[2] << 8) & 0xFF00) | (p
[3] & 0xFF);
65 parse_principal (const char **data
, size_t * len
,
66 struct keytab_principal
*out
)
71 rc
= get_uint16 (data
, len
, &out
->num_components
);
75 if (out
->num_components
>= KEYTAB_MAX_COMPONENTS
)
78 rc
= get_uint16 (data
, len
, &out
->realm
.length
);
82 if (*len
< out
->realm
.length
)
84 out
->realm
.data
= *data
;
85 *data
+= out
->realm
.length
;
86 *len
-= out
->realm
.length
;
88 /* Make sure realm will be zero terminated. This limits the initial
89 component length to 2^24 bytes. */
90 if (!*len
|| **(char**)data
!= '\0')
93 for (n
= 0; n
< out
->num_components
; n
++)
95 rc
= get_uint16 (data
, len
, &out
->components
[n
].length
);
99 if (*len
< out
->components
[n
].length
)
101 out
->components
[n
].data
= *data
;
102 *data
+= out
->components
[n
].length
;
103 *len
-= out
->components
[n
].length
;
105 /* Make sure component is zero terminated. This limits the name
106 type to values below 2^24. */
107 if (!*len
|| **(char**)data
!= '\0')
111 rc
= get_uint32 (data
, len
, &out
->name_type
);
119 parse_entry (const char **data
, size_t * len
,
120 struct keytab_entry
*out
)
122 struct keytab_principal princ
;
123 uint32_t num_address
;
124 uint32_t num_authdata
;
128 rc
= get_uint32 (data
, len
, &size
);
139 rc
= parse_principal (data
, &size
, &out
->name
);
143 rc
= get_uint32 (data
, &size
, &out
->timestamp
);
147 rc
= get_uint8 (data
, &size
, &out
->key
.vno8
);
151 rc
= get_uint16 (data
, &size
, &out
->key
.type
);
155 rc
= get_uint16 (data
, &size
, &out
->key
.keylen
);
159 if (size
< out
->key
.keylen
)
162 out
->key
.keyvalue
= *data
;
164 *data
+= out
->key
.keylen
;
165 size
-= out
->key
.keylen
;
169 rc
= get_uint32 (data
, &size
, &out
->key
.vno
);
183 keytab_parse (const char *data
, size_t len
, struct keytab
*out
)
189 rc
= get_uint16 (&data
, &len
, &out
->file_format_version
);
194 out
->keytabslen
= len
;
196 /* Validate size integrity of file. */
199 rc
= get_uint32 (&data
, &len
, &size
);
215 keytab_parse_entry (const char *data
, size_t len
,
216 struct keytab_entry
*out
, size_t * n
)
218 size_t savelen
= len
;
219 int rc
= parse_entry (&data
, &len
, out
);
228 #if defined (TEST) || defined (ENABLE_PRINT)
230 keytab_print (struct keytab
*keytab
)
234 printf ("file_format_version %04x\n", keytab
->file_format_version
);
238 keytab_print_principal (struct keytab_principal
*princ
)
242 printf ("\tnum_components %04x\n", princ
->num_components
);
243 printf ("\trealmlen %04x\n", princ
->realm
.length
);
244 printf ("\trealm %.*s\n", princ
->realm
.length
, princ
->realm
.data
);
246 for (n
= 0; n
< princ
->num_components
; n
++)
248 printf ("\t\tcomponentlen %04x\n", princ
->components
[n
].length
);
249 printf ("\t\tcomponent %.*s\n", princ
->components
[n
].length
,
250 princ
->components
[n
].data
);
252 printf ("\tname_type %04x\n", princ
->name_type
);
256 keytab_print_entry (struct keytab_entry
*keytab
)
259 printf ("\tsize %04x\n", keytab
->size
);
260 printf ("\tnum_components %04x\n", keytab
->num_components
);
261 keytab_print_principal (&keytab
->name
);
263 printf ("\t\tvno8 %04x\n", keytab
->key
.vno8
);
264 printf ("\t\tkeytype %04x\n", keytab
->key
.type
);
265 printf ("\t\tkeylen %04x\n", keytab
->key
.keylen
);
266 printf ("\t\tkey value: ");
267 for (i
= 0; i
< keytab
->key
.keylen
; i
++)
268 printf ("%02x", ((char *) keytab
->key
.keyvalue
)[i
] & 0xFF);
270 if (keytab
->key
.vno
!= -1)
271 printf ("\t\tvno %04x\n", keytab
->key
.vno
);
277 main (int argc
, char *argv
[])
283 struct keytab keytab
;
284 struct keytab_entry entry
;
289 printf ("Usage: %s <krb5keytab-file>\n", argv
[0]);
293 fh
= fopen (argv
[1], "rb");
296 puts ("Error: cannot open file");
300 len
= fread (buf
, 1, sizeof (buf
), fh
);
302 if (len
>= sizeof (buf
))
304 puts ("Error: file too large");
308 rc
= keytab_parse (buf
, len
, &keytab
);
311 puts ("Error: syntax error");
315 keytab_print (&keytab
);
317 while (keytab
.keytabslen
)
321 rc
= keytab_parse_entry (keytab
.keytabs
,
322 keytab
.keytabslen
, &entry
, &n
);
325 printf ("Error: cannot parse credential %d\n", i
);
329 printf ("\nCredential %d:\n", i
++);
331 keytab_print_entry (&entry
);
334 keytab
.keytabslen
-= n
;
339 puts ("Error: cannot close file");