]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Implement KDC side cookie handling
authorSam Hartman <hartmans@mit.edu>
Fri, 3 Apr 2009 03:39:50 +0000 (03:39 +0000)
committerSam Hartman <hartmans@mit.edu>
Fri, 3 Apr 2009 03:39:50 +0000 (03:39 +0000)
Return a constant cookie in errors to indicate that clients should
continue their conversations.

git-svn-id: svn://anonsvn.mit.edu/krb5/branches/fast@22163 dc483132-0cff-0310-8789-dd5450dbe970

src/kdc/fast_util.c
src/kdc/kdc_preauth.c
src/kdc/kdc_util.h

index a95398e0a478cec1b7a4228323471fef9846d06b..da965f591a2a632b8046d36f8d0d028786f172a0 100644 (file)
@@ -342,8 +342,8 @@ krb5_error_code kdc_fast_handle_error
     krb5_fast_response resp;
     krb5_error fx_error;
     krb5_data *encoded_fx_error = NULL, *encrypted_reply = NULL;
-    krb5_pa_data pa[2];
-    krb5_pa_data *outer_pa[3];
+    krb5_pa_data pa[1];
+    krb5_pa_data *outer_pa[3], *cookie = NULL;
     krb5_pa_data **inner_pa = NULL;
     size_t size = 0;
     krb5_data *encoded_e_data = NULL;
@@ -369,7 +369,13 @@ krb5_error_code kdc_fast_handle_error
        pa[0].length = encoded_fx_error->length;
        pa[0].contents = (unsigned char *) encoded_fx_error->data;
        inner_pa[size++] = &pa[0];
-       resp.padata = inner_pa;
+       if (find_pa_data(inner_pa, KRB5_PADATA_FX_COOKIE) == NULL)
+           retval = kdc_preauth_get_cookie(state, &cookie);
+    }
+    if (cookie != NULL)
+       inner_pa[size++] = cookie;
+    if (retval == 0) {
+               resp.padata = inner_pa;
        resp.nonce = request->nonce;
        resp.rep_key = NULL;
        resp.finished = NULL;
@@ -378,6 +384,11 @@ krb5_error_code kdc_fast_handle_error
        retval = encrypt_fast_reply(state, &resp, &encrypted_reply);
     if (inner_pa)
        free(inner_pa); /*contained storage from caller and our stack*/
+    if (cookie) {
+       free(cookie->contents);
+       free(cookie);
+       cookie = NULL;
+    }
     if (retval == 0) {
        pa[0].pa_type = KRB5_PADATA_FX_FAST;
        pa[0].length = encrypted_reply->length;
@@ -399,3 +410,30 @@ krb5_error_code kdc_fast_handle_error
        krb5_free_data(kdc_context, encoded_fx_error);
     return retval;
 }
+
+krb5_error_code kdc_preauth_get_cookie(struct kdc_request_state *state,
+                                   krb5_pa_data **cookie)
+{
+    char *contents;
+    krb5_pa_data *pa = NULL;
+    /* In our current implementation, the only purpose served by
+     * returning a cookie is to indicate that a conversation should
+     * continue on error.  Thus, the cookie can have a constant
+     * string.  If cookies are used for real, versioning so that KDCs
+     * can be upgraded, keying, expiration and many other issues need
+     * to be considered.
+     */
+    contents = strdup("MIT");
+    if (contents == NULL)
+       return ENOMEM;
+    pa = calloc(1, sizeof(krb5_pa_data));
+    if (pa == NULL) {
+       free(contents);
+       return ENOMEM;
+    }
+    pa->pa_type = KRB5_PADATA_FX_COOKIE;
+    pa->length = strlen(contents);
+    pa->contents = (unsigned char *) contents;
+    *cookie = pa;
+    return 0;
+}
index cf269753d1d4e782cf74908acbab191f2bb44e36..22ebe5393ceadb6dbbb7cc614dadae17145caa3b 100644 (file)
@@ -961,7 +961,8 @@ void get_preauth_hint_list(krb5_kdc_req *request, krb5_db_entry *client,
     e_data->data = 0;
     
     hw_only = isflagset(client->attributes, KRB5_KDB_REQUIRES_HW_AUTH);
-    pa_data = malloc(sizeof(krb5_pa_data *) * (n_preauth_systems+1));
+    /* Allocate 1 entry for the terminator and one for the cookie*/
+    pa_data = malloc(sizeof(krb5_pa_data *) * (n_preauth_systems+21));
     if (pa_data == 0)
        return;
     memset(pa_data, 0, sizeof(krb5_pa_data *) * (n_preauth_systems+1));
@@ -995,6 +996,8 @@ void get_preauth_hint_list(krb5_kdc_req *request, krb5_db_entry *client,
                          "%spreauth required but hint list is empty",
                          hw_only ? "hw" : "");
     }
+/* If we fail to get the cookie it is probably still reasonable to continue with the response*/
+    kdc_preauth_get_cookie(request->kdc_state, pa);
     retval = encode_krb5_padata_sequence(pa_data, &edat);
     if (retval)
        goto errout;
index 90de8d39b7aa9694a2ba295e9b9ff9412baf06ff..e9ccc4477dc3c37440c96fb041027cec8c89b21c 100644 (file)
@@ -331,6 +331,9 @@ krb5_error_code kdc_fast_handle_error
  krb5_kdc_req *request,
  krb5_pa_data  **in_padata, krb5_error *err);
 
+krb5_error_code kdc_preauth_get_cookie(struct kdc_request_state *state,
+                                   krb5_pa_data **cookie);
+