[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