1*19261079SEd Maste /* $OpenBSD: auth2-chall.c,v 1.54 2020/10/18 11:32:01 djm Exp $ */
21e8db6e2SBrian Feldman /*
31e8db6e2SBrian Feldman * Copyright (c) 2001 Markus Friedl. All rights reserved.
4ae1f160dSDag-Erling Smørgrav * Copyright (c) 2001 Per Allansson. All rights reserved.
51e8db6e2SBrian Feldman *
61e8db6e2SBrian Feldman * Redistribution and use in source and binary forms, with or without
71e8db6e2SBrian Feldman * modification, are permitted provided that the following conditions
81e8db6e2SBrian Feldman * are met:
91e8db6e2SBrian Feldman * 1. Redistributions of source code must retain the above copyright
101e8db6e2SBrian Feldman * notice, this list of conditions and the following disclaimer.
111e8db6e2SBrian Feldman * 2. Redistributions in binary form must reproduce the above copyright
121e8db6e2SBrian Feldman * notice, this list of conditions and the following disclaimer in the
131e8db6e2SBrian Feldman * documentation and/or other materials provided with the distribution.
141e8db6e2SBrian Feldman *
151e8db6e2SBrian Feldman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
161e8db6e2SBrian Feldman * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
171e8db6e2SBrian Feldman * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
181e8db6e2SBrian Feldman * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
191e8db6e2SBrian Feldman * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
201e8db6e2SBrian Feldman * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
211e8db6e2SBrian Feldman * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
221e8db6e2SBrian Feldman * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
231e8db6e2SBrian Feldman * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
241e8db6e2SBrian Feldman * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
251e8db6e2SBrian Feldman */
261e8db6e2SBrian Feldman
27333ee039SDag-Erling Smørgrav #include "includes.h"
28333ee039SDag-Erling Smørgrav
29333ee039SDag-Erling Smørgrav #include <sys/types.h>
30333ee039SDag-Erling Smørgrav
31*19261079SEd Maste #include <stdlib.h>
32333ee039SDag-Erling Smørgrav #include <stdio.h>
33333ee039SDag-Erling Smørgrav #include <string.h>
34*19261079SEd Maste #include <stdarg.h>
35333ee039SDag-Erling Smørgrav
36333ee039SDag-Erling Smørgrav #include "xmalloc.h"
371e8db6e2SBrian Feldman #include "ssh2.h"
38190cef3dSDag-Erling Smørgrav #include "sshkey.h"
39333ee039SDag-Erling Smørgrav #include "hostfile.h"
401e8db6e2SBrian Feldman #include "auth.h"
41190cef3dSDag-Erling Smørgrav #include "sshbuf.h"
421e8db6e2SBrian Feldman #include "packet.h"
431e8db6e2SBrian Feldman #include "dispatch.h"
44190cef3dSDag-Erling Smørgrav #include "ssherr.h"
451e8db6e2SBrian Feldman #include "log.h"
46a0ee8cc6SDag-Erling Smørgrav #include "misc.h"
47aa49c926SDag-Erling Smørgrav #include "servconf.h"
48aa49c926SDag-Erling Smørgrav
49aa49c926SDag-Erling Smørgrav /* import */
50aa49c926SDag-Erling Smørgrav extern ServerOptions options;
511e8db6e2SBrian Feldman
524f52dfbbSDag-Erling Smørgrav static int auth2_challenge_start(struct ssh *);
53190cef3dSDag-Erling Smørgrav static int send_userauth_info_request(struct ssh *);
544f52dfbbSDag-Erling Smørgrav static int input_userauth_info_response(int, u_int32_t, struct ssh *);
55ae1f160dSDag-Erling Smørgrav
56ae1f160dSDag-Erling Smørgrav #ifdef BSD_AUTH
57ae1f160dSDag-Erling Smørgrav extern KbdintDevice bsdauth_device;
58989dd127SDag-Erling Smørgrav #else
59382d19eeSDag-Erling Smørgrav #ifdef USE_PAM
60cf2b5f3bSDag-Erling Smørgrav extern KbdintDevice sshpam_device;
61382d19eeSDag-Erling Smørgrav #endif
62989dd127SDag-Erling Smørgrav #endif
63ae1f160dSDag-Erling Smørgrav
64ae1f160dSDag-Erling Smørgrav KbdintDevice *devices[] = {
65ae1f160dSDag-Erling Smørgrav #ifdef BSD_AUTH
66ae1f160dSDag-Erling Smørgrav &bsdauth_device,
67989dd127SDag-Erling Smørgrav #else
68382d19eeSDag-Erling Smørgrav #ifdef USE_PAM
69cf2b5f3bSDag-Erling Smørgrav &sshpam_device,
70382d19eeSDag-Erling Smørgrav #endif
71989dd127SDag-Erling Smørgrav #endif
72ae1f160dSDag-Erling Smørgrav NULL
73ae1f160dSDag-Erling Smørgrav };
74ae1f160dSDag-Erling Smørgrav
75ae1f160dSDag-Erling Smørgrav typedef struct KbdintAuthctxt KbdintAuthctxt;
76ae1f160dSDag-Erling Smørgrav struct KbdintAuthctxt
77ae1f160dSDag-Erling Smørgrav {
78ae1f160dSDag-Erling Smørgrav char *devices;
79ae1f160dSDag-Erling Smørgrav void *ctxt;
80ae1f160dSDag-Erling Smørgrav KbdintDevice *device;
81a82e551fSDag-Erling Smørgrav u_int nreq;
823a0b9b77SXin LI u_int devices_done;
83ae1f160dSDag-Erling Smørgrav };
84ae1f160dSDag-Erling Smørgrav
85aa49c926SDag-Erling Smørgrav #ifdef USE_PAM
86aa49c926SDag-Erling Smørgrav void
remove_kbdint_device(const char * devname)87aa49c926SDag-Erling Smørgrav remove_kbdint_device(const char *devname)
88aa49c926SDag-Erling Smørgrav {
89aa49c926SDag-Erling Smørgrav int i, j;
90aa49c926SDag-Erling Smørgrav
91aa49c926SDag-Erling Smørgrav for (i = 0; devices[i] != NULL; i++)
92aa49c926SDag-Erling Smørgrav if (strcmp(devices[i]->name, devname) == 0) {
93aa49c926SDag-Erling Smørgrav for (j = i; devices[j] != NULL; j++)
94aa49c926SDag-Erling Smørgrav devices[j] = devices[j+1];
95aa49c926SDag-Erling Smørgrav i--;
96aa49c926SDag-Erling Smørgrav }
97aa49c926SDag-Erling Smørgrav }
98aa49c926SDag-Erling Smørgrav #endif
99aa49c926SDag-Erling Smørgrav
100ae1f160dSDag-Erling Smørgrav static KbdintAuthctxt *
kbdint_alloc(const char * devs)101ae1f160dSDag-Erling Smørgrav kbdint_alloc(const char *devs)
102ae1f160dSDag-Erling Smørgrav {
103ae1f160dSDag-Erling Smørgrav KbdintAuthctxt *kbdintctxt;
104190cef3dSDag-Erling Smørgrav struct sshbuf *b;
105190cef3dSDag-Erling Smørgrav int i, r;
106ae1f160dSDag-Erling Smørgrav
107aa49c926SDag-Erling Smørgrav #ifdef USE_PAM
108aa49c926SDag-Erling Smørgrav if (!options.use_pam)
109aa49c926SDag-Erling Smørgrav remove_kbdint_device("pam");
110aa49c926SDag-Erling Smørgrav #endif
111aa49c926SDag-Erling Smørgrav
1120a37d4a3SXin LI kbdintctxt = xcalloc(1, sizeof(KbdintAuthctxt));
113ae1f160dSDag-Erling Smørgrav if (strcmp(devs, "") == 0) {
114190cef3dSDag-Erling Smørgrav if ((b = sshbuf_new()) == NULL)
115*19261079SEd Maste fatal_f("sshbuf_new failed");
116ae1f160dSDag-Erling Smørgrav for (i = 0; devices[i]; i++) {
117190cef3dSDag-Erling Smørgrav if ((r = sshbuf_putf(b, "%s%s",
118190cef3dSDag-Erling Smørgrav sshbuf_len(b) ? "," : "", devices[i]->name)) != 0)
119*19261079SEd Maste fatal_fr(r, "buffer error");
120ae1f160dSDag-Erling Smørgrav }
121190cef3dSDag-Erling Smørgrav if ((kbdintctxt->devices = sshbuf_dup_string(b)) == NULL)
122*19261079SEd Maste fatal_f("sshbuf_dup_string failed");
123190cef3dSDag-Erling Smørgrav sshbuf_free(b);
124ae1f160dSDag-Erling Smørgrav } else {
125ae1f160dSDag-Erling Smørgrav kbdintctxt->devices = xstrdup(devs);
126ae1f160dSDag-Erling Smørgrav }
127ae1f160dSDag-Erling Smørgrav debug("kbdint_alloc: devices '%s'", kbdintctxt->devices);
128ae1f160dSDag-Erling Smørgrav kbdintctxt->ctxt = NULL;
129ae1f160dSDag-Erling Smørgrav kbdintctxt->device = NULL;
130a82e551fSDag-Erling Smørgrav kbdintctxt->nreq = 0;
131ae1f160dSDag-Erling Smørgrav
132ae1f160dSDag-Erling Smørgrav return kbdintctxt;
133ae1f160dSDag-Erling Smørgrav }
134ae1f160dSDag-Erling Smørgrav static void
kbdint_reset_device(KbdintAuthctxt * kbdintctxt)135ae1f160dSDag-Erling Smørgrav kbdint_reset_device(KbdintAuthctxt *kbdintctxt)
136ae1f160dSDag-Erling Smørgrav {
137ae1f160dSDag-Erling Smørgrav if (kbdintctxt->ctxt) {
138ae1f160dSDag-Erling Smørgrav kbdintctxt->device->free_ctx(kbdintctxt->ctxt);
139ae1f160dSDag-Erling Smørgrav kbdintctxt->ctxt = NULL;
140ae1f160dSDag-Erling Smørgrav }
141ae1f160dSDag-Erling Smørgrav kbdintctxt->device = NULL;
142ae1f160dSDag-Erling Smørgrav }
143ae1f160dSDag-Erling Smørgrav static void
kbdint_free(KbdintAuthctxt * kbdintctxt)144ae1f160dSDag-Erling Smørgrav kbdint_free(KbdintAuthctxt *kbdintctxt)
145ae1f160dSDag-Erling Smørgrav {
146ae1f160dSDag-Erling Smørgrav if (kbdintctxt->device)
147ae1f160dSDag-Erling Smørgrav kbdint_reset_device(kbdintctxt);
148e4a9863fSDag-Erling Smørgrav free(kbdintctxt->devices);
149*19261079SEd Maste freezero(kbdintctxt, sizeof(*kbdintctxt));
150ae1f160dSDag-Erling Smørgrav }
151ae1f160dSDag-Erling Smørgrav /* get next device */
152ae1f160dSDag-Erling Smørgrav static int
kbdint_next_device(Authctxt * authctxt,KbdintAuthctxt * kbdintctxt)153e4a9863fSDag-Erling Smørgrav kbdint_next_device(Authctxt *authctxt, KbdintAuthctxt *kbdintctxt)
154ae1f160dSDag-Erling Smørgrav {
155ae1f160dSDag-Erling Smørgrav size_t len;
156ae1f160dSDag-Erling Smørgrav char *t;
157ae1f160dSDag-Erling Smørgrav int i;
158ae1f160dSDag-Erling Smørgrav
159ae1f160dSDag-Erling Smørgrav if (kbdintctxt->device)
160ae1f160dSDag-Erling Smørgrav kbdint_reset_device(kbdintctxt);
161ae1f160dSDag-Erling Smørgrav do {
162ae1f160dSDag-Erling Smørgrav len = kbdintctxt->devices ?
163ae1f160dSDag-Erling Smørgrav strcspn(kbdintctxt->devices, ",") : 0;
164ae1f160dSDag-Erling Smørgrav
165ae1f160dSDag-Erling Smørgrav if (len == 0)
166ae1f160dSDag-Erling Smørgrav break;
167e4a9863fSDag-Erling Smørgrav for (i = 0; devices[i]; i++) {
1683a0b9b77SXin LI if ((kbdintctxt->devices_done & (1 << i)) != 0 ||
1693a0b9b77SXin LI !auth2_method_allowed(authctxt,
170e4a9863fSDag-Erling Smørgrav "keyboard-interactive", devices[i]->name))
171e4a9863fSDag-Erling Smørgrav continue;
1723a0b9b77SXin LI if (strncmp(kbdintctxt->devices, devices[i]->name,
1733a0b9b77SXin LI len) == 0) {
174ae1f160dSDag-Erling Smørgrav kbdintctxt->device = devices[i];
1753a0b9b77SXin LI kbdintctxt->devices_done |= 1 << i;
1763a0b9b77SXin LI }
177e4a9863fSDag-Erling Smørgrav }
178ae1f160dSDag-Erling Smørgrav t = kbdintctxt->devices;
179ae1f160dSDag-Erling Smørgrav kbdintctxt->devices = t[len] ? xstrdup(t+len+1) : NULL;
180e4a9863fSDag-Erling Smørgrav free(t);
181ae1f160dSDag-Erling Smørgrav debug2("kbdint_next_device: devices %s", kbdintctxt->devices ?
182ae1f160dSDag-Erling Smørgrav kbdintctxt->devices : "<empty>");
183ae1f160dSDag-Erling Smørgrav } while (kbdintctxt->devices && !kbdintctxt->device);
184ae1f160dSDag-Erling Smørgrav
185ae1f160dSDag-Erling Smørgrav return kbdintctxt->device ? 1 : 0;
186ae1f160dSDag-Erling Smørgrav }
1871e8db6e2SBrian Feldman
1881e8db6e2SBrian Feldman /*
189ae1f160dSDag-Erling Smørgrav * try challenge-response, set authctxt->postponed if we have to
1901e8db6e2SBrian Feldman * wait for the response.
1911e8db6e2SBrian Feldman */
1921e8db6e2SBrian Feldman int
auth2_challenge(struct ssh * ssh,char * devs)1934f52dfbbSDag-Erling Smørgrav auth2_challenge(struct ssh *ssh, char *devs)
1941e8db6e2SBrian Feldman {
1954f52dfbbSDag-Erling Smørgrav Authctxt *authctxt = ssh->authctxt;
196ae1f160dSDag-Erling Smørgrav debug("auth2_challenge: user=%s devs=%s",
197ae1f160dSDag-Erling Smørgrav authctxt->user ? authctxt->user : "<nouser>",
198ae1f160dSDag-Erling Smørgrav devs ? devs : "<no devs>");
1991e8db6e2SBrian Feldman
200ae1f160dSDag-Erling Smørgrav if (authctxt->user == NULL || !devs)
2011e8db6e2SBrian Feldman return 0;
202ae1f160dSDag-Erling Smørgrav if (authctxt->kbdintctxt == NULL)
203ae1f160dSDag-Erling Smørgrav authctxt->kbdintctxt = kbdint_alloc(devs);
2044f52dfbbSDag-Erling Smørgrav return auth2_challenge_start(ssh);
205ae1f160dSDag-Erling Smørgrav }
206ae1f160dSDag-Erling Smørgrav
207ae1f160dSDag-Erling Smørgrav /* unregister kbd-int callbacks and context */
208ae1f160dSDag-Erling Smørgrav void
auth2_challenge_stop(struct ssh * ssh)2094f52dfbbSDag-Erling Smørgrav auth2_challenge_stop(struct ssh *ssh)
210ae1f160dSDag-Erling Smørgrav {
2114f52dfbbSDag-Erling Smørgrav Authctxt *authctxt = ssh->authctxt;
212ae1f160dSDag-Erling Smørgrav /* unregister callback */
2134f52dfbbSDag-Erling Smørgrav ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
214ae1f160dSDag-Erling Smørgrav if (authctxt->kbdintctxt != NULL) {
215ae1f160dSDag-Erling Smørgrav kbdint_free(authctxt->kbdintctxt);
216ae1f160dSDag-Erling Smørgrav authctxt->kbdintctxt = NULL;
217ae1f160dSDag-Erling Smørgrav }
218ae1f160dSDag-Erling Smørgrav }
219ae1f160dSDag-Erling Smørgrav
220ae1f160dSDag-Erling Smørgrav /* side effect: sets authctxt->postponed if a reply was sent*/
221ae1f160dSDag-Erling Smørgrav static int
auth2_challenge_start(struct ssh * ssh)2224f52dfbbSDag-Erling Smørgrav auth2_challenge_start(struct ssh *ssh)
223ae1f160dSDag-Erling Smørgrav {
2244f52dfbbSDag-Erling Smørgrav Authctxt *authctxt = ssh->authctxt;
225ae1f160dSDag-Erling Smørgrav KbdintAuthctxt *kbdintctxt = authctxt->kbdintctxt;
226ae1f160dSDag-Erling Smørgrav
227ae1f160dSDag-Erling Smørgrav debug2("auth2_challenge_start: devices %s",
228ae1f160dSDag-Erling Smørgrav kbdintctxt->devices ? kbdintctxt->devices : "<empty>");
229ae1f160dSDag-Erling Smørgrav
230e4a9863fSDag-Erling Smørgrav if (kbdint_next_device(authctxt, kbdintctxt) == 0) {
2314f52dfbbSDag-Erling Smørgrav auth2_challenge_stop(ssh);
2321e8db6e2SBrian Feldman return 0;
233ae1f160dSDag-Erling Smørgrav }
234ae1f160dSDag-Erling Smørgrav debug("auth2_challenge_start: trying authentication method '%s'",
235ae1f160dSDag-Erling Smørgrav kbdintctxt->device->name);
236ae1f160dSDag-Erling Smørgrav
237ae1f160dSDag-Erling Smørgrav if ((kbdintctxt->ctxt = kbdintctxt->device->init_ctx(authctxt)) == NULL) {
2384f52dfbbSDag-Erling Smørgrav auth2_challenge_stop(ssh);
239ae1f160dSDag-Erling Smørgrav return 0;
240ae1f160dSDag-Erling Smørgrav }
241190cef3dSDag-Erling Smørgrav if (send_userauth_info_request(ssh) == 0) {
2424f52dfbbSDag-Erling Smørgrav auth2_challenge_stop(ssh);
243ae1f160dSDag-Erling Smørgrav return 0;
244ae1f160dSDag-Erling Smørgrav }
2454f52dfbbSDag-Erling Smørgrav ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_RESPONSE,
2461e8db6e2SBrian Feldman &input_userauth_info_response);
247ae1f160dSDag-Erling Smørgrav
2481e8db6e2SBrian Feldman authctxt->postponed = 1;
2491e8db6e2SBrian Feldman return 0;
2501e8db6e2SBrian Feldman }
2511e8db6e2SBrian Feldman
252ae1f160dSDag-Erling Smørgrav static int
send_userauth_info_request(struct ssh * ssh)253190cef3dSDag-Erling Smørgrav send_userauth_info_request(struct ssh *ssh)
2541e8db6e2SBrian Feldman {
255190cef3dSDag-Erling Smørgrav Authctxt *authctxt = ssh->authctxt;
256ae1f160dSDag-Erling Smørgrav KbdintAuthctxt *kbdintctxt;
257ae1f160dSDag-Erling Smørgrav char *name, *instr, **prompts;
258190cef3dSDag-Erling Smørgrav u_int r, i, *echo_on;
259ae1f160dSDag-Erling Smørgrav
260ae1f160dSDag-Erling Smørgrav kbdintctxt = authctxt->kbdintctxt;
261ae1f160dSDag-Erling Smørgrav if (kbdintctxt->device->query(kbdintctxt->ctxt,
262a82e551fSDag-Erling Smørgrav &name, &instr, &kbdintctxt->nreq, &prompts, &echo_on))
263ae1f160dSDag-Erling Smørgrav return 0;
2641e8db6e2SBrian Feldman
265190cef3dSDag-Erling Smørgrav if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_INFO_REQUEST)) != 0 ||
266190cef3dSDag-Erling Smørgrav (r = sshpkt_put_cstring(ssh, name)) != 0 ||
267190cef3dSDag-Erling Smørgrav (r = sshpkt_put_cstring(ssh, instr)) != 0 ||
268190cef3dSDag-Erling Smørgrav (r = sshpkt_put_cstring(ssh, "")) != 0 || /* language not used */
269190cef3dSDag-Erling Smørgrav (r = sshpkt_put_u32(ssh, kbdintctxt->nreq)) != 0)
270*19261079SEd Maste fatal_fr(r, "start packet");
271a82e551fSDag-Erling Smørgrav for (i = 0; i < kbdintctxt->nreq; i++) {
272190cef3dSDag-Erling Smørgrav if ((r = sshpkt_put_cstring(ssh, prompts[i])) != 0 ||
273190cef3dSDag-Erling Smørgrav (r = sshpkt_put_u8(ssh, echo_on[i])) != 0)
274*19261079SEd Maste fatal_fr(r, "assemble packet");
275ae1f160dSDag-Erling Smørgrav }
276190cef3dSDag-Erling Smørgrav if ((r = sshpkt_send(ssh)) != 0 ||
277190cef3dSDag-Erling Smørgrav (r = ssh_packet_write_wait(ssh)) != 0)
278*19261079SEd Maste fatal_fr(r, "send packet");
279ae1f160dSDag-Erling Smørgrav
280a82e551fSDag-Erling Smørgrav for (i = 0; i < kbdintctxt->nreq; i++)
281e4a9863fSDag-Erling Smørgrav free(prompts[i]);
282e4a9863fSDag-Erling Smørgrav free(prompts);
283e4a9863fSDag-Erling Smørgrav free(echo_on);
284e4a9863fSDag-Erling Smørgrav free(name);
285e4a9863fSDag-Erling Smørgrav free(instr);
286ae1f160dSDag-Erling Smørgrav return 1;
2871e8db6e2SBrian Feldman }
2881e8db6e2SBrian Feldman
289bc5531deSDag-Erling Smørgrav static int
input_userauth_info_response(int type,u_int32_t seq,struct ssh * ssh)2904f52dfbbSDag-Erling Smørgrav input_userauth_info_response(int type, u_int32_t seq, struct ssh *ssh)
2911e8db6e2SBrian Feldman {
2924f52dfbbSDag-Erling Smørgrav Authctxt *authctxt = ssh->authctxt;
293ae1f160dSDag-Erling Smørgrav KbdintAuthctxt *kbdintctxt;
294cce7d346SDag-Erling Smørgrav int authenticated = 0, res;
295190cef3dSDag-Erling Smørgrav int r;
296d4ecd108SDag-Erling Smørgrav u_int i, nresp;
2976888a9beSDag-Erling Smørgrav const char *devicename = NULL;
2986888a9beSDag-Erling Smørgrav char **response = NULL;
2991e8db6e2SBrian Feldman
3001e8db6e2SBrian Feldman if (authctxt == NULL)
301*19261079SEd Maste fatal_f("no authctxt");
302ae1f160dSDag-Erling Smørgrav kbdintctxt = authctxt->kbdintctxt;
303ae1f160dSDag-Erling Smørgrav if (kbdintctxt == NULL || kbdintctxt->ctxt == NULL)
304*19261079SEd Maste fatal_f("no kbdintctxt");
305ae1f160dSDag-Erling Smørgrav if (kbdintctxt->device == NULL)
306*19261079SEd Maste fatal_f("no device");
3071e8db6e2SBrian Feldman
3081e8db6e2SBrian Feldman authctxt->postponed = 0; /* reset */
309190cef3dSDag-Erling Smørgrav if ((r = sshpkt_get_u32(ssh, &nresp)) != 0)
310*19261079SEd Maste fatal_fr(r, "parse packet");
311a82e551fSDag-Erling Smørgrav if (nresp != kbdintctxt->nreq)
312*19261079SEd Maste fatal_f("wrong number of replies");
313a82e551fSDag-Erling Smørgrav if (nresp > 100)
314*19261079SEd Maste fatal_f("too many replies");
315ae1f160dSDag-Erling Smørgrav if (nresp > 0) {
316333ee039SDag-Erling Smørgrav response = xcalloc(nresp, sizeof(char *));
317*19261079SEd Maste for (i = 0; i < nresp; i++) {
318*19261079SEd Maste if ((r = sshpkt_get_cstring(ssh, &response[i], NULL)) != 0)
319*19261079SEd Maste fatal_fr(r, "parse response");
320*19261079SEd Maste }
3211e8db6e2SBrian Feldman }
322190cef3dSDag-Erling Smørgrav if ((r = sshpkt_get_end(ssh)) != 0)
323*19261079SEd Maste fatal_fr(r, "parse packet");
3241e8db6e2SBrian Feldman
325aa49c926SDag-Erling Smørgrav res = kbdintctxt->device->respond(kbdintctxt->ctxt, nresp, response);
326ae1f160dSDag-Erling Smørgrav
327ae1f160dSDag-Erling Smørgrav for (i = 0; i < nresp; i++) {
328b83788ffSDag-Erling Smørgrav explicit_bzero(response[i], strlen(response[i]));
329e4a9863fSDag-Erling Smørgrav free(response[i]);
330ae1f160dSDag-Erling Smørgrav }
331e4a9863fSDag-Erling Smørgrav free(response);
332ae1f160dSDag-Erling Smørgrav
333ae1f160dSDag-Erling Smørgrav switch (res) {
334ae1f160dSDag-Erling Smørgrav case 0:
335ae1f160dSDag-Erling Smørgrav /* Success! */
336aa49c926SDag-Erling Smørgrav authenticated = authctxt->valid ? 1 : 0;
337ae1f160dSDag-Erling Smørgrav break;
338ae1f160dSDag-Erling Smørgrav case 1:
339ae1f160dSDag-Erling Smørgrav /* Authentication needs further interaction */
340190cef3dSDag-Erling Smørgrav if (send_userauth_info_request(ssh) == 1)
341ae1f160dSDag-Erling Smørgrav authctxt->postponed = 1;
342ae1f160dSDag-Erling Smørgrav break;
343ae1f160dSDag-Erling Smørgrav default:
344ae1f160dSDag-Erling Smørgrav /* Failure! */
345ae1f160dSDag-Erling Smørgrav break;
346ae1f160dSDag-Erling Smørgrav }
3476888a9beSDag-Erling Smørgrav devicename = kbdintctxt->device->name;
348ae1f160dSDag-Erling Smørgrav if (!authctxt->postponed) {
349ae1f160dSDag-Erling Smørgrav if (authenticated) {
3504f52dfbbSDag-Erling Smørgrav auth2_challenge_stop(ssh);
351ae1f160dSDag-Erling Smørgrav } else {
352ae1f160dSDag-Erling Smørgrav /* start next device */
353ae1f160dSDag-Erling Smørgrav /* may set authctxt->postponed */
3544f52dfbbSDag-Erling Smørgrav auth2_challenge_start(ssh);
355ae1f160dSDag-Erling Smørgrav }
356ae1f160dSDag-Erling Smørgrav }
3574f52dfbbSDag-Erling Smørgrav userauth_finish(ssh, authenticated, "keyboard-interactive",
3586888a9beSDag-Erling Smørgrav devicename);
359bc5531deSDag-Erling Smørgrav return 0;
3601e8db6e2SBrian Feldman }
36180628bacSDag-Erling Smørgrav
36280628bacSDag-Erling Smørgrav void
privsep_challenge_enable(void)36380628bacSDag-Erling Smørgrav privsep_challenge_enable(void)
36480628bacSDag-Erling Smørgrav {
365190cef3dSDag-Erling Smørgrav #if defined(BSD_AUTH) || defined(USE_PAM)
366cf2b5f3bSDag-Erling Smørgrav int n = 0;
367cf2b5f3bSDag-Erling Smørgrav #endif
36880628bacSDag-Erling Smørgrav #ifdef BSD_AUTH
36980628bacSDag-Erling Smørgrav extern KbdintDevice mm_bsdauth_device;
37080628bacSDag-Erling Smørgrav #endif
371382d19eeSDag-Erling Smørgrav #ifdef USE_PAM
372cf2b5f3bSDag-Erling Smørgrav extern KbdintDevice mm_sshpam_device;
373382d19eeSDag-Erling Smørgrav #endif
374382d19eeSDag-Erling Smørgrav
37580628bacSDag-Erling Smørgrav #ifdef BSD_AUTH
376382d19eeSDag-Erling Smørgrav devices[n++] = &mm_bsdauth_device;
37780628bacSDag-Erling Smørgrav #else
378382d19eeSDag-Erling Smørgrav #ifdef USE_PAM
379cf2b5f3bSDag-Erling Smørgrav devices[n++] = &mm_sshpam_device;
380382d19eeSDag-Erling Smørgrav #endif
38180628bacSDag-Erling Smørgrav #endif
38280628bacSDag-Erling Smørgrav }
383