]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Make AS requests work with no client key
authorGreg Hudson <ghudson@mit.edu>
Thu, 2 May 2013 20:15:32 +0000 (16:15 -0400)
committerGreg Hudson <ghudson@mit.edu>
Fri, 3 May 2013 20:11:28 +0000 (16:11 -0400)
If we cannot find a client key while preparing an AS reply, give
preauth mechanisms a chance to replace the reply key before erroring
out.

ticket: 7630

src/kdc/do_as_req.c
src/kdc/kdc_preauth.c

index 4f0fc2e63026623755994a33f43e84e2cf0a811a..def7075d7b474d64ddf59d4199e4b3460b75bfe6 100644 (file)
@@ -195,23 +195,18 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode)
                                    useenctype, -1, 0, &client_key))
             break;
     }
-    if (!(client_key)) {
-        /* Cannot find an appropriate key */
-        state->status = "CANT_FIND_CLIENT_KEY";
-        errcode = KRB5KDC_ERR_ETYPE_NOSUPP;
-        goto egress;
-    }
-    state->rock.client_key = client_key;
 
-    /* convert client.key_data into a real key */
-    if ((errcode = krb5_dbe_decrypt_key_data(kdc_context, NULL,
-                                             client_key,
-                                             &state->client_keyblock,
-                                             NULL))) {
-        state->status = "DECRYPT_CLIENT_KEY";
-        goto egress;
+    if (client_key != NULL) {
+        /* Decrypt the client key data entry to get the real reply key. */
+        errcode = krb5_dbe_decrypt_key_data(kdc_context, NULL, client_key,
+                                            &state->client_keyblock, NULL);
+        if (errcode) {
+            state->status = "DECRYPT_CLIENT_KEY";
+            goto egress;
+        }
+        state->client_keyblock.enctype = useenctype;
+        state->rock.client_key = client_key;
     }
-    state->client_keyblock.enctype = useenctype;
 
     /* Start assembling the response */
     state->reply.msg_type = KRB5_AS_REP;
@@ -248,6 +243,14 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode)
         goto egress;
     }
 
+    /* If we didn't find a client long-term key and no preauth mechanism
+     * replaced the reply key, error out now. */
+    if (state->client_keyblock.enctype == ENCTYPE_NULL) {
+        state->status = "CANT_FIND_CLIENT_KEY";
+        errcode = KRB5KDC_ERR_ETYPE_NOSUPP;
+        goto egress;
+    }
+
     errcode = handle_authdata(kdc_context,
                               state->c_flags,
                               state->client,
@@ -306,7 +309,8 @@ finish_process_as_req(struct as_req_state *state, krb5_error_code errcode)
                                   &state->reply_encpart, 0,
                                   as_encrypting_key,
                                   &state->reply, &response);
-    state->reply.enc_part.kvno = client_key->key_data_kvno;
+    if (client_key != NULL)
+        state->reply.enc_part.kvno = client_key->key_data_kvno;
     if (errcode) {
         state->status = "ENCODE_KDC_REP";
         goto egress;
index 9c04f709ca63a5987b4c68333f9de77ba3fc1968..c3543caaecbc41365c55a9625ca1ad9e549533e0 100644 (file)
@@ -1489,6 +1489,9 @@ etype_info_as_rep_helper(krb5_context context, krb5_pa_data * padata,
     krb5_etype_info_entry **entry = NULL;
     krb5_data *scratch = NULL;
 
+    if (client_key == NULL)
+        return 0;
+
     /*
      * Skip PA-ETYPE-INFO completely if AS-REQ lists any "newer"
      * enctypes.
@@ -1592,6 +1595,9 @@ return_pw_salt(krb5_context context, krb5_pa_data *in_padata,
     krb5_key_data *     client_key = rock->client_key;
     int i;
 
+    if (client_key == NULL)
+        return 0;
+
     for (i = 0; i < request->nktypes; i++) {
         if (enctype_requires_etype_info_2(request->ktype[i]))
             return 0;