auth-chall.c revision 162856
133965Sjdp/* $OpenBSD: auth-chall.c,v 1.12 2006/08/03 03:34:41 deraadt Exp $ */ 233965Sjdp/* 338889Sjdp * Copyright (c) 2001 Markus Friedl. All rights reserved. 433965Sjdp * 533965Sjdp * Redistribution and use in source and binary forms, with or without 633965Sjdp * modification, are permitted provided that the following conditions 738889Sjdp * are met: 838889Sjdp * 1. Redistributions of source code must retain the above copyright 938889Sjdp * notice, this list of conditions and the following disclaimer. 1038889Sjdp * 2. Redistributions in binary form must reproduce the above copyright 1138889Sjdp * notice, this list of conditions and the following disclaimer in the 1238889Sjdp * documentation and/or other materials provided with the distribution. 1338889Sjdp * 1438889Sjdp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1538889Sjdp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1638889Sjdp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1738889Sjdp * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1838889Sjdp * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1938889Sjdp * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2038889Sjdp * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2138889Sjdp * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2238889Sjdp * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2333965Sjdp * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2433965Sjdp */ 2533965Sjdp 2633965Sjdp#include "includes.h" 2733965Sjdp__RCSID("$FreeBSD: head/crypto/openssh/auth-chall.c 162856 2006-09-30 13:38:06Z des $"); 2833965Sjdp 2933965Sjdp#include <sys/types.h> 3033965Sjdp 3133965Sjdp#include <stdarg.h> 3233965Sjdp 3333965Sjdp#include "xmalloc.h" 3433965Sjdp#include "key.h" 3533965Sjdp#include "hostfile.h" 3633965Sjdp#include "auth.h" 3733965Sjdp#include "log.h" 3833965Sjdp#include "servconf.h" 3933965Sjdp 4033965Sjdp/* limited protocol v1 interface to kbd-interactive authentication */ 4133965Sjdp 4233965Sjdpextern KbdintDevice *devices[]; 4333965Sjdpstatic KbdintDevice *device; 4433965Sjdpextern ServerOptions options; 4533965Sjdp 4633965Sjdpchar * 4733965Sjdpget_challenge(Authctxt *authctxt) 4833965Sjdp{ 4933965Sjdp char *challenge, *name, *info, **prompts; 5033965Sjdp u_int i, numprompts; 5133965Sjdp u_int *echo_on; 5233965Sjdp 5338889Sjdp#ifdef USE_PAM 5433965Sjdp if (!options.use_pam) 5533965Sjdp remove_kbdint_device("pam"); 5633965Sjdp#endif 5733965Sjdp 5833965Sjdp device = devices[0]; /* we always use the 1st device for protocol 1 */ 5933965Sjdp if (device == NULL) 6038889Sjdp return NULL; 6138889Sjdp if ((authctxt->kbdintctxt = device->init_ctx(authctxt)) == NULL) 6238889Sjdp return NULL; 6338889Sjdp if (device->query(authctxt->kbdintctxt, &name, &info, 6433965Sjdp &numprompts, &prompts, &echo_on)) { 6533965Sjdp device->free_ctx(authctxt->kbdintctxt); 6633965Sjdp authctxt->kbdintctxt = NULL; 6733965Sjdp return NULL; 6833965Sjdp } 6933965Sjdp if (numprompts < 1) 7033965Sjdp fatal("get_challenge: numprompts < 1"); 7133965Sjdp challenge = xstrdup(prompts[0]); 7233965Sjdp for (i = 0; i < numprompts; i++) 7333965Sjdp xfree(prompts[i]); 7433965Sjdp xfree(prompts); 7538889Sjdp xfree(name); 7633965Sjdp xfree(echo_on); 7733965Sjdp xfree(info); 7833965Sjdp 7933965Sjdp return (challenge); 8033965Sjdp} 8133965Sjdpint 8233965Sjdpverify_response(Authctxt *authctxt, const char *response) 8333965Sjdp{ 8433965Sjdp char *resp[1], *name, *info, **prompts; 8533965Sjdp u_int i, numprompts, *echo_on; 8633965Sjdp int authenticated = 0; 8733965Sjdp 8833965Sjdp if (device == NULL) 8933965Sjdp return 0; 9033965Sjdp if (authctxt->kbdintctxt == NULL) 9133965Sjdp return 0; 9233965Sjdp resp[0] = (char *)response; 9333965Sjdp switch (device->respond(authctxt->kbdintctxt, 1, resp)) { 9433965Sjdp case 0: /* Success */ 9533965Sjdp authenticated = 1; 9633965Sjdp break; 9733965Sjdp case 1: /* Postponed - retry with empty query for PAM */ 9838889Sjdp if ((device->query(authctxt->kbdintctxt, &name, &info, 9933965Sjdp &numprompts, &prompts, &echo_on)) != 0) 10033965Sjdp break; 10133965Sjdp if (numprompts == 0 && 10233965Sjdp device->respond(authctxt->kbdintctxt, 0, resp) == 0) 10333965Sjdp authenticated = 1; 10433965Sjdp 10533965Sjdp for (i = 0; i < numprompts; i++) 10633965Sjdp xfree(prompts[i]); 10733965Sjdp xfree(prompts); 10833965Sjdp xfree(name); 10933965Sjdp xfree(echo_on); 11033965Sjdp xfree(info); 11133965Sjdp break; 11233965Sjdp } 11338889Sjdp device->free_ctx(authctxt->kbdintctxt); 11438889Sjdp authctxt->kbdintctxt = NULL; 11533965Sjdp return authenticated; 11633965Sjdp} 11738889Sjdpvoid 11838889Sjdpabandon_challenge_response(Authctxt *authctxt) 11938889Sjdp{ 12038889Sjdp if (authctxt->kbdintctxt != NULL) { 12138889Sjdp device->free_ctx(authctxt->kbdintctxt); 12238889Sjdp authctxt->kbdintctxt = NULL; 12333965Sjdp } 12433965Sjdp} 12533965Sjdp