diff --git a/services/univention-s4-connector/debian/changelog b/services/univention-s4-connector/debian/changelog index 9d4c694664..ea699fc08a 100644 --- a/services/univention-s4-connector/debian/changelog +++ b/services/univention-s4-connector/debian/changelog @@ -1,3 +1,10 @@ +univention-s4-connector (12.0.2-2) unstable; urgency=medium + + * Bug #46292: Avoid segfault on krb5Key with unsupported + Kerberos encryption type + + -- Arvid Requate Fri, 16 Feb 2018 13:06:44 +0100 + univention-s4-connector (12.0.2-1) unstable; urgency=medium * Bug #32014: Sync account locking *state* from Samba/AD to OpenLDAP: diff --git a/services/univention-s4-connector/modules/univention/s4connector/s4/password.py b/services/univention-s4-connector/modules/univention/s4connector/s4/password.py index b4d5d1bda9..0622a89d4d 100644 --- a/services/univention-s4-connector/modules/univention/s4connector/s4/password.py +++ b/services/univention-s4-connector/modules/univention/s4connector/s4/password.py @@ -46,6 +46,13 @@ import heimdal from ldap.controls import LDAPControl import traceback +class Krb5Context(object): + def __init__(self): + self.ctx = heimdal.context() + self.etypes = self.ctx.get_permitted_enctypes() + self.etype_ids = [et.toint() for et in self.etypes] + +krb5_context = Krb5Context() def calculate_krb5key(unicodePwd, supplementalCredentials, kvno=0): up_blob = unicodePwd @@ -168,11 +175,14 @@ def calculate_supplementalCredentials(ucs_krb5key, old_supplementalCredentials): krb_ctr4_salt = '' for k in ucs_krb5key: (keyblock, salt, kvno) = heimdal.asn1_decode_key(k) - key_data = keyblock.keyvalue() saltstring = salt.saltvalue() enctype = keyblock.keytype() enctype_id = enctype.toint() + if enctype_id not in krb5_context.etype_ids: + ud.debug(ud.LDAP, ud.WARN, "calculate_supplementalCredentials: ignoring unsupported krb5_keytype: (%d)" % (enctype_id,)) + continue + ud.debug(ud.LDAP, ud.INFO, "calculate_supplementalCredentials: krb5_keytype: %s (%d)" % (enctype, enctype_id)) if enctype_id == 18: krb5_aes256 = key_data diff --git a/services/univention-samba4/debian/changelog b/services/univention-samba4/debian/changelog index 8eda77ec8f..848ecb120b 100644 --- a/services/univention-samba4/debian/changelog +++ b/services/univention-samba4/debian/changelog @@ -1,3 +1,10 @@ +univention-samba4 (7.0.2-3) unstable; urgency=medium + + * Bug #46292: Avoid s4search-decode segfault on krb5Key with unsupported + Kerberos encryption type + + -- Arvid Requate Fri, 16 Feb 2018 12:57:40 +0100 + univention-samba4 (7.0.2-2) unstable; urgency=medium * Bug #46118: Bump version for rebuild in 4.3-0 main branch diff --git a/services/univention-samba4/s4search-decode b/services/univention-samba4/s4search-decode index 68ae51c699..a782d0cc56 100755 --- a/services/univention-samba4/s4search-decode +++ b/services/univention-samba4/s4search-decode @@ -47,7 +47,13 @@ from samba.ndr import ndr_unpack from samba.ndr import ndr_print from datetime import datetime -context = None +krb5_context = None + +class Krb5Context(object): + def __init__(self): + self.ctx = heimdal.context() + self.etypes = self.ctx.get_permitted_enctypes() + self.etype_ids = [et.toint() for et in self.etypes] keytypes = { 1: 'des_crc', @@ -58,13 +64,12 @@ keytypes = { regEx = re.compile('^([a-zA-Z0-9-]*):?: (.*)') - def decode_unicodePwd(value, kvno=0): - global context - if not context: - context = heimdal.context() + global krb5_context + if not krb5_context: + krb5_context = Krb5Context() up_blob = binascii.a2b_base64(value) - keyblock = heimdal.keyblock_raw(context, 23, up_blob) + keyblock = heimdal.keyblock_raw(krb5_context.ctx, 23, up_blob) krb5key = heimdal.asn1_encode_key(keyblock, None, kvno) print "# decoded:" print "#\tsambaNTPassword:: %s" % binascii.b2a_hex(up_blob).upper().strip() @@ -74,10 +79,16 @@ def decode_unicodePwd(value, kvno=0): def decode_krb5Key(value): + global krb5_context + if not krb5_context: + krb5_context = Krb5Context() k = binascii.a2b_base64(value) (keyblock, salt, kvno) = heimdal.asn1_decode_key(k) enctype = keyblock.keytype() enctype_id = enctype.toint() + if enctype_id not in krb5_context.etype_ids: + print "#\tSKIPPING ENC type %s, not support by this Heimdal version" % enctype_id + return print "#\tkrb5_keytype: %s (%d)" % (enctype, enctype_id) key_data = keyblock.keyvalue() print "#\tkeyblock: ", binascii.b2a_base64(key_data).strip() @@ -88,9 +99,9 @@ def decode_krb5Key(value): def decode_supplementalCredentials(value, kvno=0): - global context - if not context: - context = heimdal.context() + global krb5_context + if not krb5_context: + krb5_context = Krb5Context() object_data = ndr_unpack(drsblobs.supplementalCredentialsBlob, binascii.a2b_base64(value)) print "# supplementalCredentials recoded as krb5key:" # print "%s" % (ndr_print(object_data).strip(),) @@ -107,11 +118,11 @@ def decode_supplementalCredentials(value, kvno=0): keytype = keytypes.get(k.keytype, k.keytype) print "#\tkeytype: %s (%d)" % (keytype, k.keytype) print "#\tkeyblock:", - keyblock = heimdal.keyblock_raw(context, k.keytype, k.value) + keyblock = heimdal.keyblock_raw(krb5_context.ctx, k.keytype, k.value) key_data = keyblock.keyvalue() print binascii.b2a_base64(key_data).strip() print "#\tkrb5SaltObject:", - krb5SaltObject = heimdal.salt_raw(context, krb.ctr.salt.string) + krb5SaltObject = heimdal.salt_raw(krb5_context.ctx, krb.ctr.salt.string) print krb5SaltObject.saltvalue() krb5key = heimdal.asn1_encode_key(keyblock, krb5SaltObject, kvno) print "#\tkrb5Key:: %s" % binascii.b2a_base64(krb5key).strip()