svn rev #24359: trunk/src/ clients/kpasswd/ include/krb5/ lib/krb5/ lib/krb5/krb/ ...

hartmans@MIT.EDU hartmans at MIT.EDU
Mon Sep 27 13:16:41 EDT 2010


http://src.mit.edu/fisheye/changelog/krb5/?cs=24359
Commit By: hartmans
Log Message:
ticket: 6786
subject: kpasswd: if a credential cache is present, use FAST

If a credentials cache is available, use it as an armor cache to enable FAST negotiation for kpasswd. This requires an attacker to attack both the user's long-term key for the old password as well as the ticket used for the armor cache in order to attack the password change. Depending on how the armor ticket is obtained, this may provide limited value. However, it provides users an easy option if they are concerned about their current password. Users can kinit with one principal to help protect changing the password of another principal.

* krb5_get_init_creds_opt_set_fast_ccache: new API to set fast ccache based on a krb5_ccache object rather than a resolvable string

* kpasswd: always open the current credential cache even if not needed
  for determining the principal. If the cache has tickets, use it as
  an armor cache.

* tests/dejagnu/krb-standalone/kadmin.exp: Arrange to test new code path


Changed Files:
U   trunk/src/clients/kpasswd/kpasswd.c
U   trunk/src/include/krb5/krb5.hin
U   trunk/src/lib/krb5/krb/gic_opt.c
U   trunk/src/lib/krb5/libkrb5.exports
U   trunk/src/tests/dejagnu/krb-standalone/kadmin.exp
Modified: trunk/src/clients/kpasswd/kpasswd.c
===================================================================
--- trunk/src/clients/kpasswd/kpasswd.c	2010-09-27 16:56:17 UTC (rev 24358)
+++ trunk/src/clients/kpasswd/kpasswd.c	2010-09-27 17:16:41 UTC (rev 24359)
@@ -70,6 +70,10 @@
         com_err(argv[0], ret, "initializing kerberos library");
         exit(1);
     }
+    if ((ret = krb5_get_init_creds_opt_alloc(context, &opts))) {
+        com_err(argv[0], ret, "allocating krb5_get_init_creds_opt");
+        exit(1);
+    }
 
     /* in order, use the first of:
        - a name specified on the command line
@@ -77,40 +81,43 @@
        - the name corresponding to the ruid of the process
 
        otherwise, it's an error.
+       We always attempt to open  the default ccache in order to use FAST if
+       possible.
     */
-
+    ret = krb5_cc_default(context, &ccache);
+    if (ret != 0) {
+        com_err(argv[0], ret, "opening default ccache");
+        exit(1);
+    }
+    ret = krb5_cc_get_principal(context, ccache, &princ);
+    if (ret != 0 && ret != KRB5_CC_NOTFOUND && ret != KRB5_FCC_NOFILE) {
+        com_err(argv[0], ret, "getting principal from ccache");
+        exit(1);
+    } else {
+        if (princ != NULL)
+            ret = krb5_get_init_creds_opt_set_fast_ccache(context, opts, ccache);
+        else ret = 0;
+        if (ret) {
+            com_err(argv[0], ret, "while setting default ccache name");
+            exit(1);
+        }
+    }
+    ret = krb5_cc_close(context, ccache);
+    if (ret != 0) {
+        com_err(argv[0], ret, "closing ccache");
+        exit(1);
+    }
     if (pname) {
+        krb5_free_principal(context, princ);
+        princ = NULL;
         if ((ret = krb5_parse_name(context, pname, &princ))) {
             com_err(argv[0], ret, "parsing client name");
             exit(1);
         }
-    } else {
-        ret = krb5_cc_default(context, &ccache);
-        if (ret != 0) {
-            com_err(argv[0], ret, "opening default ccache");
-            exit(1);
-        }
-
-        ret = krb5_cc_get_principal(context, ccache, &princ);
-        if (ret != 0 && ret != KRB5_CC_NOTFOUND && ret != KRB5_FCC_NOFILE) {
-            com_err(argv[0], ret, "getting principal from ccache");
-            exit(1);
-        }
-
-        ret = krb5_cc_close(context, ccache);
-        if (ret != 0) {
-            com_err(argv[0], ret, "closing ccache");
-            exit(1);
-        }
-
-        if (princ == NULL)
-            get_name_from_passwd_file(argv[0], context, &princ);
     }
+    if (princ == NULL)
+        get_name_from_passwd_file(argv[0], context, &princ);
 
-    if ((ret = krb5_get_init_creds_opt_alloc(context, &opts))) {
-        com_err(argv[0], ret, "allocating krb5_get_init_creds_opt");
-        exit(1);
-    }
     krb5_get_init_creds_opt_set_tkt_life(opts, 5*60);
     krb5_get_init_creds_opt_set_renew_life(opts, 0);
     krb5_get_init_creds_opt_set_forwardable(opts, 0);

Modified: trunk/src/include/krb5/krb5.hin
===================================================================
--- trunk/src/include/krb5/krb5.hin	2010-09-27 16:56:17 UTC (rev 24358)
+++ trunk/src/include/krb5/krb5.hin	2010-09-27 17:16:41 UTC (rev 24359)
@@ -1434,6 +1434,11 @@
 #define KRB5_TC_OPENCLOSE               0x00000001
 #define KRB5_TC_NOTICKET                0x00000002
 
+/** Retrieve the name but not type of a credential cache @returns The name of
+ * the credential cache as an alias that should not be freed or modified by the
+ * caller. This name does not include the type portion, so cannot be used as
+ * input to krb5_cc_resolve().
+ */
 const char * KRB5_CALLCONV
 krb5_cc_get_name(krb5_context context, krb5_ccache cache);
 
@@ -1484,6 +1489,9 @@
 krb5_error_code KRB5_CALLCONV
 krb5_cc_get_flags(krb5_context context, krb5_ccache cache, krb5_flags *flags);
 
+/** Retrive the type of a credential cache @returns The type of a credential
+ * cache as an alias that should not be modified or freed by the caller.
+ */
 const char * KRB5_CALLCONV
 krb5_cc_get_type(krb5_context context, krb5_ccache cache);
 
@@ -2329,6 +2337,15 @@
                                              krb5_get_init_creds_opt *opt,
                                              const char *fast_ccache_name);
 
+/** Set the FAST ccache name as in
+ * krb5_get_init_creds_opt_set_fast_ccache_name() but using a krb5_ccache
+ * rather than a name
+ */
+krb5_error_code KRB5_CALLCONV
+krb5_get_init_creds_opt_set_fast_ccache(krb5_context context,
+                                             krb5_get_init_creds_opt *opt,
+                                        krb5_ccache fast_ccache_name);
+
 /**
  * Set a ccache where resulting credentials will be stored.  If set, then the
  * krb5_get_init_creds family of APIs will write out credentials to the given

Modified: trunk/src/lib/krb5/krb/gic_opt.c
===================================================================
--- trunk/src/lib/krb5/krb/gic_opt.c	2010-09-27 16:56:17 UTC (rev 24358)
+++ trunk/src/lib/krb5/krb/gic_opt.c	2010-09-27 17:16:41 UTC (rev 24359)
@@ -1,6 +1,7 @@
 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
 #include "k5-int.h"
 #include "int-proto.h"
+#include "k5-buf.h"
 
 static void
 init_common(krb5_get_init_creds_opt *opt)
@@ -431,6 +432,28 @@
 }
 
 krb5_error_code KRB5_CALLCONV
+krb5_get_init_creds_opt_set_fast_ccache(
+    krb5_context context,
+    krb5_get_init_creds_opt *opt,
+    krb5_ccache ccache)
+{
+    krb5_error_code retval = 0;
+    struct k5buf buf;
+    char *cc_name;
+    krb5int_buf_init_dynamic(&buf);
+    krb5int_buf_add(&buf, krb5_cc_get_type(context, ccache));
+    krb5int_buf_add(&buf, ":");
+    krb5int_buf_add(&buf, krb5_cc_get_name(context, ccache));
+    cc_name = krb5int_buf_data(&buf);
+    if (cc_name)
+        retval =  krb5_get_init_creds_opt_set_fast_ccache_name(context, opt, cc_name);
+    else retval = ENOMEM;
+        krb5int_free_buf(&buf);
+    return retval;
+}
+
+
+krb5_error_code KRB5_CALLCONV
 krb5_get_init_creds_opt_set_out_ccache(krb5_context context,
                                        krb5_get_init_creds_opt *opt,
                                        krb5_ccache ccache)

Modified: trunk/src/lib/krb5/libkrb5.exports
===================================================================
--- trunk/src/lib/krb5/libkrb5.exports	2010-09-27 16:56:17 UTC (rev 24358)
+++ trunk/src/lib/krb5/libkrb5.exports	2010-09-27 17:16:41 UTC (rev 24359)
@@ -352,6 +352,7 @@
 krb5_get_init_creds_opt_set_change_password_prompt
 krb5_get_init_creds_opt_set_etype_list
 krb5_get_init_creds_opt_set_expire_callback
+krb5_get_init_creds_opt_set_fast_ccache
 krb5_get_init_creds_opt_set_fast_ccache_name
 krb5_get_init_creds_opt_set_fast_flags
 krb5_get_init_creds_opt_set_forwardable

Modified: trunk/src/tests/dejagnu/krb-standalone/kadmin.exp
===================================================================
--- trunk/src/tests/dejagnu/krb-standalone/kadmin.exp	2010-09-27 16:56:17 UTC (rev 24358)
+++ trunk/src/tests/dejagnu/krb-standalone/kadmin.exp	2010-09-27 17:16:41 UTC (rev 24359)
@@ -996,10 +996,11 @@
     }
 
     # now test that we can kinit with principals/passwords.
+    # We defer kdestroying until after kpasswd at least once to test FAST automatic use in kpasswd
     if {![kadmin_add testprinc1/instance thisisatest] \
 	    || ![kinit testprinc1/instance thisisatest 0] \
+	    || ![kpasswd_cpw testprinc1/instance thisisatest anothertest] \
 	    || ![kdestroy] \
-	    || ![kpasswd_cpw testprinc1/instance thisisatest anothertest] \
 	    || ![kinit testprinc1/instance anothertest 0] \
 	    || ![kdestroy] \
 	    || ![kpasswd_cpw testprinc1/instance anothertest goredsox] \




More information about the cvs-krb5 mailing list