svn rev #25292: trunk/src/kdc/

ghudson@MIT.EDU ghudson at MIT.EDU
Mon Oct 3 15:13:58 EDT 2011


http://src.mit.edu/fisheye/changelog/krb5/?cs=25292
Commit By: ghudson
Log Message:
Make do_as_req() respond via a callback.

>From npmccallum at redhat.com with changes.


Changed Files:
U   trunk/src/kdc/dispatch.c
U   trunk/src/kdc/do_as_req.c
U   trunk/src/kdc/kdc_util.h
Modified: trunk/src/kdc/dispatch.c
===================================================================
--- trunk/src/kdc/dispatch.c	2011-10-03 19:13:39 UTC (rev 25291)
+++ trunk/src/kdc/dispatch.c	2011-10-03 19:13:57 UTC (rev 25292)
@@ -36,6 +36,45 @@
 
 static krb5_error_code make_too_big_error (krb5_data **out);
 
+struct dispatch_state {
+    loop_respond_fn respond;
+    void *arg;
+    krb5_data *request;
+    int is_tcp;
+};
+
+static void
+finish_dispatch(void *arg, krb5_error_code code, krb5_data *response)
+{
+    struct dispatch_state *state = arg;
+    loop_respond_fn oldrespond;
+    void *oldarg;
+
+    assert(state);
+    oldrespond = state->respond;
+    oldarg = state->arg;
+
+    if (state->is_tcp == 0 && response &&
+        response->length > max_dgram_reply_size) {
+        krb5_free_data(kdc_context, response);
+        response = NULL;
+        code = make_too_big_error(&response);
+        if (code)
+            krb5_klog_syslog(LOG_ERR, "error constructing "
+                             "KRB_ERR_RESPONSE_TOO_BIG error: %s",
+                             error_message(code));
+    }
+
+#ifndef NOCACHE
+    /* put the response into the lookaside buffer */
+    else if (!code)
+        kdc_insert_lookaside(state->request, response);
+#endif
+
+    free(state);
+    (*oldrespond)(oldarg, code, response);
+}
+
 void
 dispatch(void *cb, struct sockaddr *local_saddr, const krb5_fulladdr *from,
          krb5_data *pkt, int is_tcp, loop_respond_fn respond, void *arg)
@@ -43,8 +82,19 @@
     krb5_error_code retval;
     krb5_kdc_req *as_req;
     krb5_int32 now, now_usec;
-    krb5_data *response;
+    krb5_data *response = NULL;
+    struct dispatch_state *state;
 
+    state = malloc(sizeof(*state));
+    if (!state) {
+        (*respond)(arg, ENOMEM, NULL);
+        return;
+    }
+    state->respond = respond;
+    state->arg = arg;
+    state->request = pkt;
+    state->is_tcp = is_tcp;
+
     /* decode incoming packet, and dispatch */
 
 #ifndef NOCACHE
@@ -54,20 +104,22 @@
         const char *name = 0;
         char buf[46];
 
-        if (is_tcp == 0 && response->length > max_dgram_reply_size)
-            goto too_big_for_udp;
+        if (is_tcp != 0 || response->length <= max_dgram_reply_size) {
+            name = inet_ntop (ADDRTYPE2FAMILY (from->address->addrtype),
+                              from->address->contents, buf, sizeof (buf));
+            if (name == 0)
+                name = "[unknown address type]";
+            krb5_klog_syslog(LOG_INFO,
+                             "DISPATCH: repeated (retransmitted?) request "
+                             "from %s, resending previous response",
+                             name);
+        }
 
-        name = inet_ntop (ADDRTYPE2FAMILY (from->address->addrtype),
-                          from->address->contents, buf, sizeof (buf));
-        if (name == 0)
-            name = "[unknown address type]";
-        krb5_klog_syslog(LOG_INFO,
-                         "DISPATCH: repeated (retransmitted?) request from %s, resending previous response",
-                         name);
-        (*respond)(arg, 0, response);
+        finish_dispatch(state, 0, response);
         return;
     }
 #endif
+
     retval = krb5_crypto_us_timeofday(&now, &now_usec);
     if (retval == 0) {
         krb5_int32 usec_difference = now_usec-last_usec;
@@ -99,32 +151,16 @@
              * process_as_req frees the request if it is called
              */
             if (!(retval = setup_server_realm(as_req->server))) {
-                retval = process_as_req(as_req, pkt, from, &response);
+                process_as_req(as_req, pkt, from, finish_dispatch, state);
+                return;
             }
-            else            krb5_free_kdc_req(kdc_context, as_req);
+            else
+                krb5_free_kdc_req(kdc_context, as_req);
         }
-    }
-    else
+    } else
         retval = KRB5KRB_AP_ERR_MSG_TYPE;
-#ifndef NOCACHE
-    /* put the response into the lookaside buffer */
-    if (!retval)
-        kdc_insert_lookaside(pkt, response);
-#endif
 
-    if (is_tcp == 0 && response != NULL &&
-        response->length > max_dgram_reply_size) {
-    too_big_for_udp:
-        krb5_free_data(kdc_context, response);
-        retval = make_too_big_error(&response);
-        if (retval) {
-            krb5_klog_syslog(LOG_ERR,
-                             "error constructing KRB_ERR_RESPONSE_TOO_BIG error: %s",
-                             error_message(retval));
-        }
-    }
-
-    (*respond)(arg, retval, retval == 0 ? response : NULL);
+    finish_dispatch(state, retval, response);
 }
 
 static krb5_error_code

Modified: trunk/src/kdc/do_as_req.c
===================================================================
--- trunk/src/kdc/do_as_req.c	2011-10-03 19:13:39 UTC (rev 25291)
+++ trunk/src/kdc/do_as_req.c	2011-10-03 19:13:57 UTC (rev 25292)
@@ -99,9 +99,9 @@
 }
 
 /*ARGSUSED*/
-krb5_error_code
+void
 process_as_req(krb5_kdc_req *request, krb5_data *req_pkt,
-               const krb5_fulladdr *from, krb5_data **response)
+               const krb5_fulladdr *from, loop_respond_fn respond, void *arg)
 {
     krb5_db_entry *client = NULL, *server = NULL;
     krb5_kdc_rep reply;
@@ -127,6 +127,7 @@
     struct kdc_request_state *state = NULL;
     krb5_data encoded_req_body;
     krb5_keyblock *as_encrypting_key = NULL;
+    krb5_data *response;
 
 
 #if APPLE_PKINIT
@@ -593,7 +594,7 @@
     }
 
     errcode = krb5_encode_kdc_rep(kdc_context, KRB5_AS_REP, &reply_encpart,
-                                  0, as_encrypting_key,  &reply, response);
+                                  0, as_encrypting_key,  &reply, &response);
     reply.enc_part.kvno = client_key->key_data_kvno;
     if (errcode) {
         status = "ENCODE_KDC_REP";
@@ -639,11 +640,12 @@
 
         errcode = prepare_error_as(state, request, errcode, &e_data,
                                    (client != NULL) ? client->princ : NULL,
-                                   response, status);
+                                   &response, status);
         status = 0;
     }
 
-discard: if (emsg)
+discard:
+    if (emsg)
         krb5_free_error_message(kdc_context, emsg);
     if (enc_tkt_reply.authorization_data != NULL)
         krb5_free_authdata(kdc_context, enc_tkt_reply.authorization_data);
@@ -676,7 +678,7 @@
     krb5_free_kdc_req(kdc_context, request);
     assert(did_log != 0);
 
-    return errcode;
+    (*respond)(arg, errcode, response);
 }
 
 /*

Modified: trunk/src/kdc/kdc_util.h
===================================================================
--- trunk/src/kdc/kdc_util.h	2011-10-03 19:13:39 UTC (rev 25291)
+++ trunk/src/kdc/kdc_util.h	2011-10-03 19:13:57 UTC (rev 25292)
@@ -118,10 +118,10 @@
 rep_etypes2str(char *s, size_t len, krb5_kdc_rep *rep);
 
 /* do_as_req.c */
-krb5_error_code
+void
 process_as_req (krb5_kdc_req *, krb5_data *,
                 const krb5_fulladdr *,
-                krb5_data ** );
+                loop_respond_fn, void *);
 
 /* do_tgs_req.c */
 krb5_error_code




More information about the cvs-krb5 mailing list