krb5 commit: Apply permitted_enctypes to KDC request enctypes

Greg Hudson ghudson at mit.edu
Thu Jan 23 14:34:11 EST 2020


https://github.com/krb5/krb5/commit/8f13fb2342b2a715cfb694688e3435e7f11691f8
commit 8f13fb2342b2a715cfb694688e3435e7f11691f8
Author: Robbie Harwood <rharwood at redhat.com>
Date:   Tue Jan 14 14:23:00 2020 -0500

    Apply permitted_enctypes to KDC request enctypes
    
    permitted_enctypes was initially intended only to restrict the
    processing of AP requests (and was later applied to KDB key data
    searches so that the KDC wouldn't issue a ticket it would refuse to
    accept).  Because the documentation was never clear about its scope,
    many configurations assume that permitted_enctypes also applies to
    clients.
    
    In light of the existing configurations, take the simple way out and
    use permitted_enctypes as the default for default_tkt_enctypes and
    default_tgs_enctypes.  Update the documentation, add a test to
    explicitly check the new behavior, and remove now-unnecessary
    configuration from the test suite.
    
    [ghudson at mit.edu: unrolled helper function; edited documentation and
    commit message; simplified test case]
    
    ticket: 8869 (new)
    tags: pullup
    target_version: 1.18

 doc/admin/conf_files/krb5_conf.rst   |   20 ++++--
 doc/admin/enctypes.rst               |    8 ++-
 src/lib/krb5/krb/init_ctx.c          |  144 ++++++++++++++++++----------------
 src/man/krb5.conf.man                |   22 ++++--
 src/tests/dejagnu/config/default.exp |   16 ----
 src/tests/gssapi/t_enctypes.py       |    6 +-
 src/tests/t_sesskeynego.py           |    8 ++
 src/util/k5test.py                   |   30 ++------
 8 files changed, 128 insertions(+), 126 deletions(-)

diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst
index d7687ef..f682255 100644
--- a/doc/admin/conf_files/krb5_conf.rst
+++ b/doc/admin/conf_files/krb5_conf.rst
@@ -159,7 +159,10 @@ The libdefaults section may contain any of the following relations:
     preference from highest to lowest.  The list may be delimited with
     commas or whitespace.  See :ref:`Encryption_types` in
     :ref:`kdc.conf(5)` for a list of the accepted values for this tag.
-    The default value is |defetypes|.
+    Starting in release 1.18, the default value is the value of
+    **permitted_enctypes**.  For previous releases or if
+    **permitted_enctypes** is not set, the default value is
+    |defetypes|.
 
     Do not set this unless required for specific backward
     compatibility purposes; stale values of this setting can prevent
@@ -170,8 +173,10 @@ The libdefaults section may contain any of the following relations:
     Identifies the supported list of session key encryption types that
     the client should request when making an AS-REQ, in order of
     preference from highest to lowest.  The format is the same as for
-    default_tgs_enctypes.  The default value for this tag is
-    |defetypes|.
+    default_tgs_enctypes.  Starting in release 1.18, the default
+    value is the value of **permitted_enctypes**.  For previous
+    releases or if **permitted_enctypes** is not set, the default
+    value is |defetypes|.
 
     Do not set this unless required for specific backward
     compatibility purposes; stale values of this setting can prevent
@@ -294,9 +299,12 @@ The libdefaults section may contain any of the following relations:
     used across NATs.  The default value is true.
 
 **permitted_enctypes**
-    Identifies all encryption types that are permitted for use in
-    session key encryption.  The default value for this tag is
-    |defetypes|.
+    Identifies the encryption types that servers will permit for
+    session keys and for ticket and authenticator encryption, ordered
+    by preference from highest to lowest.  Starting in release 1.18,
+    this tag also acts as the default value for
+    **default_tgs_enctypes** and **default_tkt_enctypes**.  The
+    default value for this tag is |defetypes|.
 
 **plugin_base_dir**
     If set, determines the base directory where krb5 plugins are
diff --git a/doc/admin/enctypes.rst b/doc/admin/enctypes.rst
index 84183a5..caf6d92 100644
--- a/doc/admin/enctypes.rst
+++ b/doc/admin/enctypes.rst
@@ -88,8 +88,12 @@ affect how enctypes are chosen.
     required for backward compatibility.
 
 **permitted_enctypes**
-    controls the set of enctypes that a service will accept as session
-    keys.
+    controls the set of enctypes that a service will permit for
+    session keys and for ticket and authenticator encryption.  The KDC
+    and other programs that access the Kerberos database will ignore
+    keys of non-permitted enctypes.  Starting in release 1.18, this
+    setting also acts as the default for **default_tkt_enctypes** and
+    **defaut_tgs_enctypes**.
 
 **default_tkt_enctypes**
     controls the default set of enctypes that the Kerberos client
diff --git a/src/lib/krb5/krb/init_ctx.c b/src/lib/krb5/krb/init_ctx.c
index 0fad903..e7d67cc 100644
--- a/src/lib/krb5/krb/init_ctx.c
+++ b/src/lib/krb5/krb/init_ctx.c
@@ -501,63 +501,43 @@ krb5int_parse_enctype_list(krb5_context context, const char *profkey,
 
     if (list == NULL)
         return ENOMEM;
-    *result = list;
-    return 0;
-}
-
-/*
- * Set *etypes_ptr to a zero-terminated list of enctypes.  ctx_list
- * (containing application-specified enctypes) is used if non-NULL;
- * otherwise the libdefaults profile string specified by profkey is
- * used.  default_list is the default enctype list to be used while
- * parsing profile strings, and is also used if the profile string is
- * not set.
- */
-static krb5_error_code
-get_profile_etype_list(krb5_context context, krb5_enctype **etypes_ptr,
-                       char *profkey, krb5_enctype *ctx_list,
-                       krb5_enctype *default_list)
-{
-    krb5_enctype *etypes;
-    krb5_error_code code;
-    char *profstr;
-
-    *etypes_ptr = NULL;
-
-    if (ctx_list) {
-        /* Use application defaults. */
-        code = k5_copy_etypes(ctx_list, &etypes);
-        if (code)
-            return code;
-    } else {
-        /* Parse profile setting, or "DEFAULT" if not specified. */
-        code = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS,
-                                  profkey, NULL, "DEFAULT", &profstr);
-        if (code)
-            return code;
-        code = krb5int_parse_enctype_list(context, profkey, profstr,
-                                          default_list, &etypes);
-        profile_release_string(profstr);
-        if (code)
-            return code;
-    }
-
-    if (etypes[0] == 0) {
-        free(etypes);
+    if (list[0] == ENCTYPE_NULL) {
+        free(list);
         return KRB5_CONFIG_ETYPE_NOSUPP;
     }
-
-    *etypes_ptr = etypes;
+    *result = list;
     return 0;
 }
 
 krb5_error_code
 krb5_get_default_in_tkt_ktypes(krb5_context context, krb5_enctype **ktypes)
 {
-    return get_profile_etype_list(context, ktypes,
-                                  KRB5_CONF_DEFAULT_TKT_ENCTYPES,
-                                  context->in_tkt_etypes,
-                                  default_enctype_list);
+    krb5_error_code ret;
+    char *profstr = NULL;
+    const char *profkey;
+
+    *ktypes = NULL;
+
+    if (context->in_tkt_etypes != NULL)
+        return k5_copy_etypes(context->in_tkt_etypes, ktypes);
+
+    profkey = KRB5_CONF_DEFAULT_TKT_ENCTYPES;
+    ret = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS,
+                             profkey, NULL, NULL, &profstr);
+    if (ret)
+        return ret;
+    if (profstr == NULL) {
+        profkey = KRB5_CONF_PERMITTED_ENCTYPES;
+        ret = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS,
+                                 profkey, NULL, "DEFAULT", &profstr);
+        if (ret)
+            return ret;
+    }
+
+    ret = krb5int_parse_enctype_list(context, profkey, profstr,
+                                     default_enctype_list, ktypes);
+    profile_release_string(profstr);
+    return ret;
 }
 
 void
@@ -567,29 +547,61 @@ krb5_free_enctypes(krb5_context context, krb5_enctype *val)
     free (val);
 }
 
-krb5_error_code
-KRB5_CALLCONV
-krb5_get_tgs_ktypes(krb5_context context, krb5_const_principal princ, krb5_enctype **ktypes)
+krb5_error_code KRB5_CALLCONV
+krb5_get_tgs_ktypes(krb5_context context, krb5_const_principal princ,
+                    krb5_enctype **ktypes)
 {
-    if (context->use_conf_ktypes)
-        /* This one is set *only* by reading the config file; it's not
-           set by the application.  */
-        return get_profile_etype_list(context, ktypes,
-                                      KRB5_CONF_DEFAULT_TGS_ENCTYPES, NULL,
-                                      default_enctype_list);
-    else
-        return get_profile_etype_list(context, ktypes,
-                                      KRB5_CONF_DEFAULT_TGS_ENCTYPES,
-                                      context->tgs_etypes,
-                                      default_enctype_list);
+    krb5_error_code ret;
+    char *profstr = NULL;
+    const char *profkey;
+
+    *ktypes = NULL;
+
+    /* Use only profile configuration when use_conf_ktypes is set. */
+    if (!context->use_conf_ktypes && context->tgs_etypes != NULL)
+        return k5_copy_etypes(context->tgs_etypes, ktypes);
+
+    profkey = KRB5_CONF_DEFAULT_TGS_ENCTYPES;
+    ret = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS,
+                             profkey, NULL, NULL, &profstr);
+    if (ret)
+        return ret;
+    if (profstr == NULL) {
+        profkey = KRB5_CONF_PERMITTED_ENCTYPES;
+        ret = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS,
+                                 profkey, NULL, "DEFAULT", &profstr);
+        if (ret)
+            return ret;
+    }
+
+    ret = krb5int_parse_enctype_list(context, profkey, profstr,
+                                     default_enctype_list, ktypes);
+    profile_release_string(profstr);
+    return ret;
 }
 
 krb5_error_code KRB5_CALLCONV
 krb5_get_permitted_enctypes(krb5_context context, krb5_enctype **ktypes)
 {
-    return get_profile_etype_list(context, ktypes,
-                                  KRB5_CONF_PERMITTED_ENCTYPES,
-                                  context->tgs_etypes, default_enctype_list);
+    krb5_error_code ret;
+    char *profstr = NULL;
+    const char *profkey;
+
+    *ktypes = NULL;
+
+    if (context->tgs_etypes != NULL)
+        return k5_copy_etypes(context->tgs_etypes, ktypes);
+
+    profkey = KRB5_CONF_PERMITTED_ENCTYPES;
+    ret = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS,
+                             profkey, NULL, "DEFAULT", &profstr);
+    if (ret)
+        return ret;
+
+    ret = krb5int_parse_enctype_list(context, profkey, profstr,
+                                     default_enctype_list, ktypes);
+    profile_release_string(profstr);
+    return ret;
 }
 
 krb5_boolean
diff --git a/src/man/krb5.conf.man b/src/man/krb5.conf.man
index fbcecb8..7b6ada5 100644
--- a/src/man/krb5.conf.man
+++ b/src/man/krb5.conf.man
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "KRB5.CONF" "5" " " "1.18" "MIT Kerberos"
+.TH "KRB5.CONF" "5" " " "1.19" "MIT Kerberos"
 .SH NAME
 krb5.conf \- Kerberos configuration file
 .
@@ -242,7 +242,10 @@ the client should request when making a TGS\-REQ, in order of
 preference from highest to lowest.  The list may be delimited with
 commas or whitespace.  See Encryption_types in
 kdc.conf(5) for a list of the accepted values for this tag.
-The default value is \fBaes256\-cts\-hmac\-sha1\-96 aes128\-cts\-hmac\-sha1\-96 aes256\-cts\-hmac\-sha384\-192 aes128\-cts\-hmac\-sha256\-128 des3\-cbc\-sha1 arcfour\-hmac\-md5 camellia256\-cts\-cmac camellia128\-cts\-cmac\fP\&.
+Starting in release 1.18, the default value is the value of
+\fBpermitted_enctypes\fP\&.  For previous releases or if
+\fBpermitted_enctypes\fP is not set, the default value is
+\fBaes256\-cts\-hmac\-sha1\-96 aes128\-cts\-hmac\-sha1\-96 aes256\-cts\-hmac\-sha384\-192 aes128\-cts\-hmac\-sha256\-128 des3\-cbc\-sha1 arcfour\-hmac\-md5 camellia256\-cts\-cmac camellia128\-cts\-cmac\fP\&.
 .sp
 Do not set this unless required for specific backward
 compatibility purposes; stale values of this setting can prevent
@@ -253,8 +256,10 @@ libraries are upgraded.
 Identifies the supported list of session key encryption types that
 the client should request when making an AS\-REQ, in order of
 preference from highest to lowest.  The format is the same as for
-default_tgs_enctypes.  The default value for this tag is
-\fBaes256\-cts\-hmac\-sha1\-96 aes128\-cts\-hmac\-sha1\-96 aes256\-cts\-hmac\-sha384\-192 aes128\-cts\-hmac\-sha256\-128 des3\-cbc\-sha1 arcfour\-hmac\-md5 camellia256\-cts\-cmac camellia128\-cts\-cmac\fP\&.
+default_tgs_enctypes.  Starting in release 1.18, the default
+value is the value of \fBpermitted_enctypes\fP\&.  For previous
+releases or if \fBpermitted_enctypes\fP is not set, the default
+value is \fBaes256\-cts\-hmac\-sha1\-96 aes128\-cts\-hmac\-sha1\-96 aes256\-cts\-hmac\-sha384\-192 aes128\-cts\-hmac\-sha256\-128 des3\-cbc\-sha1 arcfour\-hmac\-md5 camellia256\-cts\-cmac camellia128\-cts\-cmac\fP\&.
 .sp
 Do not set this unless required for specific backward
 compatibility purposes; stale values of this setting can prevent
@@ -377,9 +382,12 @@ made with address restrictions set, allowing the tickets to be
 used across NATs.  The default value is true.
 .TP
 \fBpermitted_enctypes\fP
-Identifies all encryption types that are permitted for use in
-session key encryption.  The default value for this tag is
-\fBaes256\-cts\-hmac\-sha1\-96 aes128\-cts\-hmac\-sha1\-96 aes256\-cts\-hmac\-sha384\-192 aes128\-cts\-hmac\-sha256\-128 des3\-cbc\-sha1 arcfour\-hmac\-md5 camellia256\-cts\-cmac camellia128\-cts\-cmac\fP\&.
+Identifies the encryption types that servers will permit for
+session keys and for ticket and authenticator encryption, ordered
+by preference from highest to lowest.  Starting in release 1.18,
+this tag also acts as the default value for
+\fBdefault_tgs_enctypes\fP and \fBdefault_tkt_enctypes\fP\&.  The
+default value for this tag is \fBaes256\-cts\-hmac\-sha1\-96 aes128\-cts\-hmac\-sha1\-96 aes256\-cts\-hmac\-sha384\-192 aes128\-cts\-hmac\-sha256\-128 des3\-cbc\-sha1 arcfour\-hmac\-md5 camellia256\-cts\-cmac camellia128\-cts\-cmac\fP\&.
 .TP
 \fBplugin_base_dir\fP
 If set, determines the base directory where krb5 plugins are
diff --git a/src/tests/dejagnu/config/default.exp b/src/tests/dejagnu/config/default.exp
index c246517..b047ef1 100644
--- a/src/tests/dejagnu/config/default.exp
+++ b/src/tests/dejagnu/config/default.exp
@@ -136,14 +136,6 @@ set passes {
 	{permitted_enctypes(replica)=aes256-sha2}
 	{permitted_enctypes(client)=aes256-sha2}
 	{permitted_enctypes(server)=aes256-sha2}
-	{default_tgs_enctypes(kdc)=aes256-sha2}
-	{default_tgs_enctypes(replica)=aes256-sha2}
-	{default_tgs_enctypes(client)=aes256-sha2}
-	{default_tgs_enctypes(server)=aes256-sha2}
-	{default_tkt_enctypes(kdc)=aes256-sha2}
-	{default_tkt_enctypes(replica)=aes256-sha2}
-	{default_tkt_enctypes(client)=aes256-sha2}
-	{default_tkt_enctypes(server)=aes256-sha2}
 	{allow_weak_crypto(kdc)=false}
 	{allow_weak_crypto(replica)=false}
 	{allow_weak_crypto(client)=false}
@@ -160,14 +152,6 @@ set passes {
 	{permitted_enctypes(replica)=camellia256-cts}
 	{permitted_enctypes(client)=camellia256-cts}
 	{permitted_enctypes(server)=camellia256-cts}
-	{default_tgs_enctypes(kdc)=camellia256-cts}
-	{default_tgs_enctypes(replica)=camellia256-cts}
-	{default_tgs_enctypes(client)=camellia256-cts}
-	{default_tgs_enctypes(server)=camellia256-cts}
-	{default_tkt_enctypes(kdc)=camellia256-cts}
-	{default_tkt_enctypes(replica)=camellia256-cts}
-	{default_tkt_enctypes(client)=camellia256-cts}
-	{default_tkt_enctypes(server)=camellia256-cts}
 	{allow_weak_crypto(kdc)=false}
 	{allow_weak_crypto(replica)=false}
 	{allow_weak_crypto(client)=false}
diff --git a/src/tests/gssapi/t_enctypes.py b/src/tests/gssapi/t_enctypes.py
index ca3d32d..7494d7f 100755
--- a/src/tests/gssapi/t_enctypes.py
+++ b/src/tests/gssapi/t_enctypes.py
@@ -17,12 +17,8 @@ d_rc4 = 'DEPRECATED:arcfour-hmac'
 
 # These tests make assumptions about the default enctype lists, so set
 # them explicitly rather than relying on the library defaults.
-enctypes='aes des3 rc4'
 supp='aes256-cts:normal aes128-cts:normal des3-cbc-sha1:normal rc4-hmac:normal'
-conf = {'libdefaults': {
-        'default_tgs_enctypes': enctypes,
-        'default_tkt_enctypes': enctypes,
-        'permitted_enctypes': enctypes},
+conf = {'libdefaults': {'permitted_enctypes': 'aes des3 rc4'},
         'realms': {'$realm': {'supported_enctypes': supp}}}
 realm = K5Realm(krb5_conf=conf)
 shutil.copyfile(realm.ccache, os.path.join(realm.testdir, 'save'))
diff --git a/src/tests/t_sesskeynego.py b/src/tests/t_sesskeynego.py
index 621b271..73a5536 100755
--- a/src/tests/t_sesskeynego.py
+++ b/src/tests/t_sesskeynego.py
@@ -24,6 +24,7 @@ conf3 = {'libdefaults': {
         'allow_weak_crypto': 'true',
         'default_tkt_enctypes': 'aes128-cts',
         'default_tgs_enctypes': 'rc4-hmac,aes128-cts'}}
+conf4 = {'libdefaults': {'permitted_enctypes': 'aes256-cts'}}
 # Test with client request and session_enctypes preferring aes128, but
 # aes256 long-term key.
 realm = K5Realm(krb5_conf=conf1, create_host=False, get_creds=False)
@@ -59,4 +60,11 @@ realm.run([kadminl, 'setstr', 'server', 'session_enctypes',
 test_kvno(realm, 'DEPRECATED:arcfour-hmac', 'aes256-cts-hmac-sha1-96')
 realm.stop()
 
+# 4: Check that permitted_enctypes is a default for session key enctypes.
+realm = K5Realm(krb5_conf=conf4, create_host=False, get_creds=False)
+realm.kinit(realm.user_princ, password('user'))
+realm.run([kvno, 'user'],
+          expected_trace=('etypes requested in TGS request: aes256-cts',))
+realm.stop()
+
 success('sesskeynego')
diff --git a/src/util/k5test.py b/src/util/k5test.py
index e3614d7..2b0e111 100644
--- a/src/util/k5test.py
+++ b/src/util/k5test.py
@@ -1299,60 +1299,42 @@ _passes = [
 
     # Exercise the DES3 enctype.
     ('des3', None,
-     {'libdefaults': {
-                'default_tgs_enctypes': 'des3',
-                'default_tkt_enctypes': 'des3',
-                'permitted_enctypes': 'des3'}},
+     {'libdefaults': {'permitted_enctypes': 'des3'}},
      {'realms': {'$realm': {
                     'supported_enctypes': 'des3-cbc-sha1:normal',
                     'master_key_type': 'des3-cbc-sha1'}}}),
 
     # Exercise the arcfour enctype.
     ('arcfour', None,
-     {'libdefaults': {
-                'default_tgs_enctypes': 'rc4',
-                'default_tkt_enctypes': 'rc4',
-                'permitted_enctypes': 'rc4'}},
+     {'libdefaults': {'permitted_enctypes': 'rc4'}},
      {'realms': {'$realm': {
                     'supported_enctypes': 'arcfour-hmac:normal',
                     'master_key_type': 'arcfour-hmac'}}}),
 
     # Exercise the AES128 enctype.
     ('aes128', None,
-      {'libdefaults': {
-                'default_tgs_enctypes': 'aes128-cts',
-                'default_tkt_enctypes': 'aes128-cts',
-                'permitted_enctypes': 'aes128-cts'}},
+      {'libdefaults': {'permitted_enctypes': 'aes128-cts'}},
       {'realms': {'$realm': {
                     'supported_enctypes': 'aes128-cts:normal',
                     'master_key_type': 'aes128-cts'}}}),
 
     # Exercise the camellia256-cts enctype.
     ('camellia256', None,
-      {'libdefaults': {
-                'default_tgs_enctypes': 'camellia256-cts',
-                'default_tkt_enctypes': 'camellia256-cts',
-                'permitted_enctypes': 'camellia256-cts'}},
+      {'libdefaults': {'permitted_enctypes': 'camellia256-cts'}},
       {'realms': {'$realm': {
                     'supported_enctypes': 'camellia256-cts:normal',
                     'master_key_type': 'camellia256-cts'}}}),
 
     # Exercise the aes128-sha2 enctype.
     ('aes128-sha2', None,
-      {'libdefaults': {
-                'default_tgs_enctypes': 'aes128-sha2',
-                'default_tkt_enctypes': 'aes128-sha2',
-                'permitted_enctypes': 'aes128-sha2'}},
+      {'libdefaults': {'permitted_enctypes': 'aes128-sha2'}},
       {'realms': {'$realm': {
                     'supported_enctypes': 'aes128-sha2:normal',
                     'master_key_type': 'aes128-sha2'}}}),
 
     # Exercise the aes256-sha2 enctype.
     ('aes256-sha2', None,
-      {'libdefaults': {
-                'default_tgs_enctypes': 'aes256-sha2',
-                'default_tkt_enctypes': 'aes256-sha2',
-                'permitted_enctypes': 'aes256-sha2'}},
+      {'libdefaults': {'permitted_enctypes': 'aes256-sha2'}},
       {'realms': {'$realm': {
                     'supported_enctypes': 'aes256-sha2:normal',
                     'master_key_type': 'aes256-sha2'}}}),


More information about the cvs-krb5 mailing list