auth-chall.c revision 112870
176259Sgreen/*
276259Sgreen * Copyright (c) 2001 Markus Friedl.  All rights reserved.
376259Sgreen *
476259Sgreen * Redistribution and use in source and binary forms, with or without
576259Sgreen * modification, are permitted provided that the following conditions
676259Sgreen * are met:
776259Sgreen * 1. Redistributions of source code must retain the above copyright
876259Sgreen *    notice, this list of conditions and the following disclaimer.
976259Sgreen * 2. Redistributions in binary form must reproduce the above copyright
1076259Sgreen *    notice, this list of conditions and the following disclaimer in the
1176259Sgreen *    documentation and/or other materials provided with the distribution.
1276259Sgreen *
1376259Sgreen * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1476259Sgreen * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1576259Sgreen * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1676259Sgreen * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1776259Sgreen * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
1876259Sgreen * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1976259Sgreen * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2076259Sgreen * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2176259Sgreen * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2276259Sgreen * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2376259Sgreen */
2476259Sgreen
2576259Sgreen#include "includes.h"
2692559SdesRCSID("$OpenBSD: auth-chall.c,v 1.8 2001/05/18 14:13:28 markus Exp $");
27110138SdesRCSID("$FreeBSD: head/crypto/openssh/auth-chall.c 112870 2003-03-31 13:45:36Z des $");
2876259Sgreen
2976259Sgreen#include "auth.h"
3076259Sgreen#include "log.h"
3192559Sdes#include "xmalloc.h"
3276259Sgreen
3392559Sdes/* limited protocol v1 interface to kbd-interactive authentication */
3492559Sdes
3592559Sdesextern KbdintDevice *devices[];
3692559Sdesstatic KbdintDevice *device;
3792559Sdes
3876259Sgreenchar *
3992559Sdesget_challenge(Authctxt *authctxt)
4076259Sgreen{
4192559Sdes	char *challenge, *name, *info, **prompts;
4292559Sdes	u_int i, numprompts;
4392559Sdes	u_int *echo_on;
4476259Sgreen
4592559Sdes	device = devices[0]; /* we always use the 1st device for protocol 1 */
4692559Sdes	if (device == NULL)
4792559Sdes		return NULL;
4892559Sdes	if ((authctxt->kbdintctxt = device->init_ctx(authctxt)) == NULL)
4992559Sdes		return NULL;
5092559Sdes	if (device->query(authctxt->kbdintctxt, &name, &info,
5192559Sdes	    &numprompts, &prompts, &echo_on)) {
5292559Sdes		device->free_ctx(authctxt->kbdintctxt);
5392559Sdes		authctxt->kbdintctxt = NULL;
5492559Sdes		return NULL;
5576259Sgreen	}
5692559Sdes	if (numprompts < 1)
5792559Sdes		fatal("get_challenge: numprompts < 1");
5892559Sdes	challenge = xstrdup(prompts[0]);
5992559Sdes	for (i = 0; i < numprompts; i++)
6092559Sdes		xfree(prompts[i]);
6192559Sdes	xfree(prompts);
6292559Sdes	xfree(name);
6392559Sdes	xfree(echo_on);
6492559Sdes	xfree(info);
6592559Sdes
6692559Sdes	return (challenge);
6776259Sgreen}
6876259Sgreenint
6992559Sdesverify_response(Authctxt *authctxt, const char *response)
7076259Sgreen{
7192559Sdes	char *resp[1];
7292559Sdes	int res;
7376259Sgreen
7492559Sdes	if (device == NULL)
7592559Sdes		return 0;
7692559Sdes	if (authctxt->kbdintctxt == NULL)
7792559Sdes		return 0;
7892559Sdes	resp[0] = (char *)response;
7992559Sdes	res = device->respond(authctxt->kbdintctxt, 1, resp);
80110138Sdes	if (res == 1) {
81110138Sdes		/* postponed - send a null query just in case */
82110138Sdes		char *name, *info, **prompts;
83110138Sdes		u_int i, numprompts, *echo_on;
84110138Sdes
85110138Sdes		res = device->query(authctxt->kbdintctxt, &name, &info,
86110138Sdes		    &numprompts, &prompts, &echo_on);
87110138Sdes		if (res == 0) {
88110138Sdes			for (i = 0; i < numprompts; i++)
89110138Sdes				xfree(prompts[i]);
90110138Sdes			xfree(prompts);
91110138Sdes			xfree(name);
92110138Sdes			xfree(echo_on);
93110138Sdes			xfree(info);
94110138Sdes		}
95110138Sdes		/* if we received more prompts, we're screwed */
96110138Sdes		res = (numprompts != 0);
97110138Sdes	}
9892559Sdes	device->free_ctx(authctxt->kbdintctxt);
9992559Sdes	authctxt->kbdintctxt = NULL;
10092559Sdes	return res ? 0 : 1;
10176259Sgreen}
102112870Sdesvoid
103112870Sdesabandon_challenge_response(Authctxt *authctxt)
104112870Sdes{
105112870Sdes	if (authctxt->kbdintctxt != NULL) {
106112870Sdes		device->free_ctx(authctxt->kbdintctxt);
107112870Sdes		authctxt->kbdintctxt = NULL;
108112870Sdes	}
109112870Sdes}
110