1*50a69bb5SSascha Wildner /* $OpenBSD: auth2-chall.c,v 1.54 2020/10/18 11:32:01 djm Exp $ */
218de8d7fSPeter Avalos /*
318de8d7fSPeter Avalos * Copyright (c) 2001 Markus Friedl. All rights reserved.
418de8d7fSPeter Avalos * Copyright (c) 2001 Per Allansson. All rights reserved.
518de8d7fSPeter Avalos *
618de8d7fSPeter Avalos * Redistribution and use in source and binary forms, with or without
718de8d7fSPeter Avalos * modification, are permitted provided that the following conditions
818de8d7fSPeter Avalos * are met:
918de8d7fSPeter Avalos * 1. Redistributions of source code must retain the above copyright
1018de8d7fSPeter Avalos * notice, this list of conditions and the following disclaimer.
1118de8d7fSPeter Avalos * 2. Redistributions in binary form must reproduce the above copyright
1218de8d7fSPeter Avalos * notice, this list of conditions and the following disclaimer in the
1318de8d7fSPeter Avalos * documentation and/or other materials provided with the distribution.
1418de8d7fSPeter Avalos *
1518de8d7fSPeter Avalos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1618de8d7fSPeter Avalos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1718de8d7fSPeter Avalos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1818de8d7fSPeter Avalos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1918de8d7fSPeter Avalos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2018de8d7fSPeter Avalos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2118de8d7fSPeter Avalos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2218de8d7fSPeter Avalos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2318de8d7fSPeter Avalos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2418de8d7fSPeter Avalos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2518de8d7fSPeter Avalos */
2618de8d7fSPeter Avalos
2718de8d7fSPeter Avalos #include "includes.h"
2818de8d7fSPeter Avalos
2918de8d7fSPeter Avalos #include <sys/types.h>
3018de8d7fSPeter Avalos
310cbfa66cSDaniel Fojt #include <stdlib.h>
3218de8d7fSPeter Avalos #include <stdio.h>
3318de8d7fSPeter Avalos #include <string.h>
340cbfa66cSDaniel Fojt #include <stdarg.h>
3518de8d7fSPeter Avalos
3618de8d7fSPeter Avalos #include "xmalloc.h"
3718de8d7fSPeter Avalos #include "ssh2.h"
38664f4763Szrj #include "sshkey.h"
3918de8d7fSPeter Avalos #include "hostfile.h"
4018de8d7fSPeter Avalos #include "auth.h"
41664f4763Szrj #include "sshbuf.h"
4218de8d7fSPeter Avalos #include "packet.h"
4318de8d7fSPeter Avalos #include "dispatch.h"
44664f4763Szrj #include "ssherr.h"
4518de8d7fSPeter Avalos #include "log.h"
4636e94dc5SPeter Avalos #include "misc.h"
4718de8d7fSPeter Avalos #include "servconf.h"
4818de8d7fSPeter Avalos
4918de8d7fSPeter Avalos /* import */
5018de8d7fSPeter Avalos extern ServerOptions options;
5118de8d7fSPeter Avalos
52ce74bacaSMatthew Dillon static int auth2_challenge_start(struct ssh *);
53664f4763Szrj static int send_userauth_info_request(struct ssh *);
54ce74bacaSMatthew Dillon static int input_userauth_info_response(int, u_int32_t, struct ssh *);
5518de8d7fSPeter Avalos
5618de8d7fSPeter Avalos #ifdef BSD_AUTH
5718de8d7fSPeter Avalos extern KbdintDevice bsdauth_device;
5818de8d7fSPeter Avalos #else
5918de8d7fSPeter Avalos #ifdef USE_PAM
6018de8d7fSPeter Avalos extern KbdintDevice sshpam_device;
6118de8d7fSPeter Avalos #endif
6218de8d7fSPeter Avalos #endif
6318de8d7fSPeter Avalos
6418de8d7fSPeter Avalos KbdintDevice *devices[] = {
6518de8d7fSPeter Avalos #ifdef BSD_AUTH
6618de8d7fSPeter Avalos &bsdauth_device,
6718de8d7fSPeter Avalos #else
6818de8d7fSPeter Avalos #ifdef USE_PAM
6918de8d7fSPeter Avalos &sshpam_device,
7018de8d7fSPeter Avalos #endif
7118de8d7fSPeter Avalos #endif
7218de8d7fSPeter Avalos NULL
7318de8d7fSPeter Avalos };
7418de8d7fSPeter Avalos
7518de8d7fSPeter Avalos typedef struct KbdintAuthctxt KbdintAuthctxt;
7618de8d7fSPeter Avalos struct KbdintAuthctxt
7718de8d7fSPeter Avalos {
7818de8d7fSPeter Avalos char *devices;
7918de8d7fSPeter Avalos void *ctxt;
8018de8d7fSPeter Avalos KbdintDevice *device;
8118de8d7fSPeter Avalos u_int nreq;
82e9778795SPeter Avalos u_int devices_done;
8318de8d7fSPeter Avalos };
8418de8d7fSPeter Avalos
8518de8d7fSPeter Avalos #ifdef USE_PAM
8618de8d7fSPeter Avalos void
remove_kbdint_device(const char * devname)8718de8d7fSPeter Avalos remove_kbdint_device(const char *devname)
8818de8d7fSPeter Avalos {
8918de8d7fSPeter Avalos int i, j;
9018de8d7fSPeter Avalos
9118de8d7fSPeter Avalos for (i = 0; devices[i] != NULL; i++)
9218de8d7fSPeter Avalos if (strcmp(devices[i]->name, devname) == 0) {
9318de8d7fSPeter Avalos for (j = i; devices[j] != NULL; j++)
9418de8d7fSPeter Avalos devices[j] = devices[j+1];
9518de8d7fSPeter Avalos i--;
9618de8d7fSPeter Avalos }
9718de8d7fSPeter Avalos }
9818de8d7fSPeter Avalos #endif
9918de8d7fSPeter Avalos
10018de8d7fSPeter Avalos static KbdintAuthctxt *
kbdint_alloc(const char * devs)10118de8d7fSPeter Avalos kbdint_alloc(const char *devs)
10218de8d7fSPeter Avalos {
10318de8d7fSPeter Avalos KbdintAuthctxt *kbdintctxt;
104664f4763Szrj struct sshbuf *b;
105664f4763Szrj int i, r;
10618de8d7fSPeter Avalos
10718de8d7fSPeter Avalos #ifdef USE_PAM
10818de8d7fSPeter Avalos if (!options.use_pam)
10918de8d7fSPeter Avalos remove_kbdint_device("pam");
11018de8d7fSPeter Avalos #endif
11118de8d7fSPeter Avalos
11236e94dc5SPeter Avalos kbdintctxt = xcalloc(1, sizeof(KbdintAuthctxt));
11318de8d7fSPeter Avalos if (strcmp(devs, "") == 0) {
114664f4763Szrj if ((b = sshbuf_new()) == NULL)
115*50a69bb5SSascha Wildner fatal_f("sshbuf_new failed");
11618de8d7fSPeter Avalos for (i = 0; devices[i]; i++) {
117664f4763Szrj if ((r = sshbuf_putf(b, "%s%s",
118664f4763Szrj sshbuf_len(b) ? "," : "", devices[i]->name)) != 0)
119*50a69bb5SSascha Wildner fatal_fr(r, "buffer error");
12018de8d7fSPeter Avalos }
121664f4763Szrj if ((kbdintctxt->devices = sshbuf_dup_string(b)) == NULL)
122*50a69bb5SSascha Wildner fatal_f("sshbuf_dup_string failed");
123664f4763Szrj sshbuf_free(b);
12418de8d7fSPeter Avalos } else {
12518de8d7fSPeter Avalos kbdintctxt->devices = xstrdup(devs);
12618de8d7fSPeter Avalos }
12718de8d7fSPeter Avalos debug("kbdint_alloc: devices '%s'", kbdintctxt->devices);
12818de8d7fSPeter Avalos kbdintctxt->ctxt = NULL;
12918de8d7fSPeter Avalos kbdintctxt->device = NULL;
13018de8d7fSPeter Avalos kbdintctxt->nreq = 0;
13118de8d7fSPeter Avalos
13218de8d7fSPeter Avalos return kbdintctxt;
13318de8d7fSPeter Avalos }
13418de8d7fSPeter Avalos static void
kbdint_reset_device(KbdintAuthctxt * kbdintctxt)13518de8d7fSPeter Avalos kbdint_reset_device(KbdintAuthctxt *kbdintctxt)
13618de8d7fSPeter Avalos {
13718de8d7fSPeter Avalos if (kbdintctxt->ctxt) {
13818de8d7fSPeter Avalos kbdintctxt->device->free_ctx(kbdintctxt->ctxt);
13918de8d7fSPeter Avalos kbdintctxt->ctxt = NULL;
14018de8d7fSPeter Avalos }
14118de8d7fSPeter Avalos kbdintctxt->device = NULL;
14218de8d7fSPeter Avalos }
14318de8d7fSPeter Avalos static void
kbdint_free(KbdintAuthctxt * kbdintctxt)14418de8d7fSPeter Avalos kbdint_free(KbdintAuthctxt *kbdintctxt)
14518de8d7fSPeter Avalos {
14618de8d7fSPeter Avalos if (kbdintctxt->device)
14718de8d7fSPeter Avalos kbdint_reset_device(kbdintctxt);
14836e94dc5SPeter Avalos free(kbdintctxt->devices);
1490cbfa66cSDaniel Fojt freezero(kbdintctxt, sizeof(*kbdintctxt));
15018de8d7fSPeter Avalos }
15118de8d7fSPeter Avalos /* get next device */
15218de8d7fSPeter Avalos static int
kbdint_next_device(Authctxt * authctxt,KbdintAuthctxt * kbdintctxt)15336e94dc5SPeter Avalos kbdint_next_device(Authctxt *authctxt, KbdintAuthctxt *kbdintctxt)
15418de8d7fSPeter Avalos {
15518de8d7fSPeter Avalos size_t len;
15618de8d7fSPeter Avalos char *t;
15718de8d7fSPeter Avalos int i;
15818de8d7fSPeter Avalos
15918de8d7fSPeter Avalos if (kbdintctxt->device)
16018de8d7fSPeter Avalos kbdint_reset_device(kbdintctxt);
16118de8d7fSPeter Avalos do {
16218de8d7fSPeter Avalos len = kbdintctxt->devices ?
16318de8d7fSPeter Avalos strcspn(kbdintctxt->devices, ",") : 0;
16418de8d7fSPeter Avalos
16518de8d7fSPeter Avalos if (len == 0)
16618de8d7fSPeter Avalos break;
16736e94dc5SPeter Avalos for (i = 0; devices[i]; i++) {
168e9778795SPeter Avalos if ((kbdintctxt->devices_done & (1 << i)) != 0 ||
169e9778795SPeter Avalos !auth2_method_allowed(authctxt,
17036e94dc5SPeter Avalos "keyboard-interactive", devices[i]->name))
17136e94dc5SPeter Avalos continue;
172e9778795SPeter Avalos if (strncmp(kbdintctxt->devices, devices[i]->name,
173e9778795SPeter Avalos len) == 0) {
17418de8d7fSPeter Avalos kbdintctxt->device = devices[i];
175e9778795SPeter Avalos kbdintctxt->devices_done |= 1 << i;
176e9778795SPeter Avalos }
17736e94dc5SPeter Avalos }
17818de8d7fSPeter Avalos t = kbdintctxt->devices;
17918de8d7fSPeter Avalos kbdintctxt->devices = t[len] ? xstrdup(t+len+1) : NULL;
18036e94dc5SPeter Avalos free(t);
18118de8d7fSPeter Avalos debug2("kbdint_next_device: devices %s", kbdintctxt->devices ?
18218de8d7fSPeter Avalos kbdintctxt->devices : "<empty>");
18318de8d7fSPeter Avalos } while (kbdintctxt->devices && !kbdintctxt->device);
18418de8d7fSPeter Avalos
18518de8d7fSPeter Avalos return kbdintctxt->device ? 1 : 0;
18618de8d7fSPeter Avalos }
18718de8d7fSPeter Avalos
18818de8d7fSPeter Avalos /*
18918de8d7fSPeter Avalos * try challenge-response, set authctxt->postponed if we have to
19018de8d7fSPeter Avalos * wait for the response.
19118de8d7fSPeter Avalos */
19218de8d7fSPeter Avalos int
auth2_challenge(struct ssh * ssh,char * devs)193ce74bacaSMatthew Dillon auth2_challenge(struct ssh *ssh, char *devs)
19418de8d7fSPeter Avalos {
195ce74bacaSMatthew Dillon Authctxt *authctxt = ssh->authctxt;
19618de8d7fSPeter Avalos debug("auth2_challenge: user=%s devs=%s",
19718de8d7fSPeter Avalos authctxt->user ? authctxt->user : "<nouser>",
19818de8d7fSPeter Avalos devs ? devs : "<no devs>");
19918de8d7fSPeter Avalos
20018de8d7fSPeter Avalos if (authctxt->user == NULL || !devs)
20118de8d7fSPeter Avalos return 0;
20218de8d7fSPeter Avalos if (authctxt->kbdintctxt == NULL)
20318de8d7fSPeter Avalos authctxt->kbdintctxt = kbdint_alloc(devs);
204ce74bacaSMatthew Dillon return auth2_challenge_start(ssh);
20518de8d7fSPeter Avalos }
20618de8d7fSPeter Avalos
20718de8d7fSPeter Avalos /* unregister kbd-int callbacks and context */
20818de8d7fSPeter Avalos void
auth2_challenge_stop(struct ssh * ssh)209ce74bacaSMatthew Dillon auth2_challenge_stop(struct ssh *ssh)
21018de8d7fSPeter Avalos {
211ce74bacaSMatthew Dillon Authctxt *authctxt = ssh->authctxt;
21218de8d7fSPeter Avalos /* unregister callback */
213ce74bacaSMatthew Dillon ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
21418de8d7fSPeter Avalos if (authctxt->kbdintctxt != NULL) {
21518de8d7fSPeter Avalos kbdint_free(authctxt->kbdintctxt);
21618de8d7fSPeter Avalos authctxt->kbdintctxt = NULL;
21718de8d7fSPeter Avalos }
21818de8d7fSPeter Avalos }
21918de8d7fSPeter Avalos
22018de8d7fSPeter Avalos /* side effect: sets authctxt->postponed if a reply was sent*/
22118de8d7fSPeter Avalos static int
auth2_challenge_start(struct ssh * ssh)222ce74bacaSMatthew Dillon auth2_challenge_start(struct ssh *ssh)
22318de8d7fSPeter Avalos {
224ce74bacaSMatthew Dillon Authctxt *authctxt = ssh->authctxt;
22518de8d7fSPeter Avalos KbdintAuthctxt *kbdintctxt = authctxt->kbdintctxt;
22618de8d7fSPeter Avalos
22718de8d7fSPeter Avalos debug2("auth2_challenge_start: devices %s",
22818de8d7fSPeter Avalos kbdintctxt->devices ? kbdintctxt->devices : "<empty>");
22918de8d7fSPeter Avalos
23036e94dc5SPeter Avalos if (kbdint_next_device(authctxt, kbdintctxt) == 0) {
231ce74bacaSMatthew Dillon auth2_challenge_stop(ssh);
23218de8d7fSPeter Avalos return 0;
23318de8d7fSPeter Avalos }
23418de8d7fSPeter Avalos debug("auth2_challenge_start: trying authentication method '%s'",
23518de8d7fSPeter Avalos kbdintctxt->device->name);
23618de8d7fSPeter Avalos
23718de8d7fSPeter Avalos if ((kbdintctxt->ctxt = kbdintctxt->device->init_ctx(authctxt)) == NULL) {
238ce74bacaSMatthew Dillon auth2_challenge_stop(ssh);
23918de8d7fSPeter Avalos return 0;
24018de8d7fSPeter Avalos }
241664f4763Szrj if (send_userauth_info_request(ssh) == 0) {
242ce74bacaSMatthew Dillon auth2_challenge_stop(ssh);
24318de8d7fSPeter Avalos return 0;
24418de8d7fSPeter Avalos }
245ce74bacaSMatthew Dillon ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_RESPONSE,
24618de8d7fSPeter Avalos &input_userauth_info_response);
24718de8d7fSPeter Avalos
24818de8d7fSPeter Avalos authctxt->postponed = 1;
24918de8d7fSPeter Avalos return 0;
25018de8d7fSPeter Avalos }
25118de8d7fSPeter Avalos
25218de8d7fSPeter Avalos static int
send_userauth_info_request(struct ssh * ssh)253664f4763Szrj send_userauth_info_request(struct ssh *ssh)
25418de8d7fSPeter Avalos {
255664f4763Szrj Authctxt *authctxt = ssh->authctxt;
25618de8d7fSPeter Avalos KbdintAuthctxt *kbdintctxt;
25718de8d7fSPeter Avalos char *name, *instr, **prompts;
258664f4763Szrj u_int r, i, *echo_on;
25918de8d7fSPeter Avalos
26018de8d7fSPeter Avalos kbdintctxt = authctxt->kbdintctxt;
26118de8d7fSPeter Avalos if (kbdintctxt->device->query(kbdintctxt->ctxt,
26218de8d7fSPeter Avalos &name, &instr, &kbdintctxt->nreq, &prompts, &echo_on))
26318de8d7fSPeter Avalos return 0;
26418de8d7fSPeter Avalos
265664f4763Szrj if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_INFO_REQUEST)) != 0 ||
266664f4763Szrj (r = sshpkt_put_cstring(ssh, name)) != 0 ||
267664f4763Szrj (r = sshpkt_put_cstring(ssh, instr)) != 0 ||
268664f4763Szrj (r = sshpkt_put_cstring(ssh, "")) != 0 || /* language not used */
269664f4763Szrj (r = sshpkt_put_u32(ssh, kbdintctxt->nreq)) != 0)
270*50a69bb5SSascha Wildner fatal_fr(r, "start packet");
27118de8d7fSPeter Avalos for (i = 0; i < kbdintctxt->nreq; i++) {
272664f4763Szrj if ((r = sshpkt_put_cstring(ssh, prompts[i])) != 0 ||
273664f4763Szrj (r = sshpkt_put_u8(ssh, echo_on[i])) != 0)
274*50a69bb5SSascha Wildner fatal_fr(r, "assemble packet");
27518de8d7fSPeter Avalos }
276664f4763Szrj if ((r = sshpkt_send(ssh)) != 0 ||
277664f4763Szrj (r = ssh_packet_write_wait(ssh)) != 0)
278*50a69bb5SSascha Wildner fatal_fr(r, "send packet");
27918de8d7fSPeter Avalos
28018de8d7fSPeter Avalos for (i = 0; i < kbdintctxt->nreq; i++)
28136e94dc5SPeter Avalos free(prompts[i]);
28236e94dc5SPeter Avalos free(prompts);
28336e94dc5SPeter Avalos free(echo_on);
28436e94dc5SPeter Avalos free(name);
28536e94dc5SPeter Avalos free(instr);
28618de8d7fSPeter Avalos return 1;
28718de8d7fSPeter Avalos }
28818de8d7fSPeter Avalos
289e9778795SPeter Avalos static int
input_userauth_info_response(int type,u_int32_t seq,struct ssh * ssh)290ce74bacaSMatthew Dillon input_userauth_info_response(int type, u_int32_t seq, struct ssh *ssh)
29118de8d7fSPeter Avalos {
292ce74bacaSMatthew Dillon Authctxt *authctxt = ssh->authctxt;
29318de8d7fSPeter Avalos KbdintAuthctxt *kbdintctxt;
294cb5eb4f1SPeter Avalos int authenticated = 0, res;
295664f4763Szrj int r;
29618de8d7fSPeter Avalos u_int i, nresp;
29736e94dc5SPeter Avalos const char *devicename = NULL;
29836e94dc5SPeter Avalos char **response = NULL;
29918de8d7fSPeter Avalos
30018de8d7fSPeter Avalos if (authctxt == NULL)
301*50a69bb5SSascha Wildner fatal_f("no authctxt");
30218de8d7fSPeter Avalos kbdintctxt = authctxt->kbdintctxt;
30318de8d7fSPeter Avalos if (kbdintctxt == NULL || kbdintctxt->ctxt == NULL)
304*50a69bb5SSascha Wildner fatal_f("no kbdintctxt");
30518de8d7fSPeter Avalos if (kbdintctxt->device == NULL)
306*50a69bb5SSascha Wildner fatal_f("no device");
30718de8d7fSPeter Avalos
30818de8d7fSPeter Avalos authctxt->postponed = 0; /* reset */
309664f4763Szrj if ((r = sshpkt_get_u32(ssh, &nresp)) != 0)
310*50a69bb5SSascha Wildner fatal_fr(r, "parse packet");
31118de8d7fSPeter Avalos if (nresp != kbdintctxt->nreq)
312*50a69bb5SSascha Wildner fatal_f("wrong number of replies");
31318de8d7fSPeter Avalos if (nresp > 100)
314*50a69bb5SSascha Wildner fatal_f("too many replies");
31518de8d7fSPeter Avalos if (nresp > 0) {
31618de8d7fSPeter Avalos response = xcalloc(nresp, sizeof(char *));
317*50a69bb5SSascha Wildner for (i = 0; i < nresp; i++) {
318*50a69bb5SSascha Wildner if ((r = sshpkt_get_cstring(ssh, &response[i], NULL)) != 0)
319*50a69bb5SSascha Wildner fatal_fr(r, "parse response");
320*50a69bb5SSascha Wildner }
32118de8d7fSPeter Avalos }
322664f4763Szrj if ((r = sshpkt_get_end(ssh)) != 0)
323*50a69bb5SSascha Wildner fatal_fr(r, "parse packet");
32418de8d7fSPeter Avalos
32518de8d7fSPeter Avalos res = kbdintctxt->device->respond(kbdintctxt->ctxt, nresp, response);
32618de8d7fSPeter Avalos
32718de8d7fSPeter Avalos for (i = 0; i < nresp; i++) {
32836e94dc5SPeter Avalos explicit_bzero(response[i], strlen(response[i]));
32936e94dc5SPeter Avalos free(response[i]);
33018de8d7fSPeter Avalos }
33136e94dc5SPeter Avalos free(response);
33218de8d7fSPeter Avalos
33318de8d7fSPeter Avalos switch (res) {
33418de8d7fSPeter Avalos case 0:
33518de8d7fSPeter Avalos /* Success! */
33618de8d7fSPeter Avalos authenticated = authctxt->valid ? 1 : 0;
33718de8d7fSPeter Avalos break;
33818de8d7fSPeter Avalos case 1:
33918de8d7fSPeter Avalos /* Authentication needs further interaction */
340664f4763Szrj if (send_userauth_info_request(ssh) == 1)
34118de8d7fSPeter Avalos authctxt->postponed = 1;
34218de8d7fSPeter Avalos break;
34318de8d7fSPeter Avalos default:
34418de8d7fSPeter Avalos /* Failure! */
34518de8d7fSPeter Avalos break;
34618de8d7fSPeter Avalos }
34736e94dc5SPeter Avalos devicename = kbdintctxt->device->name;
34818de8d7fSPeter Avalos if (!authctxt->postponed) {
34918de8d7fSPeter Avalos if (authenticated) {
350ce74bacaSMatthew Dillon auth2_challenge_stop(ssh);
35118de8d7fSPeter Avalos } else {
35218de8d7fSPeter Avalos /* start next device */
35318de8d7fSPeter Avalos /* may set authctxt->postponed */
354ce74bacaSMatthew Dillon auth2_challenge_start(ssh);
35518de8d7fSPeter Avalos }
35618de8d7fSPeter Avalos }
357ce74bacaSMatthew Dillon userauth_finish(ssh, authenticated, "keyboard-interactive",
35836e94dc5SPeter Avalos devicename);
359e9778795SPeter Avalos return 0;
36018de8d7fSPeter Avalos }
36118de8d7fSPeter Avalos
36218de8d7fSPeter Avalos void
privsep_challenge_enable(void)36318de8d7fSPeter Avalos privsep_challenge_enable(void)
36418de8d7fSPeter Avalos {
365664f4763Szrj #if defined(BSD_AUTH) || defined(USE_PAM)
36618de8d7fSPeter Avalos int n = 0;
36718de8d7fSPeter Avalos #endif
36818de8d7fSPeter Avalos #ifdef BSD_AUTH
36918de8d7fSPeter Avalos extern KbdintDevice mm_bsdauth_device;
37018de8d7fSPeter Avalos #endif
37118de8d7fSPeter Avalos #ifdef USE_PAM
37218de8d7fSPeter Avalos extern KbdintDevice mm_sshpam_device;
37318de8d7fSPeter Avalos #endif
37418de8d7fSPeter Avalos
37518de8d7fSPeter Avalos #ifdef BSD_AUTH
37618de8d7fSPeter Avalos devices[n++] = &mm_bsdauth_device;
37718de8d7fSPeter Avalos #else
37818de8d7fSPeter Avalos #ifdef USE_PAM
37918de8d7fSPeter Avalos devices[n++] = &mm_sshpam_device;
38018de8d7fSPeter Avalos #endif
38118de8d7fSPeter Avalos #endif
38218de8d7fSPeter Avalos }
383