implement KRB5_TC_SUPPORTED_KTYPES and common _retrieve methods; from 1.1 branch
authorKen Raeburn <raeburn@mit.edu>
Wed, 1 Sep 1999 21:12:02 +0000 (21:12 +0000)
committerKen Raeburn <raeburn@mit.edu>
Wed, 1 Sep 1999 21:12:02 +0000 (21:12 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@11768 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb5/ccache/ChangeLog
src/lib/krb5/ccache/Makefile.in
src/lib/krb5/ccache/cc_retr.c [new file with mode: 0644]
src/lib/krb5/ccache/ccapi/ChangeLog
src/lib/krb5/ccache/ccapi/stdcc.c
src/lib/krb5/ccache/file/ChangeLog
src/lib/krb5/ccache/file/fcc_retrv.c
src/lib/krb5/ccache/memory/ChangeLog
src/lib/krb5/ccache/memory/mcc_retrv.c
src/lib/krb5/ccache/stdio/ChangeLog
src/lib/krb5/ccache/stdio/scc_retrv.c

index 5080786448bae97b474df7cd4d6450c3442ece07..3ec681fd9c9dfed81577391a5b5de91f3c84f350 100644 (file)
@@ -1,3 +1,15 @@
+1999-08-23  Ken Raeburn  <raeburn@mit.edu>
+
+       * cc_retr.c: New file.
+       (krb5_cc_retrieve_cred_seq): New function, derived from
+       fcc_retrieve but takes an optional list of enctypes to look for in
+       priority order.
+       (krb5_cc_retrieve_cred_default): New function.  Same signature as
+       original fcc_retrieve but if new flag KRB5_TC_SUPPORTED_KTYPES is
+       set, calls krb5_get_tgs_ktypes to get a list of enctypes to look
+       for.
+       * Makefile.in (STLIBOBJS, OBJS, SRCS): Add it.
+
 Tue May 18 19:52:56 1999  Danilo Almeida  <dalmeida@mit.edu>
 
        * Makefile.in: Remove - from recursive Win32 make invocation.
index eafa55773c675dd4765613d8e938584f5a41d609..a9d426595498b8038cb4472f7b2e8f50e6c564f3 100644 (file)
@@ -21,18 +21,21 @@ STLIBOBJS= \
        cccopy.o \
        ccdefault.o \
        ccdefops.o \
+       cc_retr.o \
        ser_cc.o
 
 OBJS=  $(OUTPRE)ccbase.$(OBJEXT) \
        $(OUTPRE)cccopy.$(OBJEXT) \
        $(OUTPRE)ccdefault.$(OBJEXT) \
        $(OUTPRE)ccdefops.$(OBJEXT) \
+       $(OUTPRE)cc_retr.$(OBJEXT) \
        $(OUTPRE)ser_cc.$(OBJEXT)
 
 SRCS=  $(srcdir)/ccbase.c \
        $(srcdir)/cccopy.c \
        $(srcdir)/ccdefault.c \
        $(srcdir)/ccdefops.c \
+       $(srcdir)/cc_retr.c \
        $(srcdir)/ser_cc.c
 
 all-unix:: all-libobjs
diff --git a/src/lib/krb5/ccache/cc_retr.c b/src/lib/krb5/ccache/cc_retr.c
new file mode 100644 (file)
index 0000000..e786335
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ * lib/krb5/ccache/cc_retr.c
+ *
+ * Copyright 1990,1991,1999 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ * 
+ *
+ */
+
+#include "k5-int.h"
+
+#define KRB5_OK 0
+
+#define set(bits) (whichfields & bits)
+#define flags_match(a,b) (((a) & (b)) == (a))
+#define times_match_exact(t1,t2) (memcmp((char *)(t1), (char *)(t2), sizeof(*(t1))) == 0)
+
+static krb5_boolean
+times_match(t1, t2)
+     const krb5_ticket_times *t1;
+     const krb5_ticket_times *t2;
+{
+    if (t1->renew_till) {
+       if (t1->renew_till > t2->renew_till)
+           return FALSE;               /* this one expires too late */
+    }
+    if (t1->endtime) {
+       if (t1->endtime > t2->endtime)
+           return FALSE;               /* this one expires too late */
+    }
+    /* only care about expiration on a times_match */
+    return TRUE;
+}
+
+static krb5_boolean
+standard_fields_match(context, mcreds, creds)
+krb5_context           context;
+const krb5_creds       *mcreds;
+const krb5_creds       *creds;
+{
+  return (krb5_principal_compare(context, mcreds->client,creds->client)
+         && krb5_principal_compare(context, mcreds->server,creds->server));
+}
+
+/* only match the server name portion, not the server realm portion */
+
+static krb5_boolean
+srvname_match(context, mcreds, creds)
+   krb5_context context;
+   const krb5_creds *mcreds, *creds;
+{
+    krb5_boolean retval;
+    krb5_principal_data p1, p2;
+    
+    retval = krb5_principal_compare(context, mcreds->client,creds->client);
+    if (retval != TRUE)
+       return retval;
+    /*
+     * Hack to ignore the server realm for the purposes of the compare.
+     */
+    p1 = *mcreds->server;
+    p2 = *creds->server;
+    p1.realm = p2.realm;
+    return krb5_principal_compare(context, &p1, &p2);
+}
+
+static krb5_boolean
+authdata_match(mdata, data)
+     krb5_authdata * const *mdata, * const *data;
+{
+    const krb5_authdata *mdatap, *datap;
+
+    if (mdata == data)
+      return TRUE;
+
+    if (mdata == NULL)
+       return *data == NULL;
+       
+    if (data == NULL)
+       return *mdata == NULL;
+    
+    while ((mdatap = *mdata) && (datap = *data)) {
+      if ((mdatap->ad_type != datap->ad_type) ||
+          (mdatap->length != datap->length) ||
+          (memcmp ((char *)mdatap->contents,
+                (char *)datap->contents, mdatap->length) != 0))
+          return FALSE;
+      mdata++;
+      data++;
+    }
+    return (*mdata == NULL) && (*data == NULL);
+}
+
+static krb5_boolean
+data_match(data1, data2)
+     const krb5_data *data1, *data2;
+{
+    if (!data1) {
+       if (!data2)
+           return TRUE;
+       else
+           return FALSE;
+    }
+    if (!data2) return FALSE;
+
+    if (data1->length != data2->length)
+       return FALSE;
+    else
+       return memcmp(data1->data, data2->data, data1->length) ? FALSE : TRUE;
+}
+
+static int
+pref (krb5_enctype my_ktype, int nktypes, krb5_enctype *ktypes)
+{
+  int i;
+  for (i = 0; i < nktypes; i++)
+    if (my_ktype == ktypes[i])
+      return i;
+  return -1;
+}
+
+/*
+ * Effects:
+ * Searches the credentials cache for a credential matching mcreds,
+ * with the fields specified by whichfields.  If one if found, it is
+ * returned in creds, which should be freed by the caller with
+ * krb5_free_credentials().
+ * 
+ * The fields are interpreted in the following way (all constants are
+ * preceded by KRB5_TC_).  MATCH_IS_SKEY requires the is_skey field to
+ * match exactly.  MATCH_TIMES requires the requested lifetime to be
+ * at least as great as that specified; MATCH_TIMES_EXACT requires the
+ * requested lifetime to be exactly that specified.  MATCH_FLAGS
+ * requires only the set bits in mcreds be set in creds;
+ * MATCH_FLAGS_EXACT requires all bits to match.
+ *
+ * Flag SUPPORTED_KTYPES means check all matching entries that have
+ * any supported enctype (according to tgs_enctypes) and return the one
+ * with the enctype listed earliest.  Return CC_NOT_KTYPE if a match
+ * is found *except* for having a supported enctype.
+ *
+ * Errors:
+ * system errors
+ * permission errors
+ * KRB5_CC_NOMEM
+ * KRB5_CC_NOT_KTYPE
+ */
+
+static krb5_error_code
+krb5_cc_retrieve_cred_seq (context, id, whichfields,
+                          mcreds, creds, nktypes, ktypes)
+   krb5_context context;
+   krb5_ccache id;
+   krb5_flags whichfields;
+   krb5_creds *mcreds;
+   krb5_creds *creds;
+   int nktypes;
+   krb5_enctype *ktypes;
+{
+     /* This function could be considerably faster if it kept indexing */
+     /* information.. sounds like a "next version" idea to me. :-) */
+
+     krb5_cc_cursor cursor;
+     krb5_error_code kret;
+     krb5_error_code nomatch_err = KRB5_CC_NOTFOUND;
+     struct {
+       krb5_creds creds;
+       int pref;
+     } fetched, best;
+     int have_creds = 0;
+#define fetchcreds (fetched.creds)
+
+     kret = krb5_cc_start_seq_get(context, id, &cursor);
+     if (kret != KRB5_OK)
+         return kret;
+
+     while ((kret = krb5_cc_next_cred(context, id, &cursor, &fetchcreds)) == KRB5_OK) {
+        if (((set(KRB5_TC_MATCH_SRV_NAMEONLY) &&
+                  srvname_match(context, mcreds, &fetchcreds)) ||
+              standard_fields_match(context, mcreds, &fetchcreds))
+             &&
+             (! set(KRB5_TC_MATCH_IS_SKEY) ||
+              mcreds->is_skey == fetchcreds.is_skey)
+             &&
+             (! set(KRB5_TC_MATCH_FLAGS_EXACT) ||
+              mcreds->ticket_flags == fetchcreds.ticket_flags)
+             &&
+             (! set(KRB5_TC_MATCH_FLAGS) ||
+              flags_match(mcreds->ticket_flags, fetchcreds.ticket_flags))
+             &&
+             (! set(KRB5_TC_MATCH_TIMES_EXACT) ||
+              times_match_exact(&mcreds->times, &fetchcreds.times))
+             &&
+             (! set(KRB5_TC_MATCH_TIMES) ||
+              times_match(&mcreds->times, &fetchcreds.times))
+             &&
+             ( ! set(KRB5_TC_MATCH_AUTHDATA) ||
+              authdata_match(mcreds->authdata, fetchcreds.authdata))
+             &&
+             (! set(KRB5_TC_MATCH_2ND_TKT) ||
+              data_match (&mcreds->second_ticket, &fetchcreds.second_ticket))
+             &&
+            ((! set(KRB5_TC_MATCH_KTYPE))||
+               (mcreds->keyblock.enctype == fetchcreds.keyblock.enctype)))
+         {
+             if (ktypes) {
+                 fetched.pref = pref (fetchcreds.keyblock.enctype,
+                                      nktypes, ktypes);
+                 if (fetched.pref < 0)
+                     nomatch_err = KRB5_CC_NOT_KTYPE;
+                 else if (!have_creds || fetched.pref < best.pref) {
+                     if (have_creds)
+                         krb5_free_cred_contents (context, &best.creds);
+                     else
+                         have_creds = 1;
+                     best = fetched;
+                     continue;
+                 }
+             } else {
+                 krb5_cc_end_seq_get(context, id, &cursor);
+                 *creds = fetchcreds;
+                 return KRB5_OK;
+             }
+         }
+
+         /* This one doesn't match */
+         krb5_free_cred_contents(context, &fetchcreds);
+     }
+
+     /* If we get here, a match wasn't found */
+     krb5_cc_end_seq_get(context, id, &cursor);
+     if (have_creds) {
+        *creds = best.creds;
+        return KRB5_OK;
+     } else
+        return nomatch_err;
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_cc_retrieve_cred_default (context, id, flags, mcreds, creds)
+   krb5_context context;
+   krb5_ccache id;
+   krb5_flags flags;
+   krb5_creds *mcreds;
+   krb5_creds *creds;
+{
+    krb5_enctype *ktypes;
+    int nktypes;
+    krb5_error_code ret;
+
+    if (flags & KRB5_TC_SUPPORTED_KTYPES) {
+       ret = krb5_get_tgs_ktypes (context, mcreds->server, &ktypes);
+       if (ret)
+           return ret;
+       nktypes = 0;
+       while (ktypes[nktypes])
+           nktypes++;
+
+       ret = krb5_cc_retrieve_cred_seq (context, id, flags, mcreds, creds,
+                                        nktypes, ktypes);
+       free (ktypes);
+       return ret;
+    } else {
+       return krb5_cc_retrieve_cred_seq (context, id, flags, mcreds, creds,
+                                         0, 0);
+    }
+}
index dfe92f16ff96400f657b401cddae70f4ac60ec84..c6ca9f7eae135ccb307ddfe17438c92ec780523c 100644 (file)
@@ -1,3 +1,8 @@
+1999-08-23  Ken Raeburn  <raeburn@mit.edu>
+
+       * stdcc.c (krb5_stdcc_retrieve): Replace with a version that calls
+       krb5_cc_retrieve_cred_default.
+
 1999-08-05     Alexandra Ellwood <lxs@mit.edu>
 
        * stdcc_util.c (deep_free_cc_v5_creds):
index db93102cad8bfe0ef826451bda3830e8a919adee..18cc870b4a8b08bea0f78e6c4ce3b5561b86c314 100644 (file)
@@ -478,6 +478,7 @@ krb5_error_code KRB5_CALLCONV krb5_stdcc_next_cred
  *
  * - try to find a matching credential in the cache
  */
+#if 0
 krb5_error_code KRB5_CALLCONV krb5_stdcc_retrieve 
                        (krb5_context context, 
                   krb5_ccache id, 
@@ -523,6 +524,22 @@ krb5_error_code KRB5_CALLCONV krb5_stdcc_retrieve
        
        return KRB5_CC_NOTFOUND;
 }
+#else
+#include "k5-int.h"
+
+krb5_error_code KRB5_CALLCONV
+krb5_stdcc_retrieve(context, id, whichfields, mcreds, creds)
+   krb5_context context;
+   krb5_ccache id;
+   krb5_flags whichfields;
+   krb5_creds *mcreds;
+   krb5_creds *creds;
+{
+    return krb5_cc_retrieve_cred_default (context, id, whichfields,
+                                         mcreds, creds);
+}
+
+#endif
 
 /*
  *  end seq
index f99e78246022e0e2981aa3cd35b7d973f19a1534..0da5c9701b67f7738d26283474a0483347d56960 100644 (file)
@@ -1,3 +1,8 @@
+1999-08-23  Ken Raeburn  <raeburn@mit.edu>
+
+       * fcc_retrv.c (krb5_fcc_retrieve): Replace with a version that
+       calls krb5_cc_retrieve_cred_default.
+
 1999-06-10  Danilo Almeida  <dalmeida@mit.edu>
 
        * fcc_ops.c (krb5_cache_change): Use PostMessage instead of 
index 5f4e71d7c63b5f6225c64dd1adce298b799b2d50..c3d1f48cbba45fc25e27584f68ca03df04d3be57 100644 (file)
@@ -24,6 +24,8 @@
  * This file contains the source code for krb5_fcc_retrieve.
  */
 
+#if 0
+
 #include "fcc.h"
 
 #ifdef macintosh
@@ -230,3 +232,21 @@ authdata_match(mdata, data)
     }
     return (*mdata == NULL) && (*data == NULL);
 }
+
+#else
+
+#include "k5-int.h"
+
+krb5_error_code KRB5_CALLCONV
+krb5_fcc_retrieve(context, id, whichfields, mcreds, creds)
+   krb5_context context;
+   krb5_ccache id;
+   krb5_flags whichfields;
+   krb5_creds *mcreds;
+   krb5_creds *creds;
+{
+    return krb5_cc_retrieve_cred_default (context, id, whichfields,
+                                         mcreds, creds);
+}
+
+#endif
index 4ff0ffafd85369c049b417bdb76b9c7520c5b1a7..9a68c4118e4b75a2664f214cb2da4eca44a4433f 100644 (file)
@@ -1,3 +1,8 @@
+1999-08-23  Ken Raeburn  <raeburn@mit.edu>
+
+       * mcc_retrv.c (krb5_mcc_retrieve): Replace with a version that
+       calls krb5_cc_retrieve_cred_default.
+
 Mon May 10 15:25:06 1999  Danilo Almeida  <dalmeida@mit.edu>
 
        * Makefile.in: Do win32 build in subdir.
index ae3510129d9b81ccdbf5a6f0e9e70e0c3e8942d1..6ae6d290d5b3659fdab0a6355bbf45a2a0345798 100644 (file)
@@ -24,6 +24,8 @@
  * This file contains the source code for krb5_mcc_retrieve.
  */
 
+#if 0
+
 #include "mcc.h"
 
 #define set(bits) (whichfields & bits)
@@ -223,3 +225,21 @@ authdata_match(mdata, data)
     }
     return (*mdata == NULL) && (*data == NULL);
 }
+
+#else
+
+#include "k5-int.h"
+
+krb5_error_code KRB5_CALLCONV
+krb5_mcc_retrieve(context, id, whichfields, mcreds, creds)
+   krb5_context context;
+   krb5_ccache id;
+   krb5_flags whichfields;
+   krb5_creds *mcreds;
+   krb5_creds *creds;
+{
+    return krb5_cc_retrieve_cred_default (context, id, whichfields,
+                                         mcreds, creds);
+}
+
+#endif
index 5b7e7ea1a42bbd5370a55b2c74825e97ec64fb8e..9a402a46c2c24a91a88909a832ad6ed9bac052cb 100644 (file)
@@ -1,3 +1,8 @@
+1999-08-23  Ken Raeburn  <raeburn@mit.edu>
+
+       * scc_retrv.c (krb5_scc_retrieve): Replace with a version that
+       calls krb5_cc_retrieve_cred_default.
+
 1998-11-13  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
        * Makefile.in: Set the myfulldir and mydir variables (which are
index 7498d906e12c2412ce9e4c9200e9555f750ad2d0..00a7800978dd8f8c356c7df83e72fb3e0ffc4147 100644 (file)
@@ -24,6 +24,8 @@
  * This file contains the source code for krb5_scc_retrieve.
  */
 
+#if 0
+
 #include "scc.h"
 
 #define set(bits) (whichfields & bits)
@@ -217,3 +219,21 @@ krb5_scc_retrieve(context, id, whichfields, mcreds, creds)
      krb5_scc_end_seq_get(context, id, &cursor);
      return KRB5_CC_NOTFOUND;
 }
+
+#else
+
+#include "k5-int.h"
+
+krb5_error_code KRB5_CALLCONV
+krb5_scc_retrieve(context, id, whichfields, mcreds, creds)
+   krb5_context context;
+   krb5_ccache id;
+   krb5_flags whichfields;
+   krb5_creds *mcreds;
+   krb5_creds *creds;
+{
+    return krb5_cc_retrieve_cred_default (context, id, whichfields,
+                                         mcreds, creds);
+}
+
+#endif