void *gak_data,
k5_response_items *ritems)
{
- krb5_data *password;
+ struct gak_password *gp = gak_data;
krb5_error_code ret;
krb5_data defsalt;
char *clientstr;
- char promptstr[1024];
+ char promptstr[1024], pwbuf[1024];
+ krb5_data pw;
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')
+ if (gp->password != NULL)
return 0;
return k5_response_items_ask_question(ritems,
}
}
- if (password->data[0] == '\0') {
+ if (gp->password == NULL) {
/* 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);
+ ret = alloc_data(&gp->storage, strlen(rpass));
+ if (ret)
+ return ret;
+ memcpy(gp->storage.data, rpass, strlen(rpass));
+ gp->password = &gp->storage;
}
}
- if (password->data[0] == '\0') {
+ if (gp->password == NULL) {
if (prompter == NULL)
return(EIO);
clientstr);
free(clientstr);
+ pw = make_data(pwbuf, sizeof(pwbuf));
prompt.prompt = promptstr;
prompt.hidden = 1;
- prompt.reply = password;
+ prompt.reply = &pw;
prompt_type = KRB5_PROMPT_TYPE_PASSWORD;
/* PROMPTER_INVOCATION */
k5_set_prompt_types(context, 0);
if (ret)
return(ret);
+
+ ret = krb5int_copy_data_contents(context, &pw, &gp->storage);
+ zap(pw.data, pw.length);
+ if (ret)
+ return ret;
+ gp->password = &gp->storage;
}
if (salt == NULL) {
defsalt.length = 0;
}
- ret = krb5_c_string_to_key_with_params(context, etype, password, salt,
+ ret = krb5_c_string_to_key_with_params(context, etype, gp->password, salt,
params->data?params:NULL, as_key);
if (defsalt.length)
if (s == NULL)
return ENOMEM;
- if (ctx->password.data != NULL) {
- zap(ctx->password.data, ctx->password.length);
- krb5_free_data_contents(context, &ctx->password);
- }
-
- ctx->password.data = s;
- ctx->password.length = strlen(s);
+ zapfree(ctx->gakpw.storage.data, ctx->gakpw.storage.length);
+ ctx->gakpw.storage = string2data(s);
+ ctx->gakpw.password = &ctx->gakpw.storage;
ctx->gak_fct = krb5_get_as_key_password;
- ctx->gak_data = &ctx->password;
-
+ ctx->gak_data = &ctx->gakpw;
return 0;
}
int tries;
krb5_creds chpw_creds;
krb5_get_init_creds_opt *chpw_opts = NULL;
+ struct gak_password gakpw;
krb5_data pw0, pw1;
char banner[1024], pw0array[1024], pw1array[1024];
krb5_prompt prompt[2];
use_master = 0;
as_reply = NULL;
memset(&chpw_creds, 0, sizeof(chpw_creds));
+ memset(&gakpw, 0, sizeof(gakpw));
- pw0.data = pw0array;
-
- if (password && password[0]) {
- if (strlcpy(pw0.data, password, sizeof(pw0array)) >= sizeof(pw0array)) {
- ret = EINVAL;
- goto cleanup;
- }
- pw0.length = strlen(password);
- } else {
- pw0.data[0] = '\0';
- pw0.length = sizeof(pw0array);
+ if (password != NULL) {
+ pw0 = string2data((char *)password);
+ gakpw.password = &pw0;
}
- pw1.data = pw1array;
- pw1.data[0] = '\0';
- pw1.length = sizeof(pw1array);
-
/* first try: get the requested tkt from any kdc */
ret = k5_get_init_creds(context, creds, client, prompter, data, start_time,
in_tkt_service, options, krb5_get_as_key_password,
- (void *) &pw0, &use_master, &as_reply);
+ &gakpw, &use_master, &as_reply);
/* check for success */
}
ret = k5_get_init_creds(context, creds, client, prompter, data,
start_time, in_tkt_service, options,
- krb5_get_as_key_password, (void *) &pw0,
- &use_master, &as_reply);
+ krb5_get_as_key_password, &gakpw, &use_master,
+ &as_reply);
if (ret == 0)
goto cleanup;
ret = k5_get_init_creds(context, &chpw_creds, client, prompter, data,
start_time, "kadmin/changepw", chpw_opts,
- krb5_get_as_key_password, (void *) &pw0,
- &use_master, NULL);
+ krb5_get_as_key_password, &gakpw, &use_master,
+ NULL);
if (ret)
goto cleanup;
+ pw0.data = pw0array;
+ pw0.data[0] = '\0';
+ pw0.length = sizeof(pw0array);
prompt[0].prompt = _("Enter new password");
prompt[0].hidden = 1;
prompt[0].reply = &pw0;
prompt_types[0] = KRB5_PROMPT_TYPE_NEW_PASSWORD;
+ pw1.data = pw1array;
+ pw1.data[0] = '\0';
+ pw1.length = sizeof(pw1array);
prompt[1].prompt = _("Enter it again");
prompt[1].hidden = 1;
prompt[1].reply = &pw1;
is final. */
TRACE_GIC_PWD_CHANGED(context);
+ gakpw.password = &pw0;
ret = k5_get_init_creds(context, creds, client, prompter, data,
start_time, in_tkt_service, options,
- krb5_get_as_key_password, (void *) &pw0,
- &use_master, &as_reply);
+ krb5_get_as_key_password, &gakpw, &use_master,
+ &as_reply);
if (ret)
goto cleanup;
if (chpw_opts)
krb5_get_init_creds_opt_free(context, chpw_opts);
+ zapfree(gakpw.storage.data, gakpw.storage.length);
memset(pw0array, 0, sizeof(pw0array));
memset(pw1array, 0, sizeof(pw1array));
krb5_free_cred_contents(context, &chpw_creds);
krb5_creds *creds, krb5_kdc_rep **ret_as_reply)
{
krb5_error_code retval;
- krb5_data pw0;
- char pw0array[1024];
+ struct gak_password gakpw;
+ krb5_data pw;
char * server;
krb5_principal server_princ, client_princ;
int use_master = 0;
krb5_get_init_creds_opt *opts = NULL;
- pw0.data = pw0array;
- if (password && password[0]) {
- if (strlcpy(pw0.data, password, sizeof(pw0array)) >= sizeof(pw0array))
- return EINVAL;
- pw0.length = strlen(password);
- } else {
- pw0.data[0] = '\0';
- pw0.length = sizeof(pw0array);
+ memset(&gakpw, 0, sizeof(gakpw));
+ if (password != NULL) {
+ pw = string2data((char *)password);
+ gakpw.password = &pw;
}
retval = k5_populate_gic_opt(context, &opts, options, addrs, ktypes,
pre_auth_types, creds);
client_princ = creds->client;
retval = k5_get_init_creds(context, creds, creds->client,
krb5_prompter_posix, NULL, 0, server, opts,
- krb5_get_as_key_password, &pw0, &use_master,
+ krb5_get_as_key_password, &gakpw, &use_master,
ret_as_reply);
krb5_free_unparsed_name( context, server);
krb5_get_init_creds_opt_free(context, opts);
+ zapfree(gakpw.storage.data, gakpw.storage.length);
if (retval) {
return (retval);
}
--- /dev/null
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* tests/t_init_creds.c - test harness for getting initial creds */
+/*
+ * Copyright (C) 2013 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This program exercises the init_creds APIs in ways kinit doesn't. Right now
+ * it is very simplistic, but it can be extended as needed.
+ */
+
+#include <krb5.h>
+#include <stdio.h>
+
+static krb5_context ctx;
+
+static void
+check(krb5_error_code code)
+{
+ const char *errmsg;
+
+ if (code) {
+ errmsg = krb5_get_error_message(ctx, code);
+ fprintf(stderr, "%s\n", errmsg);
+ krb5_free_error_message(ctx, errmsg);
+ exit(1);
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *princstr, *password;
+ krb5_principal client;
+ krb5_init_creds_context icc;
+ krb5_creds creds;
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage: t_init_creds princname password\n");
+ exit(1);
+ }
+ princstr = argv[1];
+ password = argv[2];
+
+ check(krb5_init_context(&ctx));
+ check(krb5_parse_name(ctx, princstr, &client));
+
+ /* Try once with the traditional interface. */
+ check(krb5_get_init_creds_password(ctx, &creds, client, password, NULL,
+ NULL, 0, NULL, NULL));
+ krb5_free_cred_contents(ctx, &creds);
+
+ /* Try again with the step interface. */
+ check(krb5_init_creds_init(ctx, client, NULL, NULL, 0, NULL, &icc));
+ check(krb5_init_creds_set_password(ctx, icc, password));
+ check(krb5_init_creds_get(ctx, icc));
+ krb5_init_creds_free(ctx, icc);
+
+ krb5_free_principal(ctx, client);
+ krb5_free_context(ctx);
+ return 0;
+}