OSDN Git Service

Define HAVE_ATTRIBUTE__SENTINEL__ to 1.
[android-x86/external-openssh.git] / auth2-chall.c
index e6dbffe..4aff09d 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-chall.c,v 1.34 2008/12/09 04:32:22 djm Exp $ */
+/* $OpenBSD: auth2-chall.c,v 1.43 2015/07/18 07:57:14 djm Exp $ */
 /*
  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2001 Per Allansson.  All rights reserved.
@@ -41,6 +41,7 @@
 #include "packet.h"
 #include "dispatch.h"
 #include "log.h"
+#include "misc.h"
 #include "servconf.h"
 
 /* import */
@@ -48,7 +49,7 @@ extern ServerOptions options;
 
 static int auth2_challenge_start(Authctxt *);
 static int send_userauth_info_request(Authctxt *);
-static void input_userauth_info_response(int, u_int32_t, void *);
+static int input_userauth_info_response(int, u_int32_t, void *);
 
 #ifdef BSD_AUTH
 extern KbdintDevice bsdauth_device;
@@ -82,6 +83,7 @@ struct KbdintAuthctxt
        void *ctxt;
        KbdintDevice *device;
        u_int nreq;
+       u_int devices_done;
 };
 
 #ifdef USE_PAM
@@ -111,7 +113,7 @@ kbdint_alloc(const char *devs)
                remove_kbdint_device("pam");
 #endif
 
-       kbdintctxt = xmalloc(sizeof(KbdintAuthctxt));
+       kbdintctxt = xcalloc(1, sizeof(KbdintAuthctxt));
        if (strcmp(devs, "") == 0) {
                buffer_init(&b);
                for (i = 0; devices[i]; i++) {
@@ -147,15 +149,13 @@ kbdint_free(KbdintAuthctxt *kbdintctxt)
 {
        if (kbdintctxt->device)
                kbdint_reset_device(kbdintctxt);
-       if (kbdintctxt->devices) {
-               xfree(kbdintctxt->devices);
-               kbdintctxt->devices = NULL;
-       }
-       xfree(kbdintctxt);
+       free(kbdintctxt->devices);
+       explicit_bzero(kbdintctxt, sizeof(*kbdintctxt));
+       free(kbdintctxt);
 }
 /* get next device */
 static int
-kbdint_next_device(KbdintAuthctxt *kbdintctxt)
+kbdint_next_device(Authctxt *authctxt, KbdintAuthctxt *kbdintctxt)
 {
        size_t len;
        char *t;
@@ -169,12 +169,20 @@ kbdint_next_device(KbdintAuthctxt *kbdintctxt)
 
                if (len == 0)
                        break;
-               for (i = 0; devices[i]; i++)
-                       if (strncmp(kbdintctxt->devices, devices[i]->name, len) == 0)
+               for (i = 0; devices[i]; i++) {
+                       if ((kbdintctxt->devices_done & (1 << i)) != 0 ||
+                           !auth2_method_allowed(authctxt,
+                           "keyboard-interactive", devices[i]->name))
+                               continue;
+                       if (strncmp(kbdintctxt->devices, devices[i]->name,
+                           len) == 0) {
                                kbdintctxt->device = devices[i];
+                               kbdintctxt->devices_done |= 1 << i;
+                       }
+               }
                t = kbdintctxt->devices;
                kbdintctxt->devices = t[len] ? xstrdup(t+len+1) : NULL;
-               xfree(t);
+               free(t);
                debug2("kbdint_next_device: devices %s", kbdintctxt->devices ?
                    kbdintctxt->devices : "<empty>");
        } while (kbdintctxt->devices && !kbdintctxt->device);
@@ -221,7 +229,7 @@ auth2_challenge_start(Authctxt *authctxt)
        debug2("auth2_challenge_start: devices %s",
            kbdintctxt->devices ?  kbdintctxt->devices : "<empty>");
 
-       if (kbdint_next_device(kbdintctxt) == 0) {
+       if (kbdint_next_device(authctxt, kbdintctxt) == 0) {
                auth2_challenge_stop(authctxt);
                return 0;
        }
@@ -268,22 +276,23 @@ send_userauth_info_request(Authctxt *authctxt)
        packet_write_wait();
 
        for (i = 0; i < kbdintctxt->nreq; i++)
-               xfree(prompts[i]);
-       xfree(prompts);
-       xfree(echo_on);
-       xfree(name);
-       xfree(instr);
+               free(prompts[i]);
+       free(prompts);
+       free(echo_on);
+       free(name);
+       free(instr);
        return 1;
 }
 
-static void
+static int
 input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
 {
        Authctxt *authctxt = ctxt;
        KbdintAuthctxt *kbdintctxt;
        int authenticated = 0, res;
        u_int i, nresp;
-       char **response = NULL, *method;
+       const char *devicename = NULL;
+       char **response = NULL;
 
        if (authctxt == NULL)
                fatal("input_userauth_info_response: no authctxt");
@@ -309,11 +318,10 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
        res = kbdintctxt->device->respond(kbdintctxt->ctxt, nresp, response);
 
        for (i = 0; i < nresp; i++) {
-               memset(response[i], 'r', strlen(response[i]));
-               xfree(response[i]);
+               explicit_bzero(response[i], strlen(response[i]));
+               free(response[i]);
        }
-       if (response)
-               xfree(response);
+       free(response);
 
        switch (res) {
        case 0:
@@ -329,9 +337,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
                /* Failure! */
                break;
        }
-
-       xasprintf(&method, "keyboard-interactive/%s", kbdintctxt->device->name);
-
+       devicename = kbdintctxt->device->name;
        if (!authctxt->postponed) {
                if (authenticated) {
                        auth2_challenge_stop(authctxt);
@@ -341,8 +347,9 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt)
                        auth2_challenge_start(authctxt);
                }
        }
-       userauth_finish(authctxt, authenticated, method);
-       xfree(method);
+       userauth_finish(authctxt, authenticated, "keyboard-interactive",
+           devicename);
+       return 0;
 }
 
 void