00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "includes.h"
00026 RCSID("$OpenBSD: auth-chall.c,v 1.9 2003/11/03 09:03:37 djm Exp $");
00027
00028 #include "auth.h"
00029 #include "log.h"
00030 #include "xmalloc.h"
00031 #include "servconf.h"
00032
00033
00034
00035 extern KbdintDevice *devices[];
00036 static KbdintDevice *device;
00037 extern ServerOptions options;
00038
00039 char *
00040 get_challenge(Authctxt *authctxt)
00041 {
00042 char *challenge, *name, *info, **prompts;
00043 u_int i, numprompts;
00044 u_int *echo_on;
00045
00046 #ifdef USE_PAM
00047 if (!options.use_pam)
00048 remove_kbdint_device("pam");
00049 #endif
00050
00051 device = devices[0];
00052 if (device == NULL)
00053 return NULL;
00054 if ((authctxt->kbdintctxt = device->init_ctx(authctxt)) == NULL)
00055 return NULL;
00056 if (device->query(authctxt->kbdintctxt, &name, &info,
00057 &numprompts, &prompts, &echo_on)) {
00058 device->free_ctx(authctxt->kbdintctxt);
00059 authctxt->kbdintctxt = NULL;
00060 return NULL;
00061 }
00062 if (numprompts < 1)
00063 fatal("get_challenge: numprompts < 1");
00064 challenge = xstrdup(prompts[0]);
00065 for (i = 0; i < numprompts; i++)
00066 xfree(prompts[i]);
00067 xfree(prompts);
00068 xfree(name);
00069 xfree(echo_on);
00070 xfree(info);
00071
00072 return (challenge);
00073 }
00074 int
00075 verify_response(Authctxt *authctxt, const char *response)
00076 {
00077 char *resp[1], *name, *info, **prompts;
00078 u_int i, numprompts, *echo_on;
00079 int authenticated = 0;
00080
00081 if (device == NULL)
00082 return 0;
00083 if (authctxt->kbdintctxt == NULL)
00084 return 0;
00085 resp[0] = (char *)response;
00086 switch (device->respond(authctxt->kbdintctxt, 1, resp)) {
00087 case 0:
00088 authenticated = 1;
00089 break;
00090 case 1:
00091 if ((device->query(authctxt->kbdintctxt, &name, &info,
00092 &numprompts, &prompts, &echo_on)) != 0)
00093 break;
00094 if (numprompts == 0 &&
00095 device->respond(authctxt->kbdintctxt, 0, resp) == 0)
00096 authenticated = 1;
00097
00098 for (i = 0; i < numprompts; i++)
00099 xfree(prompts[i]);
00100 xfree(prompts);
00101 xfree(name);
00102 xfree(echo_on);
00103 xfree(info);
00104 break;
00105 }
00106 device->free_ctx(authctxt->kbdintctxt);
00107 authctxt->kbdintctxt = NULL;
00108 return authenticated;
00109 }
00110 void
00111 abandon_challenge_response(Authctxt *authctxt)
00112 {
00113 if (authctxt->kbdintctxt != NULL) {
00114 device->free_ctx(authctxt->kbdintctxt);
00115 authctxt->kbdintctxt = NULL;
00116 }
00117 }