[PATCHES] limit kerberos encryption types used by winbindd

Jeremy Allison jra at samba.org
Tue Aug 2 23:52:42 UTC 2016


On Mon, Jul 25, 2016 at 07:17:06AM +0300, Uri Simchoni wrote:
> On 07/24/2016 04:31 PM, Ira Cooper wrote:
> > 
> > 
> > That compiles.
> > 
> > I'll run Uri's patch at least, though my machine isn't a real test env.
> > 
> > Cheers,
> > 
> > -Ira
> > 
> 
> The unit tests can't run because they need a testenv with an AD-DC, but
> using Alexander's patch to fix MIT build and some pointers from Ira on
> how to build for MIT I also manually tested it with MIT Kerberos as well.
> 
> Attached is a rebased patch due to the new leases default (no actual
> changes).

LGTM - I installed tshark to ensure the tests work :-).

Revewed-by: Jeremy Allison <jra at samba.org>

I tried to push but autobuild appears to be completely
broken by the AD-DC replication tests/code at the moment.

That will have to be fixed or the tests reverted/put into
skip before we can get this in.

(Feel free to try yourself !).

Jeremy.

> From 72d07e9e658cd75b5f213e940d1db17c9be9ba9b 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 v2 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 0d7a6e6393d898cdd44ebdefb7cd3aa15eff26bf 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 v2 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 185df76df2c71a83bc798ef116c104d825cbb093 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 v2 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 c1338d08afe13624e2e0dd4cfc0ec67a5da59c9c 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 v2 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 | 54 ++++++++++++++++++++++++++++++++
>  2 files changed, 57 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..a878c81
> --- /dev/null
> +++ b/testprogs/blackbox/test_client_etypes.sh
> @@ -0,0 +1,54 @@
> +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 's/[[:space:]]*ENCTYPE:.*\(([^\)]*)\)$/\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