1 /*
   2  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
   3  *
   4  * Redistribution and use in source and binary forms, with or without
   5  * modification, are permitted provided that the following conditions
   6  * are met:
   7  * 1. Redistributions of source code must retain the above copyright
   8  *    notice, this list of conditions and the following disclaimer.
   9  * 2. Redistributions in binary form must reproduce the above copyright
  10  *    notice, this list of conditions and the following disclaimer in the
  11  *    documentation and/or other materials provided with the distribution.
  12  *
  13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  14  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  15  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  16  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  17  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  18  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  19  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  20  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23  */
  24 
  25 #include "includes.h"
  26 RCSID("$OpenBSD: auth-chall.c,v 1.8 2001/05/18 14:13:28 markus Exp $");
  27 
  28 #pragma ident   "%Z%%M% %I%     %E% SMI"
  29 
  30 #include "auth.h"
  31 #include "log.h"
  32 #include "xmalloc.h"
  33 
  34 /* limited protocol v1 interface to kbd-interactive authentication */
  35 
  36 extern KbdintDevice *devices[];
  37 static KbdintDevice *device;
  38 
  39 char *
  40 get_challenge(Authctxt *authctxt)
  41 {
  42         char *challenge, *name, *info, **prompts;
  43         u_int i, numprompts;
  44         u_int *echo_on;
  45 
  46         device = devices[0]; /* we always use the 1st device for protocol 1 */
  47         if (device == NULL)
  48                 return NULL;
  49         if ((authctxt->kbdintctxt = device->init_ctx(authctxt)) == NULL)
  50                 return NULL;
  51         if (device->query(authctxt->kbdintctxt, &name, &info,
  52             &numprompts, &prompts, &echo_on)) {
  53                 device->free_ctx(authctxt->kbdintctxt);
  54                 authctxt->kbdintctxt = NULL;
  55                 return NULL;
  56         }
  57         if (numprompts < 1)
  58                 fatal("get_challenge: numprompts < 1");
  59         challenge = xstrdup(prompts[0]);
  60         for (i = 0; i < numprompts; i++)
  61                 xfree(prompts[i]);
  62         xfree(prompts);
  63         xfree(name);
  64         xfree(echo_on);
  65         xfree(info);
  66 
  67         return (challenge);
  68 }
  69 int
  70 verify_response(Authctxt *authctxt, const char *response)
  71 {
  72         char *resp[1];
  73         int res;
  74 
  75         if (device == NULL)
  76                 return 0;
  77         if (authctxt->kbdintctxt == NULL)
  78                 return 0;
  79         resp[0] = (char *)response;
  80         res = device->respond(authctxt->kbdintctxt, 1, resp);
  81         device->free_ctx(authctxt->kbdintctxt);
  82         authctxt->kbdintctxt = NULL;
  83         return res ? 0 : 1;
  84 }