auth-chall.c revision 181097
14Srgrimes/* $OpenBSD: auth-chall.c,v 1.12 2006/08/03 03:34:41 deraadt Exp $ */ 24Srgrimes/* 3295Sjtc * Copyright (c) 2001 Markus Friedl. All rights reserved. 44Srgrimes * 5295Sjtc * Redistribution and use in source and binary forms, with or without 6295Sjtc * modification, are permitted provided that the following conditions 7468Sjtc * are met: 84Srgrimes * 1. Redistributions of source code must retain the above copyright 9468Sjtc * notice, this list of conditions and the following disclaimer. 104Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 114Srgrimes * notice, this list of conditions and the following disclaimer in the 124Srgrimes * documentation and/or other materials provided with the distribution. 13468Sjtc * 144Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15295Sjtc * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1631Salm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 174Srgrimes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 184Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 194Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2031Salm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 214Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 224Srgrimes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 234Srgrimes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 244Srgrimes */ 254Srgrimes 264Srgrimes#include "includes.h" 2731Salm__RCSID("$FreeBSD: head/crypto/openssh/auth-chall.c 181097 2008-08-01 01:13:41Z des $"); 284Srgrimes 294Srgrimes#include <sys/types.h> 304Srgrimes 314Srgrimes#include <stdarg.h> 324Srgrimes 334Srgrimes#include "xmalloc.h" 344Srgrimes#include "key.h" 354Srgrimes#include "hostfile.h" 364Srgrimes#include "auth.h" 374Srgrimes#include "log.h" 384Srgrimes#include "servconf.h" 394Srgrimes 404Srgrimes/* limited protocol v1 interface to kbd-interactive authentication */ 414Srgrimes 424Srgrimesextern KbdintDevice *devices[]; 434Srgrimesstatic KbdintDevice *device; 444Srgrimesextern ServerOptions options; 454Srgrimes 464Srgrimeschar * 474Srgrimesget_challenge(Authctxt *authctxt) 484Srgrimes{ 494Srgrimes char *challenge, *name, *info, **prompts; 504Srgrimes u_int i, numprompts; 514Srgrimes u_int *echo_on; 524Srgrimes 534Srgrimes#ifdef USE_PAM 544Srgrimes if (!options.use_pam) 554Srgrimes remove_kbdint_device("pam"); 564Srgrimes#endif 574Srgrimes 584Srgrimes device = devices[0]; /* we always use the 1st device for protocol 1 */ 594Srgrimes if (device == NULL) 604Srgrimes return NULL; 614Srgrimes if ((authctxt->kbdintctxt = device->init_ctx(authctxt)) == NULL) 624Srgrimes return NULL; 634Srgrimes if (device->query(authctxt->kbdintctxt, &name, &info, 644Srgrimes &numprompts, &prompts, &echo_on)) { 654Srgrimes device->free_ctx(authctxt->kbdintctxt); 664Srgrimes authctxt->kbdintctxt = NULL; 674Srgrimes return NULL; 684Srgrimes } 694Srgrimes if (numprompts < 1) 704Srgrimes fatal("get_challenge: numprompts < 1"); 714Srgrimes challenge = xstrdup(prompts[0]); 724Srgrimes for (i = 0; i < numprompts; i++) 734Srgrimes xfree(prompts[i]); 744Srgrimes xfree(prompts); 754Srgrimes xfree(name); 764Srgrimes xfree(echo_on); 774Srgrimes xfree(info); 784Srgrimes 794Srgrimes return (challenge); 804Srgrimes} 814Srgrimesint 824Srgrimesverify_response(Authctxt *authctxt, const char *response) 834Srgrimes{ 844Srgrimes char *resp[1], *name, *info, **prompts; 854Srgrimes u_int i, numprompts, *echo_on; 864Srgrimes int authenticated = 0; 874Srgrimes 884Srgrimes if (device == NULL) 894Srgrimes return 0; 904Srgrimes if (authctxt->kbdintctxt == NULL) 914Srgrimes return 0; 924Srgrimes resp[0] = (char *)response; 934Srgrimes switch (device->respond(authctxt->kbdintctxt, 1, resp)) { 944Srgrimes case 0: /* Success */ 954Srgrimes authenticated = 1; 964Srgrimes break; 97295Sjtc case 1: /* Postponed - retry with empty query for PAM */ 984Srgrimes if ((device->query(authctxt->kbdintctxt, &name, &info, 994Srgrimes &numprompts, &prompts, &echo_on)) != 0) 1004Srgrimes break; 1014Srgrimes if (numprompts == 0 && 1024Srgrimes device->respond(authctxt->kbdintctxt, 0, resp) == 0) 1034Srgrimes authenticated = 1; 1044Srgrimes 1054Srgrimes for (i = 0; i < numprompts; i++) 1064Srgrimes xfree(prompts[i]); 1074Srgrimes xfree(prompts); 1084Srgrimes xfree(name); 1094Srgrimes xfree(echo_on); 1104Srgrimes xfree(info); 1114Srgrimes break; 1124Srgrimes } 113295Sjtc device->free_ctx(authctxt->kbdintctxt); 1144Srgrimes authctxt->kbdintctxt = NULL; 1154Srgrimes return authenticated; 1164Srgrimes} 1174Srgrimesvoid 1184Srgrimesabandon_challenge_response(Authctxt *authctxt) 1194Srgrimes{ 1204Srgrimes if (authctxt->kbdintctxt != NULL) { 1214Srgrimes device->free_ctx(authctxt->kbdintctxt); 1224Srgrimes authctxt->kbdintctxt = NULL; 1234Srgrimes } 1244Srgrimes} 1254Srgrimes