[PATCHES] limit kerberos encryption types used by winbindd

Uri Simchoni uri at samba.org
Sat Aug 6 17:20:55 UTC 2016


On 08/04/2016 09:52 PM, Jeremy Allison wrote:
> 
> Uri - In trying to push this I'm getting:
> 
> [1616(10428)/1954 at 1h52m16s] samba4.blackbox.client_etypes_all(ad_dc:client)
> UNEXPECTED(failure): samba4.blackbox.client_etypes_all(ad_dc:client).verify types(ad_dc:client)
> REASON: Exception: Exception:
> 
> FAILED (1 failures, 0 errors and 0 unexpected successes in 0 testsuites)
> 
> which does seem related even with the latest autobuild mess.
> 
> Can you investigate please ?
> 
> Cheers,
> 
> 	Jeremy.
> 

Older version of tshark. The wireshark Kerberos dissector was replaced
in commit dea68bf0.

I hope those are the only two versions of wireshark Kerberos dissector
in use and that the dissector output will be stable enough...

The attached patch set only modifies the tshark line in the test. Passes
autobuild-private.sh on sn-devel and locally on my machine.

Thanks,
Uri.
-------------- next part --------------
From 57009368e8a0fbd7eb79029b8f45fbad7d45ccc7 Mon Sep 17 00:00:00 2001
From: Uri Simchoni <uri at samba.org>
Date: Sun, 8 May 2016 15:45:44 +0300
Subject: [PATCH v3 1/4] s3-param: add kerberos encryption types parameter

Signed-off-by: Uri Simchoni <uri at samba.org>
---
 .../security/kerberosencryptiontypes.xml           | 53 ++++++++++++++++++++++
 lib/param/loadparm.c                               |  2 +
 lib/param/loadparm.h                               |  4 ++
 lib/param/param_table.c                            |  9 ++++
 4 files changed, 68 insertions(+)
 create mode 100644 docs-xml/smbdotconf/security/kerberosencryptiontypes.xml

diff --git a/docs-xml/smbdotconf/security/kerberosencryptiontypes.xml b/docs-xml/smbdotconf/security/kerberosencryptiontypes.xml
new file mode 100644
index 0000000..b19a8a8
--- /dev/null
+++ b/docs-xml/smbdotconf/security/kerberosencryptiontypes.xml
@@ -0,0 +1,53 @@
+<samba:parameter name="kerberos encryption types"
+                 context="G"
+                 type="enum"
+		 enumlist="enum_kerberos_encryption_types_vals"
+                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+<description>
+    <para>This parameter determines the encryption types to use when operating
+    as a Kerberos client. Possible values are <emphasis>all</emphasis>,
+    <emphasis>strong</emphasis>, and <emphasis>legacy</emphasis>.
+    </para>
+
+    <para>Samba uses a Kerberos library (MIT or Heimdal) to obtain Kerberos
+    tickets. This library is normally configured outside of Samba, using
+    the krb5.conf file. This file may also include directives to configure
+    the encryption types to be used. However, Samba implements Active Directory
+    protocols and algorithms to locate a domain controller. In order to
+    force the Kerberos library into using the correct domain controller,
+    some Samba processes, such as
+    <citerefentry><refentrytitle>winbindd</refentrytitle>
+    <manvolnum>8</manvolnum></citerefentry> and
+    <citerefentry><refentrytitle>net</refentrytitle>
+    <manvolnum>8</manvolnum></citerefentry>, build a private krb5.conf
+    file for use by the Kerberos library while being invoked from Samba.
+    This private file controls all aspects of the Kerberos library operation,
+    and this parameter controls how the encryption types are configured
+    within this generated file, and therefore also controls the encryption
+    types negotiable by Samba.
+    </para>
+
+    <para>When set to <constant>all</constant>, all active directory
+    encryption types are allowed.
+    </para>
+
+    <para>When set to <constant>strong</constant>, only AES-based encyption
+    types are offered. This can be used in hardened environments to prevent
+    downgrade attacks.
+    </para>
+
+    <para>When set to <constant>legacy</constant>, only RC4-HMAC-MD5
+    is allowed. Avoiding AES this way has one a very specific use.
+    Normally, the encryption type is negotiated between the peers.
+    However, there is one scenario in which a Windows read-only domain
+    controller (RODC) advertises AES encryption, but then proxies the
+    request to a writeable DC which may not support AES encryption,
+    leading to failure of the handshake. Setting this parameter to
+    <constant>legacy</constant> would cause samba not to negotiate AES
+    encryption. It is assumed of course that the weaker legacy
+    encryption types are acceptable for the setup.
+    </para>
+</description>
+
+<value type="default">all</value>
+</samba:parameter>
diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
index 5f4610e..6aa757f 100644
--- a/lib/param/loadparm.c
+++ b/lib/param/loadparm.c
@@ -2900,6 +2900,8 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
 
 	lpcfg_do_global_parameter(lp_ctx, "smb2 leases", "yes");
 
+	lpcfg_do_global_parameter(lp_ctx, "kerberos encryption types", "all");
+
 	/* Allow modules to adjust defaults */
 	for (defaults_hook = defaults_hooks; defaults_hook;
 		 defaults_hook = defaults_hook->next) {
diff --git a/lib/param/loadparm.h b/lib/param/loadparm.h
index aa256c1..d8f6975 100644
--- a/lib/param/loadparm.h
+++ b/lib/param/loadparm.h
@@ -178,6 +178,10 @@ struct file_lists {
 #define KERBEROS_VERIFY_DEDICATED_KEYTAB 2
 #define KERBEROS_VERIFY_SECRETS_AND_KEYTAB 3
 
+#define KERBEROS_ETYPES_ALL 0
+#define KERBEROS_ETYPES_STRONG 1
+#define KERBEROS_ETYPES_LEGACY 2
+
 /* ACL compatibility */
 enum acl_compatibility {ACL_COMPAT_AUTO, ACL_COMPAT_WINNT, ACL_COMPAT_WIN2K};
 
diff --git a/lib/param/param_table.c b/lib/param/param_table.c
index d8d9144..c8520d2 100644
--- a/lib/param/param_table.c
+++ b/lib/param/param_table.c
@@ -208,6 +208,15 @@ static const struct enum_list enum_kerberos_method[] = {
 	{-1, NULL}
 };
 
+/* Kerberos encryption types selection options */
+
+static const struct enum_list enum_kerberos_encryption_types_vals[] = {
+	{KERBEROS_ETYPES_ALL, "all"},
+	{KERBEROS_ETYPES_STRONG, "strong"},
+	{KERBEROS_ETYPES_LEGACY, "legacy"},
+	{-1, NULL}
+};
+
 static const struct enum_list enum_printing[] = {
 	{PRINT_SYSV, "sysv"},
 	{PRINT_AIX, "aix"},
-- 
2.5.5


From 439016168463e4a08c0377ac690fabe848cf6272 Mon Sep 17 00:00:00 2001
From: Uri Simchoni <uri at samba.org>
Date: Mon, 30 May 2016 21:21:41 +0300
Subject: [PATCH v3 2/4] libads: use "kerberos encryption types" parameter

When creating the custom krb.conf file, list etypes
according to kerberos encryption types

Also use proper directives for heimdal (heimdal recognizes
the MIT etype directives, but does not act upon them)

Signed-off-by: Uri Simchoni <uri at samba.org>
---
 source3/libads/kerberos.c | 106 ++++++++++++++++++++++++++++++++++------------
 1 file changed, 80 insertions(+), 26 deletions(-)

diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c
index 53407fa..a47ab6c 100644
--- a/source3/libads/kerberos.c
+++ b/source3/libads/kerberos.c
@@ -813,6 +813,76 @@ out:
  run as root or will fail (which is a good thing :-).
 ************************************************************************/
 
+#if !defined(SAMBA4_USES_HEIMDAL) /* MIT version */
+static char *get_enctypes(TALLOC_CTX *mem_ctx)
+{
+	char *aes_enctypes = NULL;
+	const char *legacy_enctypes = "";
+	char *enctypes = NULL;
+
+	aes_enctypes = talloc_strdup(mem_ctx, "");
+	if (aes_enctypes == NULL) {
+		goto done;
+	}
+
+	if (lp_kerberos_encryption_types() == KERBEROS_ETYPES_ALL ||
+	    lp_kerberos_encryption_types() == KERBEROS_ETYPES_STRONG) {
+#ifdef HAVE_ENCTYPE_AES256_CTS_HMAC_SHA1_96
+		aes_enctypes = talloc_asprintf_append(
+		    aes_enctypes, "%s", "aes256-cts-hmac-sha1-96 ");
+		if (aes_enctypes == NULL) {
+			goto done;
+		}
+#endif
+#ifdef HAVE_ENCTYPE_AES128_CTS_HMAC_SHA1_96
+		aes_enctypes = talloc_asprintf_append(
+		    aes_enctypes, "%s", "aes128-cts-hmac-sha1-96");
+		if (aes_enctypes == NULL) {
+			goto done;
+		}
+#endif
+	}
+
+	if (lp_kerberos_encryption_types() == KERBEROS_ETYPES_ALL ||
+	    lp_kerberos_encryption_types() == KERBEROS_ETYPES_LEGACY) {
+		legacy_enctypes = "RC4-HMAC DES-CBC-CRC DES-CBC-MD5";
+	}
+
+	enctypes =
+	    talloc_asprintf(mem_ctx, "\tdefault_tgs_enctypes = %s %s\n"
+				     "\tdefault_tkt_enctypes = %s %s\n"
+				     "\tpreferred_enctypes = %s %s\n",
+			    aes_enctypes, legacy_enctypes, aes_enctypes,
+			    legacy_enctypes, aes_enctypes, legacy_enctypes);
+done:
+	TALLOC_FREE(aes_enctypes);
+	return enctypes;
+}
+#else /* Heimdal version */
+static char *get_enctypes(TALLOC_CTX *mem_ctx)
+{
+	const char *aes_enctypes = "";
+	const char *legacy_enctypes = "";
+	char *enctypes = NULL;
+
+	if (lp_kerberos_encryption_types() == KERBEROS_ETYPES_ALL ||
+	    lp_kerberos_encryption_types() == KERBEROS_ETYPES_STRONG) {
+		aes_enctypes =
+		    "aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96";
+	}
+
+	if (lp_kerberos_encryption_types() == KERBEROS_ETYPES_ALL ||
+	    lp_kerberos_encryption_types() == KERBEROS_ETYPES_LEGACY) {
+		legacy_enctypes = "arcfour-hmac-md5 des-cbc-crc des-cbc-md5";
+	}
+
+	enctypes = talloc_asprintf(mem_ctx, "\tdefault_etypes = %s %s\n",
+				   aes_enctypes, legacy_enctypes);
+
+	return enctypes;
+}
+#endif
+
 bool create_local_private_krb5_conf_for_domain(const char *realm,
 						const char *domain,
 						const char *sitename,
@@ -828,7 +898,7 @@ bool create_local_private_krb5_conf_for_domain(const char *realm,
 	int fd;
 	char *realm_upper = NULL;
 	bool result = false;
-	char *aes_enctypes = NULL;
+	char *enctypes = NULL;
 	mode_t mask;
 
 	if (!lp_create_krb5_conf()) {
@@ -879,34 +949,18 @@ bool create_local_private_krb5_conf_for_domain(const char *realm,
 		goto done;
 	}
 
-	aes_enctypes = talloc_strdup(fname, "");
-	if (aes_enctypes == NULL) {
+	enctypes = get_enctypes(fname);
+	if (enctypes == NULL) {
 		goto done;
 	}
 
-#ifdef HAVE_ENCTYPE_AES256_CTS_HMAC_SHA1_96
-	aes_enctypes = talloc_asprintf_append(aes_enctypes, "%s", "aes256-cts-hmac-sha1-96 ");
-	if (aes_enctypes == NULL) {
-		goto done;
-	}
-#endif
-#ifdef HAVE_ENCTYPE_AES128_CTS_HMAC_SHA1_96
-	aes_enctypes = talloc_asprintf_append(aes_enctypes, "%s", "aes128-cts-hmac-sha1-96");
-	if (aes_enctypes == NULL) {
-		goto done;
-	}
-#endif
-
-	file_contents = talloc_asprintf(fname,
-					"[libdefaults]\n\tdefault_realm = %s\n"
-					"\tdefault_tgs_enctypes = %s RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n"
-					"\tdefault_tkt_enctypes = %s RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n"
-					"\tpreferred_enctypes = %s RC4-HMAC DES-CBC-CRC DES-CBC-MD5\n"
-					"\tdns_lookup_realm = false\n\n"
-					"[realms]\n\t%s = {\n"
-					"%s\t}\n",
-					realm_upper, aes_enctypes, aes_enctypes, aes_enctypes,
-					realm_upper, kdc_ip_string);
+	file_contents =
+	    talloc_asprintf(fname, "[libdefaults]\n\tdefault_realm = %s\n"
+				   "%s"
+				   "\tdns_lookup_realm = false\n\n"
+				   "[realms]\n\t%s = {\n"
+				   "%s\t}\n",
+			    realm_upper, enctypes, realm_upper, kdc_ip_string);
 
 	if (!file_contents) {
 		goto done;
-- 
2.5.5


From 70531bbd097878807b69e9d4b0d9ff1d20705b09 Mon Sep 17 00:00:00 2001
From: Uri Simchoni <uri at samba.org>
Date: Mon, 4 Jul 2016 09:50:33 +0300
Subject: [PATCH v3 3/4] heimdal: honor conf enctypes when obtaining a service
 ticket

This patch removes part of what's categorized in the code as
"hideous glue", which causes Heimdal to ignore krb5.conf
encryption types, and instead use either the application-
supplied values or the default compile-time values.

Signed-off-by: Uri Simchoni <uri at samba.org>
---
 source4/heimdal/lib/gssapi/krb5/init_sec_context.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
index 0a89ae1..efc4215 100644
--- a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
+++ b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c
@@ -427,15 +427,12 @@ init_auth
     /*
      * This is hideous glue for (NFS) clients that wants to limit the
      * available enctypes to what it can support (encryption in
-     * kernel). If there is no enctypes selected for this credential,
-     * reset it to the default set of enctypes.
+     * kernel).
      */
     {
-	krb5_enctype *enctypes = NULL;
-
-	if (cred && cred->enctypes)
-	    enctypes = cred->enctypes;
-	krb5_set_default_in_tkt_etypes(context, enctypes);
+	if (cred && cred->enctypes) {
+	    krb5_set_default_in_tkt_etypes(context, cred->enctypes);
+	}
     }
 
     /* canon name if needed for client + target realm */
-- 
2.5.5


From 00f387de884c78453dc922196041e694b3af1f47 Mon Sep 17 00:00:00 2001
From: Uri Simchoni <uri at samba.org>
Date: Tue, 5 Jul 2016 06:07:04 +0300
Subject: [PATCH v3 4/4] selftest: tests for kerberos encryption types

This test uses tshark and cwrap's packet capturing capability
to observe the Kerberos handshakes and ensure the correct
encryption types are being used.

Signed-off-by: Uri Simchoni <uri at samba.org>
---
 source4/selftest/tests.py                |  3 ++
 testprogs/blackbox/test_client_etypes.sh | 57 ++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)
 create mode 100755 testprogs/blackbox/test_client_etypes.sh

diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py
index e4af5f8..2619ecc 100755
--- a/source4/selftest/tests.py
+++ b/source4/selftest/tests.py
@@ -407,6 +407,9 @@ plantestsuite("samba4.blackbox.rfc2307_mapping(ad_dc_ntvfs:local)", "ad_dc_ntvfs
 plantestsuite("samba4.blackbox.chgdcpass", "chgdcpass", [os.path.join(bbdir, "test_chgdcpass.sh"), '$SERVER', "CHGDCPASS\$", '$REALM', '$DOMAIN', '$PREFIX', "aes256-cts-hmac-sha1-96", '$SELFTEST_PREFIX/chgdcpass', smbclient4])
 plantestsuite("samba4.blackbox.samba_upgradedns(chgdcpass:local)", "chgdcpass:local", [os.path.join(bbdir, "test_samba_upgradedns.sh"), '$SERVER', '$REALM', '$PREFIX', '$SELFTEST_PREFIX/chgdcpass'])
 plantestsuite("samba4.blackbox.net_ads(ad_dc:client)", "ad_dc:client", [os.path.join(bbdir, "test_net_ads.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX_ABS'])
+plantestsuite("samba4.blackbox.client_etypes_all(ad_dc:client)", "ad_dc:client", [os.path.join(bbdir, "test_client_etypes.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX_ABS', 'all', '17_18_23'])
+plantestsuite("samba4.blackbox.client_etypes_legacy(ad_dc:client)", "ad_dc:client", [os.path.join(bbdir, "test_client_etypes.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX_ABS', 'legacy', '23'])
+plantestsuite("samba4.blackbox.client_etypes_strong(ad_dc:client)", "ad_dc:client", [os.path.join(bbdir, "test_client_etypes.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$PREFIX_ABS', 'strong', '17_18'])
 plantestsuite("samba4.blackbox.net_ads_dns(ad_member:local)", "ad_member:local", [os.path.join(bbdir, "test_net_ads_dns.sh"), '$DC_SERVER', '$DC_USERNAME', '$DC_PASSWORD', '$REALM', '$USERNAME', '$PASSWORD'])
 plantestsuite_loadlist("samba4.rpc.echo against NetBIOS alias", "ad_dc_ntvfs", [valgrindify(smbtorture4), "$LISTOPT", "$LOADLIST", 'ncacn_np:$NETBIOSALIAS', '-U$DOMAIN/$USERNAME%$PASSWORD', 'rpc.echo'])
 
diff --git a/testprogs/blackbox/test_client_etypes.sh b/testprogs/blackbox/test_client_etypes.sh
new file mode 100755
index 0000000..0a9df9e
--- /dev/null
+++ b/testprogs/blackbox/test_client_etypes.sh
@@ -0,0 +1,57 @@
+if [ $# -lt 6 ]; then
+cat <<EOF
+Usage: test_client_etypes.sh DC_SERVER DC_USERNAME DC_PASSWORD PREFIX_ABS ETYPE_CONF EXPECTED
+EOF
+exit 1;
+fi
+
+#requires tshark
+which tshark > /dev/null 2>&1 || exit 0
+
+DC_SERVER=$1
+DC_USERNAME=$2
+DC_PASSWORD=$3
+BASEDIR=$4
+ETYPE_CONF=$5
+EXPECTED_ETYPES="$6"
+
+HOSTNAME=`dd if=/dev/urandom bs=1 count=32 2>/dev/null | sha1sum | cut -b 1-10`
+
+RUNDIR=`pwd`
+cd $BASEDIR
+WORKDIR=`mktemp -d -p .`
+WORKDIR=`basename $WORKDIR`
+cp -a client/* $WORKDIR/
+sed -ri "s@(dir|directory) = (.*)/client/@\1 = \2/$WORKDIR/@" $WORKDIR/client.conf
+sed -ri "s/netbios name = .*/netbios name = $HOSTNAME/" $WORKDIR/client.conf
+rm -f $WORKDIR/private/secrets.tdb
+cd $RUNDIR
+
+failed=0
+
+net_tool="$BINDIR/net -s $BASEDIR/$WORKDIR/client.conf --option=security=ads --option=kerberosencryptiontypes=$ETYPE_CONF"
+pcap_file=$BASEDIR/$WORKDIR/test.pcap
+
+# Load test functions
+. `dirname $0`/subunit.sh
+
+export SOCKET_WRAPPER_PCAP_FILE=$pcap_file
+testit "join" $VALGRIND $net_tool ads join -kU$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1`
+
+testit "testjoin" $VALGRIND $net_tool ads testjoin -kP || failed=`expr $failed + 1`
+
+#The leave command does not use the locally-generated
+#krb5.conf
+export SOCKET_WRAPPER_PCAP_FILE=
+testit "leave" $VALGRIND $net_tool ads leave -U$DC_USERNAME%$DC_PASSWORD || failed=`expr $failed + 1`
+
+actual_types="`tshark -r $pcap_file  -nVY "kerberos" | \
+	sed -rn -e 's/[[:space:]]*ENCTYPE:.*\(([^\)]*)\)$/\1/p' \
+	    -e 's/[[:space:]]*Encryption type:.*\(([^\)]*)\)$/\1/p' | \
+	sort -u | tr '\n' '_' | sed s/_$//`"
+
+testit "verify types" test "x$actual_types" = "x$EXPECTED_ETYPES" || failed=`expr $failed + 1`
+
+rm -rf $BASEDIR/$WORKDIR
+
+exit $failed
-- 
2.5.5



More information about the samba-technical mailing list