]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
In iakerb_acceptor_step(), avoid the use of goto for looping, and fix
authorGreg Hudson <ghudson@mit.edu>
Fri, 30 Apr 2010 20:50:42 +0000 (20:50 +0000)
committerGreg Hudson <ghudson@mit.edu>
Fri, 30 Apr 2010 20:50:42 +0000 (20:50 +0000)
a memory leak and possible double-free in some error cases.  Also fold
some function calls into fewer lines.

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

src/lib/gssapi/krb5/iakerb.c

index 5e0a2c02157cb2d0afea2104f10a5199845458d4..3463a7f711d184d73ab08ad7ec09d1acc00335e4 100644 (file)
@@ -321,31 +321,22 @@ iakerb_acceptor_step(iakerb_ctx_id_t ctx,
                      gss_buffer_t output_token)
 {
     krb5_error_code code;
-    krb5_data request, reply, realm;
+    krb5_data request = empty_data(), reply = empty_data();
+    krb5_data realm = empty_data();
     OM_uint32 tmp;
-    int tcpOnly = 0, useMaster;
+    int tcp_only, use_master;
+    krb5_ui_4 kdc_code;
 
     output_token->length = 0;
     output_token->value = NULL;
 
-    request.data = NULL;
-    request.length = 0;
-    reply.data = NULL;
-    reply.length = 0;
-    realm.data = NULL;
-    realm.length = 0;
-
     if (ctx->count >= IAKERB_MAX_HOPS) {
         code = KRB5_KDC_UNREACH;
         goto cleanup;
     }
 
-    code = iakerb_parse_token(ctx,
-                              initialContextToken,
-                              input_token,
-                              &realm,
-                              NULL,
-                              &request);
+    code = iakerb_parse_token(ctx, initialContextToken, input_token, &realm,
+                              NULL, &request);
     if (code != 0)
         goto cleanup;
 
@@ -358,10 +349,27 @@ iakerb_acceptor_step(iakerb_ctx_id_t ctx,
     if (code != 0)
         goto cleanup;
 
-send_again:
-    useMaster = 0;
-    code = krb5_sendto_kdc(ctx->k5c, &request, &realm,
-                           &reply, &useMaster, tcpOnly);
+    for (tcp_only = 0; tcp_only <= 1; tcp_only++) {
+        use_master = 0;
+        code = krb5_sendto_kdc(ctx->k5c, &request, &realm,
+                               &reply, &use_master, tcp_only);
+        if (code == 0 && krb5_is_krb_error(&reply)) {
+            krb5_error *error;
+
+            code = decode_krb5_error(&reply, &error);
+            if (code != 0)
+                goto cleanup;
+            kdc_code = error->error;
+            krb5_free_error(ctx->k5c, error);
+            if (kdc_code == KRB_ERR_RESPONSE_TOO_BIG) {
+                krb5_free_data_contents(ctx->k5c, &reply);
+                reply = empty_data();
+                continue;
+            }
+        }
+        break;
+    }
+
     if (code == KRB5_KDC_UNREACH || code == KRB5_REALM_UNKNOWN) {
         krb5_error error;
 
@@ -374,25 +382,10 @@ send_again:
         code = krb5_mk_error(ctx->k5c, &error, &reply);
         if (code != 0)
             goto cleanup;
-    } else if (code == 0 && krb5_is_krb_error(&reply)) {
-        krb5_error *error;
-
-        code = decode_krb5_error(&reply, &error);
-        if (code != 0)
-            goto cleanup;
-
-        if (error && error->error == KRB_ERR_RESPONSE_TOO_BIG &&
-            tcpOnly == 0) {
-            tcpOnly = 1;
-            krb5_free_error(ctx->k5c, error);
-            krb5_free_data_contents(ctx->k5c, &reply);
-            goto send_again;
-        }
     } else if (code != 0)
         goto cleanup;
 
-    code = iakerb_make_token(ctx, &realm, NULL, &reply,
-                             0, output_token);
+    code = iakerb_make_token(ctx, &realm, NULL, &reply, 0, output_token);
     if (code != 0)
         goto cleanup;