summaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorNathaniel McCallum <npmccallum@redhat.com>2012-10-12 10:33:36 -0400
committerGreg Hudson <ghudson@mit.edu>2012-10-12 11:44:14 -0400
commit6f143d99b3668e6020a1525f839acac54934dbb5 (patch)
treef391697e9288ca7ddb10fc2b27655e96be06ba73 /src/lib
parent816c7b59c3869e004d4ad150c7f04d026bb42177 (diff)
downloadkrb5-6f143d99b3668e6020a1525f839acac54934dbb5.tar.gz
krb5-6f143d99b3668e6020a1525f839acac54934dbb5.tar.xz
krb5-6f143d99b3668e6020a1525f839acac54934dbb5.zip
Add responder support to get_as_key()
This follows the design laid out on the project page: http://k5wiki.kerberos.org/wiki/Projects/Password_response_item
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/krb5/krb/get_in_tkt.c2
-rw-r--r--src/lib/krb5/krb/gic_keytab.c7
-rw-r--r--src/lib/krb5/krb/gic_pwd.c29
-rw-r--r--src/lib/krb5/krb/init_creds_ctx.h3
-rw-r--r--src/lib/krb5/krb/preauth2.c20
-rw-r--r--src/lib/krb5/krb/preauth_sam2.c2
6 files changed, 55 insertions, 8 deletions
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index d52147ac26..01eba6b040 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -1458,7 +1458,7 @@ init_creds_step_reply(krb5_context context,
ctx->reply->enc_part.enctype,
ctx->prompter, ctx->prompter_data,
&ctx->salt, &ctx->s2kparams,
- &ctx->as_key, ctx->gak_data);
+ &ctx->as_key, ctx->gak_data, NULL);
if (code != 0)
goto cleanup;
TRACE_INIT_CREDS_AS_KEY_GAK(context, &ctx->as_key);
diff --git a/src/lib/krb5/krb/gic_keytab.c b/src/lib/krb5/krb/gic_keytab.c
index 38051dbfdb..0fd1034a38 100644
--- a/src/lib/krb5/krb/gic_keytab.c
+++ b/src/lib/krb5/krb/gic_keytab.c
@@ -38,13 +38,18 @@ get_as_key_keytab(krb5_context context,
krb5_data *salt,
krb5_data *params,
krb5_keyblock *as_key,
- void *gak_data)
+ void *gak_data,
+ k5_response_items *ritems)
{
krb5_keytab keytab = (krb5_keytab) gak_data;
krb5_error_code ret;
krb5_keytab_entry kt_ent;
krb5_keyblock *kt_key;
+ /* We don't need the password from the responder to create the AS key. */
+ if (as_key == NULL)
+ return 0;
+
/* if there's already a key of the correct etype, we're done.
if the etype is wrong, free the existing key, and make
a new one. */
diff --git a/src/lib/krb5/krb/gic_pwd.c b/src/lib/krb5/krb/gic_pwd.c
index f5c0b30278..8ffa342be6 100644
--- a/src/lib/krb5/krb/gic_pwd.c
+++ b/src/lib/krb5/krb/gic_pwd.c
@@ -2,6 +2,7 @@
#include "k5-int.h"
#include "com_err.h"
#include "init_creds_ctx.h"
+#include "int-proto.h"
krb5_error_code
krb5_get_as_key_password(krb5_context context,
@@ -12,7 +13,8 @@ krb5_get_as_key_password(krb5_context context,
krb5_data *salt,
krb5_data *params,
krb5_keyblock *as_key,
- void *gak_data)
+ void *gak_data,
+ k5_response_items *ritems)
{
krb5_data *password;
krb5_error_code ret;
@@ -21,8 +23,21 @@ krb5_get_as_key_password(krb5_context context,
char promptstr[1024];
krb5_prompt prompt;
krb5_prompt_type prompt_type;
+ const char *rpass;
password = (krb5_data *) gak_data;
+ assert(password->length > 0);
+
+ /* If we need to get the AS key via the responder, ask for it. */
+ if (as_key == NULL) {
+ /* However, if we already have a password, don't ask. */
+ if (password->data[0] != '\0')
+ return 0;
+
+ return k5_response_items_ask_question(ritems,
+ KRB5_RESPONDER_QUESTION_PASSWORD,
+ NULL );
+ }
/* If there's already a key of the correct etype, we're done.
If the etype is wrong, free the existing key, and make
@@ -39,7 +54,17 @@ krb5_get_as_key_password(krb5_context context,
}
}
- if (password->length == 0 || password->data[0] == '\0') {
+ if (password->data[0] == '\0') {
+ /* Check the responder for the password. */
+ rpass = k5_response_items_get_answer(ritems,
+ KRB5_RESPONDER_QUESTION_PASSWORD);
+ if (rpass != NULL) {
+ strlcpy(password->data, rpass, password->length);
+ password->length = strlen(password->data);
+ }
+ }
+
+ if (password->data[0] == '\0') {
if (prompter == NULL)
return(EIO);
diff --git a/src/lib/krb5/krb/init_creds_ctx.h b/src/lib/krb5/krb/init_creds_ctx.h
index ae69ed0828..eb7b608c44 100644
--- a/src/lib/krb5/krb/init_creds_ctx.h
+++ b/src/lib/krb5/krb/init_creds_ctx.h
@@ -58,6 +58,7 @@ krb5_get_as_key_password(krb5_context context,
krb5_data *salt,
krb5_data *params,
krb5_keyblock *as_key,
- void *gak_data);
+ void *gak_data,
+ k5_response_items *ritems);
#endif /* !KRB5_INIT_CREDS_CONTEXT */
diff --git a/src/lib/krb5/krb/preauth2.c b/src/lib/krb5/krb/preauth2.c
index cf46845e2e..1ee53a6b72 100644
--- a/src/lib/krb5/krb/preauth2.c
+++ b/src/lib/krb5/krb/preauth2.c
@@ -372,7 +372,8 @@ get_as_key(krb5_context context, krb5_clpreauth_rock rock,
salt = (*rock->default_salt) ? NULL : rock->salt;
ret = (*rock->gak_fct)(context, rock->client, *rock->etype,
rock->prompter, rock->prompter_data, salt,
- rock->s2kparams, rock->as_key, *rock->gak_data);
+ rock->s2kparams, rock->as_key, *rock->gak_data,
+ rock->rctx.items);
if (ret)
return ret;
}
@@ -410,6 +411,9 @@ static krb5_error_code
responder_ask_question(krb5_context context, krb5_clpreauth_rock rock,
const char *question, const char *challenge)
{
+ /* Force plugins to use need_as_key(). */
+ if (strcmp(KRB5_RESPONDER_QUESTION_PASSWORD, question) == 0)
+ return EINVAL;
return k5_response_items_ask_question(rock->rctx.items, question,
challenge);
}
@@ -418,9 +422,20 @@ static const char *
responder_get_answer(krb5_context context, krb5_clpreauth_rock rock,
const char *question)
{
+ /* Don't let plugins get the raw password. */
+ if (question && strcmp(KRB5_RESPONDER_QUESTION_PASSWORD, question) == 0)
+ return NULL;
return k5_response_items_get_answer(rock->rctx.items, question);
}
+static void
+need_as_key(krb5_context context, krb5_clpreauth_rock rock)
+{
+ /* Calling gac_fct() with NULL as_key indicates desire for the AS key. */
+ (*rock->gak_fct)(context, rock->client, *rock->etype, NULL, NULL, NULL,
+ NULL, NULL, *rock->gak_data, rock->rctx.items);
+}
+
static struct krb5_clpreauth_callbacks_st callbacks = {
2,
get_etype,
@@ -429,7 +444,8 @@ static struct krb5_clpreauth_callbacks_st callbacks = {
set_as_key,
get_preauth_time,
responder_ask_question,
- responder_get_answer
+ responder_get_answer,
+ need_as_key
};
/* Tweak the request body, for now adding any enctypes which the module claims
diff --git a/src/lib/krb5/krb/preauth_sam2.c b/src/lib/krb5/krb/preauth_sam2.c
index 4c63ff42c2..0190137e96 100644
--- a/src/lib/krb5/krb/preauth_sam2.c
+++ b/src/lib/krb5/krb/preauth_sam2.c
@@ -155,7 +155,7 @@ sam2_process(krb5_context context, krb5_clpreauth_moddata moddata,
retval = (*rock->gak_fct)(context, request->client, sc2b->sam_etype,
prompter, prompter_data, rock->salt,
rock->s2kparams, rock->as_key,
- *rock->gak_data);
+ *rock->gak_data, rock->rctx.items);
if (retval) {
krb5_free_sam_challenge_2(context, sc2);
krb5_free_sam_challenge_2_body(context, sc2b);