krb5 commit [krb5-1.18]: Apply permitted_enctypes to KDC request enctypes

Greg Hudson <[email protected]>
Newsgroups gmane.comp.encryption.kerberos.cvs
Message-ID <[email protected]>
https://github.com/krb5/krb5/commit/62c1cb2e33ab719e6df8b03388ddd3c3fd459a27
commit 62c1cb2e33ab719e6df8b03388ddd3c3fd459a27
Author: Robbie Harwood <[email protected]>
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.
    
    [[email protected]: unrolled helper function; edited documentation and
    commit message; simplified test case]
    
    (cherry picked from commit 8f13fb2342b2a715cfb694688e3435e7f11691f8)
    
    ticket: 8869
    version_fixed: 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 9a7c32c..1498430 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'}}}),
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.