krb5 commit: Implement 32-bit keytab kvno extension
Greg Hudson
ghudson at mit.edu
Wed Apr 15 00:40:39 EDT 2015
https://github.com/krb5/krb5/commit/54b4ccf510b67140caec76b12fff4b30462e7e50
commit 54b4ccf510b67140caec76b12fff4b30462e7e50
Author: Greg Hudson <ghudson at mit.edu>
Date: Wed Mar 4 14:43:00 2015 -0500
Implement 32-bit keytab kvno extension
Heimdal and Shishi support a 32-bit kvno at the end of a keytab entry,
overriding the 8-bit version if present. Implement this in the FILE
keytab type and document it in keytab_file_format.rst.
ticket: 7532
doc/formats/keytab_file_format.rst | 10 +++++-----
src/lib/krb5/keytab/kt_file.c | 26 +++++++++++++++++++++++++-
2 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/doc/formats/keytab_file_format.rst b/doc/formats/keytab_file_format.rst
index 10caf95..92f3733 100644
--- a/doc/formats/keytab_file_format.rst
+++ b/doc/formats/keytab_file_format.rst
@@ -31,6 +31,7 @@ the key entry. Key entries use the following informal grammar::
enctype (16 bits)
key length (32 bits)
key contents
+ key version (32 bits) [in release 1.14 and later]
principal ::=
count of components (32 bits) [includes realm in version 1]
@@ -44,8 +45,7 @@ the key entry. Key entries use the following informal grammar::
length (16 bits)
value (length bytes)
-Some implementations of Kerberos recognize a 32-bit key version at the
-end of an entry, if the record length is at least 4 bytes longer than
-the entry and the value of those 32 bits is not 0. If present, this
-key version supersedes the 8-bit key version. MIT krb5 does not yet
-implement this extension.
+The 32-bit key version overrides the 8-bit key version. To determine
+if it is present, the implementation must check that at least 4 bytes
+remain in the record after the other fields are read, and that the
+value of the 32-bit integer contained in those bytes is non-zero.
diff --git a/src/lib/krb5/keytab/kt_file.c b/src/lib/krb5/keytab/kt_file.c
index 722ebe6..a54a06b 100644
--- a/src/lib/krb5/keytab/kt_file.c
+++ b/src/lib/krb5/keytab/kt_file.c
@@ -1185,10 +1185,11 @@ krb5_ktfileint_internal_read_entry(krb5_context context, krb5_keytab id, krb5_ke
krb5_int16 princ_size;
register int i;
krb5_int32 size;
- krb5_int32 start_pos;
+ krb5_int32 start_pos, pos;
krb5_error_code error;
char *tmpdata;
krb5_data *princ;
+ uint32_t vno32;
KTCHECKLOCK(id);
memset(ret_entry, 0, sizeof(krb5_keytab_entry));
@@ -1367,6 +1368,20 @@ krb5_ktfileint_internal_read_entry(krb5_context context, krb5_keytab id, krb5_ke
goto fail;
}
+ /* Check for a 32-bit kvno extension if four or more bytes remain. */
+ pos = ftell(KTFILEP(id));
+ if (pos - start_pos + 4 <= size) {
+ if (!fread(&vno32, sizeof(vno32), 1, KTFILEP(id))) {
+ error = KRB5_KT_END;
+ goto fail;
+ }
+ if (KTVERSION(id) != KRB5_KT_VNO_1)
+ vno32 = ntohl(vno32);
+ /* If the value is 0, the bytes are just zero-fill. */
+ if (vno32)
+ ret_entry->vno = vno32;
+ }
+
/*
* Reposition file pointer to the next inter-record length field.
*/
@@ -1406,6 +1421,7 @@ krb5_ktfileint_write_entry(krb5_context context, krb5_keytab id, krb5_keytab_ent
krb5_int32 princ_type;
krb5_int32 size_needed;
krb5_int32 commit_point = -1;
+ uint32_t vno32;
int i;
KTCHECKLOCK(id);
@@ -1508,6 +1524,13 @@ krb5_ktfileint_write_entry(krb5_context context, krb5_keytab id, krb5_keytab_ent
goto abend;
}
+ /* 32-bit key version number */
+ vno32 = entry->vno;
+ if (KTVERSION(id) != KRB5_KT_VNO_1)
+ vno32 = htonl(vno32);
+ if (!fwrite(&vno32, sizeof(vno32), 1, KTFILEP(id)))
+ goto abend;
+
if (fflush(KTFILEP(id)))
goto abend;
@@ -1556,6 +1579,7 @@ krb5_ktfileint_size_entry(krb5_context context, krb5_keytab_entry *entry, krb5_i
total_size += sizeof(krb5_octet);
total_size += sizeof(krb5_int16);
total_size += sizeof(krb5_int16) + entry->key.length;
+ total_size += sizeof(uint32_t);
*size_needed = total_size;
return retval;
More information about the cvs-krb5
mailing list