-/* $OpenBSD: auth2-chall.c,v 1.34 2008/12/09 04:32:22 djm Exp $ */
+/* $OpenBSD: auth2-chall.c,v 1.43 2015/07/18 07:57:14 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2001 Per Allansson. All rights reserved.
#include "packet.h"
#include "dispatch.h"
#include "log.h"
+#include "misc.h"
#include "servconf.h"
/* import */
static int auth2_challenge_start(Authctxt *);
static int send_userauth_info_request(Authctxt *);
-static void input_userauth_info_response(int, u_int32_t, void *);
+static int input_userauth_info_response(int, u_int32_t, void *);
#ifdef BSD_AUTH
extern KbdintDevice bsdauth_device;
void *ctxt;
KbdintDevice *device;
u_int nreq;
+ u_int devices_done;
};
#ifdef USE_PAM
remove_kbdint_device("pam");
#endif
- kbdintctxt = xmalloc(sizeof(KbdintAuthctxt));
+ kbdintctxt = xcalloc(1, sizeof(KbdintAuthctxt));
if (strcmp(devs, "") == 0) {
buffer_init(&b);
for (i = 0; devices[i]; i++) {
{
if (kbdintctxt->device)
kbdint_reset_device(kbdintctxt);
- if (kbdintctxt->devices) {
- xfree(kbdintctxt->devices);
- kbdintctxt->devices = NULL;
- }
- xfree(kbdintctxt);
+ free(kbdintctxt->devices);
+ explicit_bzero(kbdintctxt, sizeof(*kbdintctxt));
+ free(kbdintctxt);
}
/* get next device */
static int
-kbdint_next_device(KbdintAuthctxt *kbdintctxt)
+kbdint_next_device(Authctxt *authctxt, KbdintAuthctxt *kbdintctxt)
{
size_t len;
char *t;
if (len == 0)
break;
- for (i = 0; devices[i]; i++)
- if (strncmp(kbdintctxt->devices, devices[i]->name, len) == 0)
+ for (i = 0; devices[i]; i++) {
+ if ((kbdintctxt->devices_done & (1 << i)) != 0 ||
+ !auth2_method_allowed(authctxt,
+ "keyboard-interactive", devices[i]->name))
+ continue;
+ if (strncmp(kbdintctxt->devices, devices[i]->name,
+ len) == 0) {
kbdintctxt->device = devices[i];
+ kbdintctxt->devices_done |= 1 << i;
+ }
+ }
t = kbdintctxt->devices;
kbdintctxt->devices = t[len] ? xstrdup(t+len+1) : NULL;
- xfree(t);
+ free(t);
debug2("kbdint_next_device: devices %s", kbdintctxt->devices ?
kbdintctxt->devices : "<empty>");
} while (kbdintctxt->devices && !kbdintctxt->device);
debug2("auth2_challenge_start: devices %s",
kbdintctxt->devices ? kbdintctxt->devices : "<empty>");
- if (kbdint_next_device(kbdintctxt) == 0) {
+ if (kbdint_next_device(authctxt, kbdintctxt) == 0) {
auth2_challenge_stop(authctxt);
return 0;
}
packet_write_wait();
for (i = 0; i < kbdintctxt->nreq; i++)
- xfree(prompts[i]);
- xfree(prompts);
- xfree(echo_on);
- xfree(name);
- xfree(instr);
+ free(prompts[i]);
+ free(prompts);
+ free(echo_on);
+ free(name);
+ free(instr);
return 1;
}
-static void
+static int
input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
{
Authctxt *authctxt = ctxt;
KbdintAuthctxt *kbdintctxt;
int authenticated = 0, res;
u_int i, nresp;
- char **response = NULL, *method;
+ const char *devicename = NULL;
+ char **response = NULL;
if (authctxt == NULL)
fatal("input_userauth_info_response: no authctxt");
res = kbdintctxt->device->respond(kbdintctxt->ctxt, nresp, response);
for (i = 0; i < nresp; i++) {
- memset(response[i], 'r', strlen(response[i]));
- xfree(response[i]);
+ explicit_bzero(response[i], strlen(response[i]));
+ free(response[i]);
}
- if (response)
- xfree(response);
+ free(response);
switch (res) {
case 0:
/* Failure! */
break;
}
-
- xasprintf(&method, "keyboard-interactive/%s", kbdintctxt->device->name);
-
+ devicename = kbdintctxt->device->name;
if (!authctxt->postponed) {
if (authenticated) {
auth2_challenge_stop(authctxt);
auth2_challenge_start(authctxt);
}
}
- userauth_finish(authctxt, authenticated, method);
- xfree(method);
+ userauth_finish(authctxt, authenticated, "keyboard-interactive",
+ devicename);
+ return 0;
}
void