summaryrefslogtreecommitdiff
path: root/usr.bin/ssh
diff options
context:
space:
mode:
authorMarkus Friedl <markus@cvs.openbsd.org>2001-05-18 14:13:30 +0000
committerMarkus Friedl <markus@cvs.openbsd.org>2001-05-18 14:13:30 +0000
commit887cfdd77aaa2210e1da65fcd2a5a4452b0cbc29 (patch)
tree93af6307b283f25bcbce9a9c6c8baa89c9a36649 /usr.bin/ssh
parent87a316979eadfa099f50a4ed7b87a1ccce28a79c (diff)
improved kbd-interactive support. work by per@appgate.com and me
Diffstat (limited to 'usr.bin/ssh')
-rw-r--r--usr.bin/ssh/auth-bsdauth.c116
-rw-r--r--usr.bin/ssh/auth-chall.c110
-rw-r--r--usr.bin/ssh/auth-skey.c97
-rw-r--r--usr.bin/ssh/auth.h27
-rw-r--r--usr.bin/ssh/auth1.c9
-rw-r--r--usr.bin/ssh/auth2-chall.c279
-rw-r--r--usr.bin/ssh/auth2.c16
-rw-r--r--usr.bin/ssh/readconf.c10
-rw-r--r--usr.bin/ssh/readconf.h4
-rw-r--r--usr.bin/ssh/servconf.c10
-rw-r--r--usr.bin/ssh/servconf.h4
-rw-r--r--usr.bin/ssh/sshconnect1.c8
-rw-r--r--usr.bin/ssh/sshconnect2.c5
-rw-r--r--usr.bin/ssh/sshd.c4
-rw-r--r--usr.bin/ssh/sshd/Makefile5
15 files changed, 557 insertions, 147 deletions
diff --git a/usr.bin/ssh/auth-bsdauth.c b/usr.bin/ssh/auth-bsdauth.c
new file mode 100644
index 00000000000..3732477deb0
--- /dev/null
+++ b/usr.bin/ssh/auth-bsdauth.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2001 Markus Friedl. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "includes.h"
+RCSID("$OpenBSD: auth-bsdauth.c,v 1.1 2001/05/18 14:13:28 markus Exp $");
+
+#ifdef BSD_AUTH
+#include "xmalloc.h"
+#include "auth.h"
+#include "log.h"
+
+static void *
+bsdauth_init_ctx(Authctxt *authctxt)
+{
+ return authctxt;
+}
+
+static int
+bsdauth_query(void *ctx, char **name, char **infotxt,
+ u_int *numprompts, char ***prompts, u_int **echo_on)
+{
+ Authctxt *authctxt = ctx;
+ char *challenge = NULL;
+
+ if (authctxt->as != NULL) {
+ debug2("bsdauth_query: try reuse session");
+ challenge = auth_getitem(authctxt->as, AUTHV_CHALLENGE);
+ if (challenge == NULL) {
+ auth_close(authctxt->as);
+ authctxt->as = NULL;
+ }
+ }
+
+ if (challenge == NULL) {
+ debug2("bsdauth_query: new bsd auth session");
+ debug3("bsdauth_query: style %s",
+ authctxt->style ? authctxt->style : "<default>");
+ authctxt->as = auth_userchallenge(authctxt->user,
+ authctxt->style, "auth-ssh", &challenge);
+ if (authctxt->as == NULL)
+ challenge = NULL;
+ debug2("bsdauth_query: <%s>", challenge ? challenge : "empty");
+ }
+
+ if (challenge == NULL)
+ return -1;
+
+ *name = xstrdup("");
+ *infotxt = xstrdup("");
+ *numprompts = 1;
+ *prompts = xmalloc(*numprompts * sizeof(char*));
+ *echo_on = xmalloc(*numprompts * sizeof(u_int));
+ (*echo_on)[0] = 0;
+ (*prompts)[0] = xstrdup(challenge);
+
+ return 0;
+}
+
+static int
+bsdauth_respond(void *ctx, u_int numresponses, char **responses)
+{
+ Authctxt *authctxt = ctx;
+ int authok;
+
+ if (authctxt->as == 0)
+ error("bsdauth_respond: no bsd auth session");
+
+ if (numresponses != 1)
+ return -1;
+
+ authok = auth_userresponse(authctxt->as, responses[0], 0);
+ authctxt->as = NULL;
+ debug3("bsdauth_respond: <%s> = <%d>", responses[0], authok);
+
+ return (authok == 0) ? -1 : 0;
+}
+
+static void
+bsdauth_free_ctx(void *ctx)
+{
+ Authctxt *authctxt = ctx;
+
+ if (authctxt && authctxt->as) {
+ auth_close(authctxt->as);
+ authctxt->as = NULL;
+ }
+}
+
+KbdintDevice bsdauth_device = {
+ "bsdauth",
+ bsdauth_init_ctx,
+ bsdauth_query,
+ bsdauth_respond,
+ bsdauth_free_ctx
+};
+#endif
diff --git a/usr.bin/ssh/auth-chall.c b/usr.bin/ssh/auth-chall.c
index f3502f4eee3..45e0c34522b 100644
--- a/usr.bin/ssh/auth-chall.c
+++ b/usr.bin/ssh/auth-chall.c
@@ -23,82 +23,60 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: auth-chall.c,v 1.7 2001/04/05 10:42:47 markus Exp $");
+RCSID("$OpenBSD: auth-chall.c,v 1.8 2001/05/18 14:13:28 markus Exp $");
#include "auth.h"
#include "log.h"
+#include "xmalloc.h"
-#ifdef BSD_AUTH
-char *
-get_challenge(Authctxt *authctxt, char *devs)
-{
- char *challenge;
+/* limited protocol v1 interface to kbd-interactive authentication */
- if (authctxt->as != NULL) {
- debug2("try reuse session");
- challenge = auth_getitem(authctxt->as, AUTHV_CHALLENGE);
- if (challenge != NULL) {
- debug2("reuse bsd auth session");
- return challenge;
- }
- auth_close(authctxt->as);
- authctxt->as = NULL;
- }
- debug2("new bsd auth session");
- if (devs == NULL || strlen(devs) == 0)
- devs = authctxt->style;
- debug3("bsd auth: devs %s", devs ? devs : "<default>");
- authctxt->as = auth_userchallenge(authctxt->user, devs, "auth-ssh",
- &challenge);
- if (authctxt->as == NULL)
- return NULL;
- debug2("get_challenge: <%s>", challenge ? challenge : "EMPTY");
- return challenge;
-}
-int
-verify_response(Authctxt *authctxt, char *response)
-{
- int authok;
-
- if (authctxt->as == 0)
- error("verify_response: no bsd auth session");
- authok = auth_userresponse(authctxt->as, response, 0);
- authctxt->as = NULL;
- debug("verify_response: <%s> = <%d>", response, authok);
- return authok != 0;
-}
-#else
-#ifdef SKEY
-#include <skey.h>
+extern KbdintDevice *devices[];
+static KbdintDevice *device;
char *
-get_challenge(Authctxt *authctxt, char *devs)
+get_challenge(Authctxt *authctxt)
{
- static char challenge[1024];
- struct skey skey;
- if (skeychallenge(&skey, authctxt->user, challenge) == -1)
+ char *challenge, *name, *info, **prompts;
+ u_int i, numprompts;
+ u_int *echo_on;
+
+ device = devices[0]; /* we always use the 1st device for protocol 1 */
+ if (device == NULL)
return NULL;
- strlcat(challenge, "\nS/Key Password: ", sizeof challenge);
- return challenge;
-}
-int
-verify_response(Authctxt *authctxt, char *response)
-{
- return (authctxt->valid &&
- skey_haskey(authctxt->pw->pw_name) == 0 &&
- skey_passcheck(authctxt->pw->pw_name, response) != -1);
-}
-#else
-/* not available */
-char *
-get_challenge(Authctxt *authctxt, char *devs)
-{
- return NULL;
+ if ((authctxt->kbdintctxt = device->init_ctx(authctxt)) == NULL)
+ return NULL;
+ if (device->query(authctxt->kbdintctxt, &name, &info,
+ &numprompts, &prompts, &echo_on)) {
+ device->free_ctx(authctxt->kbdintctxt);
+ authctxt->kbdintctxt = NULL;
+ return NULL;
+ }
+ if (numprompts < 1)
+ fatal("get_challenge: numprompts < 1");
+ challenge = xstrdup(prompts[0]);
+ for (i = 0; i < numprompts; i++)
+ xfree(prompts[i]);
+ xfree(prompts);
+ xfree(name);
+ xfree(echo_on);
+ xfree(info);
+
+ return (challenge);
}
int
-verify_response(Authctxt *authctxt, char *response)
+verify_response(Authctxt *authctxt, const char *response)
{
- return 0;
+ char *resp[1];
+ int res;
+
+ if (device == NULL)
+ return 0;
+ if (authctxt->kbdintctxt == NULL)
+ return 0;
+ resp[0] = (char *)response;
+ res = device->respond(authctxt->kbdintctxt, 1, resp);
+ device->free_ctx(authctxt->kbdintctxt);
+ authctxt->kbdintctxt = NULL;
+ return res ? 0 : 1;
}
-#endif
-#endif
diff --git a/usr.bin/ssh/auth-skey.c b/usr.bin/ssh/auth-skey.c
new file mode 100644
index 00000000000..f921fc1bb70
--- /dev/null
+++ b/usr.bin/ssh/auth-skey.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2001 Markus Friedl. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "includes.h"
+RCSID("$OpenBSD: auth-skey.c,v 1.12 2001/05/18 14:13:28 markus Exp $");
+
+#ifdef SKEY
+
+#include <skey.h>
+
+#include "xmalloc.h"
+#include "auth.h"
+
+static void *
+skey_init_ctx(Authctxt *authctxt)
+{
+ return authctxt;
+}
+
+#define PROMPT "\nS/Key Password: "
+
+static int
+skey_query(void *ctx, char **name, char **infotxt,
+ u_int* numprompts, char ***prompts, u_int **echo_on)
+{
+ Authctxt *authctxt = ctx;
+ char challenge[1024], *p;
+ int len;
+ struct skey skey;
+
+ if (skeychallenge(&skey, authctxt->user, challenge) == -1)
+ return -1;
+
+ *name = xstrdup("");
+ *infotxt = xstrdup("");
+ *numprompts = 1;
+ *prompts = xmalloc(*numprompts * sizeof(char*));
+ *echo_on = xmalloc(*numprompts * sizeof(u_int));
+ (*echo_on)[0] = 0;
+
+ len = strlen(challenge) + strlen(PROMPT) + 1;
+ p = xmalloc(len);
+ p[0] = '\0';
+ strlcat(p, challenge, len);
+ strlcat(p, PROMPT, len);
+ (*prompts)[0] = p;
+
+ return 0;
+}
+
+static int
+skey_respond(void *ctx, u_int numresponses, char **responses)
+{
+ Authctxt *authctxt = ctx;
+
+ if (authctxt->valid &&
+ numresponses == 1 &&
+ skey_haskey(authctxt->pw->pw_name) == 0 &&
+ skey_passcheck(authctxt->pw->pw_name, responses[0]) != -1)
+ return 0;
+ return -1;
+}
+
+static void
+skey_free_ctx(void *ctx)
+{
+ /* we don't have a special context */
+}
+
+KbdintDevice skey_device = {
+ "skey",
+ skey_init_ctx,
+ skey_query,
+ skey_respond,
+ skey_free_ctx
+};
+#endif /* SKEY */
diff --git a/usr.bin/ssh/auth.h b/usr.bin/ssh/auth.h
index 500b73a3f0f..8927957bc9d 100644
--- a/usr.bin/ssh/auth.h
+++ b/usr.bin/ssh/auth.h
@@ -21,7 +21,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $OpenBSD: auth.h,v 1.15 2001/04/12 19:15:24 markus Exp $
+ * $OpenBSD: auth.h,v 1.16 2001/05/18 14:13:28 markus Exp $
*/
#ifndef AUTH_H
#define AUTH_H
@@ -36,6 +36,8 @@
#endif
typedef struct Authctxt Authctxt;
+typedef struct KbdintDevice KbdintDevice;
+
struct Authctxt {
int success;
int postponed;
@@ -46,12 +48,31 @@ struct Authctxt {
char *service;
struct passwd *pw;
char *style;
+ void *kbdintctxt;
#ifdef BSD_AUTH
auth_session_t *as;
#endif
};
/*
+ * Keyboard interactive device:
+ * init_ctx returns: non NULL upon success
+ * query returns: 0 - success, otherwise failure
+ * respond returns: 0 - success, 1 - need further interaction,
+ * otherwise - failure
+ */
+struct KbdintDevice
+{
+ const char *name;
+ void* (*init_ctx) __P((Authctxt*));
+ int (*query) __P((void *ctx, char **name, char **infotxt,
+ u_int *numprompts, char ***prompts,
+ u_int **echo_on));
+ int (*respond) __P((void *ctx, u_int numresp, char **responses));
+ void (*free_ctx) __P((void *ctx));
+};
+
+/*
* Tries to authenticate the user using the .rhosts file. Returns true if
* authentication succeeds. If ignore_rhosts is non-zero, this will not
* consider .rhosts and .shosts (/etc/hosts.equiv will still be used).
@@ -130,8 +151,8 @@ int auth2_challenge(Authctxt *authctxt, char *devs);
int allowed_user(struct passwd * pw);
-char *get_challenge(Authctxt *authctxt, char *devs);
-int verify_response(Authctxt *authctxt, char *response);
+char *get_challenge(Authctxt *authctxt);
+int verify_response(Authctxt *authctxt, const char *response);
struct passwd * auth_get_user(void);
diff --git a/usr.bin/ssh/auth1.c b/usr.bin/ssh/auth1.c
index 00abdb2297a..3fb0d5dc716 100644
--- a/usr.bin/ssh/auth1.c
+++ b/usr.bin/ssh/auth1.c
@@ -10,7 +10,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: auth1.c,v 1.22 2001/03/23 12:02:49 markus Exp $");
+RCSID("$OpenBSD: auth1.c,v 1.23 2001/05/18 14:13:28 markus Exp $");
#include "xmalloc.h"
#include "rsa.h"
@@ -252,12 +252,13 @@ do_authloop(Authctxt *authctxt)
case SSH_CMSG_AUTH_TIS:
debug("rcvd SSH_CMSG_AUTH_TIS");
- if (options.challenge_reponse_authentication == 1) {
- char *challenge = get_challenge(authctxt, authctxt->style);
+ if (options.challenge_response_authentication == 1) {
+ char *challenge = get_challenge(authctxt);
if (challenge != NULL) {
debug("sending challenge '%s'", challenge);
packet_start(SSH_SMSG_AUTH_TIS_CHALLENGE);
packet_put_cstring(challenge);
+ xfree(challenge);
packet_send();
packet_write_wait();
continue;
@@ -266,7 +267,7 @@ do_authloop(Authctxt *authctxt)
break;
case SSH_CMSG_AUTH_TIS_RESPONSE:
debug("rcvd SSH_CMSG_AUTH_TIS_RESPONSE");
- if (options.challenge_reponse_authentication == 1) {
+ if (options.challenge_response_authentication == 1) {
char *response = packet_get_string(&dlen);
debug("got response '%s'", response);
packet_integrity_check(plen, 4 + dlen, type);
diff --git a/usr.bin/ssh/auth2-chall.c b/usr.bin/ssh/auth2-chall.c
index 5af60e42fa0..ad4f7ac42e5 100644
--- a/usr.bin/ssh/auth2-chall.c
+++ b/usr.bin/ssh/auth2-chall.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
+ * Copyright (c) 2001 Per Allansson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -22,91 +23,285 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "includes.h"
-RCSID("$OpenBSD: auth2-chall.c,v 1.4 2001/03/28 22:43:31 markus Exp $");
+RCSID("$OpenBSD: auth2-chall.c,v 1.5 2001/05/18 14:13:28 markus Exp $");
#include "ssh2.h"
#include "auth.h"
#include "packet.h"
#include "xmalloc.h"
#include "dispatch.h"
+#include "auth.h"
#include "log.h"
-void send_userauth_into_request(Authctxt *authctxt, char *challenge, int echo);
-void input_userauth_info_response(int type, int plen, void *ctxt);
+static int auth2_challenge_start(Authctxt *authctxt);
+static int send_userauth_info_request(Authctxt *authctxt);
+static void input_userauth_info_response(int type, int plen, void *ctxt);
+
+#ifdef BSD_AUTH
+extern KbdintDevice bsdauth_device;
+#else
+#ifdef SKEY
+extern KbdintDevice skey_device;
+#endif
+#endif
+
+KbdintDevice *devices[] = {
+#ifdef BSD_AUTH
+ &bsdauth_device,
+#else
+#ifdef SKEY
+ &skey_device,
+#endif
+#endif
+ NULL
+};
+
+typedef struct KbdintAuthctxt KbdintAuthctxt;
+struct KbdintAuthctxt
+{
+ char *devices;
+ void *ctxt;
+ KbdintDevice *device;
+};
+
+KbdintAuthctxt *
+kbdint_alloc(const char *devs)
+{
+ KbdintAuthctxt *kbdintctxt;
+ int i;
+ char buf[1024];
+
+ kbdintctxt = xmalloc(sizeof(KbdintAuthctxt));
+ if (strcmp(devs, "") == 0) {
+ buf[0] = '\0';
+ for (i = 0; devices[i]; i++) {
+ if (i != 0)
+ strlcat(buf, ",", sizeof(buf));
+ strlcat(buf, devices[i]->name, sizeof(buf));
+ }
+ debug("kbdint_alloc: devices '%s'", buf);
+ kbdintctxt->devices = xstrdup(buf);
+ } else {
+ kbdintctxt->devices = xstrdup(devs);
+ }
+ kbdintctxt->ctxt = NULL;
+ kbdintctxt->device = NULL;
+
+ return kbdintctxt;
+}
+void
+kbdint_reset_device(KbdintAuthctxt *kbdintctxt)
+{
+ if (kbdintctxt->ctxt) {
+ kbdintctxt->device->free_ctx(kbdintctxt->ctxt);
+ kbdintctxt->ctxt = NULL;
+ }
+ kbdintctxt->device = NULL;
+}
+void
+kbdint_free(KbdintAuthctxt *kbdintctxt)
+{
+ if (kbdintctxt->device)
+ kbdint_reset_device(kbdintctxt);
+ if (kbdintctxt->devices) {
+ xfree(kbdintctxt->devices);
+ kbdintctxt->devices = NULL;
+ }
+ xfree(kbdintctxt);
+}
+/* get next device */
+int
+kbdint_next_device(KbdintAuthctxt *kbdintctxt)
+{
+ size_t len;
+ char *t;
+ int i;
+
+ if (kbdintctxt->device)
+ kbdint_reset_device(kbdintctxt);
+ do {
+ len = kbdintctxt->devices ?
+ strcspn(kbdintctxt->devices, ",") : 0;
+
+ if (len == 0)
+ break;
+ for (i = 0; devices[i]; i++)
+ if (strncmp(kbdintctxt->devices, devices[i]->name, len) == 0)
+ kbdintctxt->device = devices[i];
+ t = kbdintctxt->devices;
+ kbdintctxt->devices = t[len] ? xstrdup(t+len+1) : NULL;
+ xfree(t);
+ debug2("kbdint_next_device: devices %s", kbdintctxt->devices ?
+ kbdintctxt->devices : "<empty>");
+ } while (kbdintctxt->devices && !kbdintctxt->device);
+
+ return kbdintctxt->device ? 1 : 0;
+}
/*
- * try challenge-reponse, return -1 (= postponed) if we have to
+ * try challenge-reponse, set authctxt->postponed if we have to
* wait for the response.
*/
int
auth2_challenge(Authctxt *authctxt, char *devs)
{
- char *challenge;
+ debug("auth2_challenge: user=%s devs=%s",
+ authctxt->user ? authctxt->user : "<nouser>",
+ devs ? devs : "<no devs>");
+
+ if (!authctxt->valid || authctxt->user == NULL || !devs)
+ return 0;
+ if (authctxt->kbdintctxt == NULL)
+ authctxt->kbdintctxt = kbdint_alloc(devs);
+ return auth2_challenge_start(authctxt);
+}
+
+/* side effect: sets authctxt->postponed if a reply was sent*/
+static int
+auth2_challenge_start(Authctxt *authctxt)
+{
+ KbdintAuthctxt *kbdintctxt = authctxt->kbdintctxt;
+
+ debug2("auth2_challenge_start: devices %s",
+ kbdintctxt->devices ? kbdintctxt->devices : "<empty>");
+
+ if (kbdint_next_device(kbdintctxt) == 0) {
+ kbdint_free(kbdintctxt);
+ authctxt->kbdintctxt = NULL;
+ return 0;
+ }
+ debug("auth2_challenge_start: trying authentication method '%s'",
+ kbdintctxt->device->name);
- if (!authctxt->valid || authctxt->user == NULL)
+ if ((kbdintctxt->ctxt = kbdintctxt->device->init_ctx(authctxt)) == NULL) {
+ kbdint_free(kbdintctxt);
+ authctxt->kbdintctxt = NULL;
return 0;
- if ((challenge = get_challenge(authctxt, devs)) == NULL)
+ }
+ if (send_userauth_info_request(authctxt) == 0) {
+ kbdint_free(kbdintctxt);
+ authctxt->kbdintctxt = NULL;
return 0;
- send_userauth_into_request(authctxt, challenge, 0);
+ }
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE,
&input_userauth_info_response);
+
authctxt->postponed = 1;
return 0;
}
-void
-send_userauth_into_request(Authctxt *authctxt, char *challenge, int echo)
+static int
+send_userauth_info_request(Authctxt *authctxt)
{
- int nprompts = 1;
+ KbdintAuthctxt *kbdintctxt;
+ char *name, *instr, **prompts;
+ int i;
+ u_int numprompts, *echo_on;
+
+ kbdintctxt = authctxt->kbdintctxt;
+ if (kbdintctxt->device->query(kbdintctxt->ctxt,
+ &name, &instr, &numprompts, &prompts, &echo_on))
+ return 0;
packet_start(SSH2_MSG_USERAUTH_INFO_REQUEST);
- /* name, instruction and language are unused */
- packet_put_cstring("");
- packet_put_cstring("");
- packet_put_cstring("");
- packet_put_int(nprompts);
- packet_put_cstring(challenge);
- packet_put_char(echo);
+ packet_put_cstring(name);
+ packet_put_cstring(instr);
+ packet_put_cstring(""); /* language not used */
+ packet_put_int(numprompts);
+ for (i = 0; i < numprompts; i++) {
+ packet_put_cstring(prompts[i]);
+ packet_put_char(echo_on[i]);
+ }
packet_send();
packet_write_wait();
+
+ for (i = 0; i < numprompts; i++)
+ xfree(prompts[i]);
+ xfree(prompts);
+ xfree(echo_on);
+ xfree(name);
+ xfree(instr);
+ return 1;
}
-void
+static void
input_userauth_info_response(int type, int plen, void *ctxt)
{
Authctxt *authctxt = ctxt;
- int authenticated = 0;
- u_int nresp, rlen;
- char *response, *method = "challenge-reponse";
+ KbdintAuthctxt *kbdintctxt;
+ int i, authenticated = 0, res, len;
+ u_int nresp;
+ char **response = NULL, *method;
if (authctxt == NULL)
fatal("input_userauth_info_response: no authctxt");
+ kbdintctxt = authctxt->kbdintctxt;
+ if (kbdintctxt == NULL || kbdintctxt->ctxt == NULL)
+ fatal("input_userauth_info_response: no kbdintctxt");
+ if (kbdintctxt->device == NULL)
+ fatal("input_userauth_info_response: no device");
authctxt->postponed = 0; /* reset */
nresp = packet_get_int();
- if (nresp == 1) {
- response = packet_get_string(&rlen);
- packet_done();
- if (strlen(response) == 0) {
- /*
- * if we received an empty response, resend challenge
- * with echo enabled
- */
- char *challenge = get_challenge(authctxt, NULL);
- if (challenge != NULL) {
- send_userauth_into_request(authctxt,
- challenge, 1);
- authctxt->postponed = 1;
- }
- } else if (authctxt->valid) {
- authenticated = verify_response(authctxt, response);
- memset(response, 'r', rlen);
- }
+ if (nresp > 0) {
+ response = xmalloc(nresp * sizeof(char*));
+ for (i = 0; i < nresp; i++)
+ response[i] = packet_get_string(NULL);
+ }
+ packet_done();
+
+ if (authctxt->valid) {
+ res = kbdintctxt->device->respond(kbdintctxt->ctxt,
+ nresp, response);
+ } else {
+ res = -1;
+ }
+
+ for (i = 0; i < nresp; i++) {
+ memset(response[i], 'r', strlen(response[i]));
+ xfree(response[i]);
+ }
+ if (response)
xfree(response);
+
+ switch (res) {
+ case 0:
+ /* Success! */
+ authenticated = 1;
+ break;
+ case 1:
+ /* Authentication needs further interaction */
+ authctxt->postponed = 1;
+ if (send_userauth_info_request(authctxt) == 0) {
+ authctxt->postponed = 0;
+ }
+ break;
+ default:
+ /* Failure! */
+ break;
}
- /* unregister callback */
- if (!authctxt->postponed)
+
+ len = strlen("keyboard-interactive") + 2 +
+ strlen(kbdintctxt->device->name);
+ method = xmalloc(len);
+ method[0] = '\0';
+ strlcat(method, "keyboard-interactive", len);
+ strlcat(method, "/", len);
+ strlcat(method, kbdintctxt->device->name, len);
+
+ if (!authctxt->postponed) {
+ /* unregister callback */
dispatch_set(SSH2_MSG_USERAUTH_INFO_RESPONSE, NULL);
+ if (authenticated) {
+ kbdint_free(kbdintctxt);
+ authctxt->kbdintctxt = NULL;
+ } else {
+ /* start next device */
+ /* may set authctxt->postponed */
+ auth2_challenge_start(authctxt);
+ }
+ }
userauth_finish(authctxt, authenticated, method);
+ xfree(method);
}
diff --git a/usr.bin/ssh/auth2.c b/usr.bin/ssh/auth2.c
index f2ee9a2dbc1..18c2545fe90 100644
--- a/usr.bin/ssh/auth2.c
+++ b/usr.bin/ssh/auth2.c
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: auth2.c,v 1.56 2001/04/19 00:05:11 markus Exp $");
+RCSID("$OpenBSD: auth2.c,v 1.57 2001/05/18 14:13:28 markus Exp $");
#include <openssl/evp.h>
@@ -51,6 +51,7 @@ RCSID("$OpenBSD: auth2.c,v 1.56 2001/04/19 00:05:11 markus Exp $");
#include "hostfile.h"
#include "canohost.h"
#include "tildexpand.h"
+#include "match.h"
/* import */
extern ServerOptions options;
@@ -121,7 +122,7 @@ do_authentication2()
x_authctxt = authctxt; /*XXX*/
/* challenge-reponse is implemented via keyboard interactive */
- if (options.challenge_reponse_authentication)
+ if (options.challenge_response_authentication)
options.kbd_interactive_authentication = 1;
dispatch_init(&protocol_error);
@@ -352,20 +353,19 @@ int
userauth_kbdint(Authctxt *authctxt)
{
int authenticated = 0;
- char *lang = NULL;
- char *devs = NULL;
-
+ char *lang, *devs;
+
lang = packet_get_string(NULL);
devs = packet_get_string(NULL);
packet_done();
- debug("keyboard-interactive language %s devs %s", lang, devs);
+ debug("keyboard-interactive devs %s", devs);
- if (options.challenge_reponse_authentication)
+ if (options.challenge_response_authentication)
authenticated = auth2_challenge(authctxt, devs);
- xfree(lang);
xfree(devs);
+ xfree(lang);
return authenticated;
}
diff --git a/usr.bin/ssh/readconf.c b/usr.bin/ssh/readconf.c
index 7c7a4ebab4c..ca17ef4ee0c 100644
--- a/usr.bin/ssh/readconf.c
+++ b/usr.bin/ssh/readconf.c
@@ -12,7 +12,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: readconf.c,v 1.77 2001/04/30 11:18:51 markus Exp $");
+RCSID("$OpenBSD: readconf.c,v 1.78 2001/05/18 14:13:28 markus Exp $");
#include "ssh.h"
#include "xmalloc.h"
@@ -331,7 +331,7 @@ parse_flag:
goto parse_flag;
case oChallengeResponseAuthentication:
- intptr = &options->challenge_reponse_authentication;
+ intptr = &options->challenge_response_authentication;
goto parse_flag;
#ifdef KRB4
@@ -721,7 +721,7 @@ initialize_options(Options * options)
options->rhosts_authentication = -1;
options->rsa_authentication = -1;
options->pubkey_authentication = -1;
- options->challenge_reponse_authentication = -1;
+ options->challenge_response_authentication = -1;
#ifdef KRB4
options->kerberos_authentication = -1;
#endif
@@ -795,8 +795,8 @@ fill_default_options(Options * options)
options->rsa_authentication = 1;
if (options->pubkey_authentication == -1)
options->pubkey_authentication = 1;
- if (options->challenge_reponse_authentication == -1)
- options->challenge_reponse_authentication = 0;
+ if (options->challenge_response_authentication == -1)
+ options->challenge_response_authentication = 0;
#ifdef KRB4
if (options->kerberos_authentication == -1)
options->kerberos_authentication = 1;
diff --git a/usr.bin/ssh/readconf.h b/usr.bin/ssh/readconf.h
index 4b20c93bf5d..489ffc8c19d 100644
--- a/usr.bin/ssh/readconf.h
+++ b/usr.bin/ssh/readconf.h
@@ -11,7 +11,7 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-/* RCSID("$OpenBSD: readconf.h,v 1.31 2001/04/30 11:18:52 markus Exp $"); */
+/* RCSID("$OpenBSD: readconf.h,v 1.32 2001/05/18 14:13:29 markus Exp $"); */
#ifndef READCONF_H
#define READCONF_H
@@ -39,7 +39,7 @@ typedef struct {
int rsa_authentication; /* Try RSA authentication. */
int pubkey_authentication; /* Try ssh2 pubkey authentication. */
int hostbased_authentication; /* ssh2's rhosts_rsa */
- int challenge_reponse_authentication;
+ int challenge_response_authentication;
/* Try S/Key or TIS, authentication. */
#ifdef KRB4
int kerberos_authentication; /* Try Kerberos
diff --git a/usr.bin/ssh/servconf.c b/usr.bin/ssh/servconf.c
index 10ec41200a8..40c2e1035df 100644
--- a/usr.bin/ssh/servconf.c
+++ b/usr.bin/ssh/servconf.c
@@ -10,7 +10,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: servconf.c,v 1.79 2001/05/03 21:43:01 stevesk Exp $");
+RCSID("$OpenBSD: servconf.c,v 1.80 2001/05/18 14:13:29 markus Exp $");
#ifdef KRB4
#include <krb.h>
@@ -81,7 +81,7 @@ initialize_server_options(ServerOptions *options)
#endif
options->password_authentication = -1;
options->kbd_interactive_authentication = -1;
- options->challenge_reponse_authentication = -1;
+ options->challenge_response_authentication = -1;
options->permit_empty_passwd = -1;
options->use_login = -1;
options->allow_tcp_forwarding = -1;
@@ -185,8 +185,8 @@ fill_default_server_options(ServerOptions *options)
options->password_authentication = 1;
if (options->kbd_interactive_authentication == -1)
options->kbd_interactive_authentication = 0;
- if (options->challenge_reponse_authentication == -1)
- options->challenge_reponse_authentication = 1;
+ if (options->challenge_response_authentication == -1)
+ options->challenge_response_authentication = 1;
if (options->permit_empty_passwd == -1)
options->permit_empty_passwd = 0;
if (options->use_login == -1)
@@ -599,7 +599,7 @@ parse_flag:
goto parse_flag;
case sChallengeResponseAuthentication:
- intptr = &options->challenge_reponse_authentication;
+ intptr = &options->challenge_response_authentication;
goto parse_flag;
case sPrintMotd:
diff --git a/usr.bin/ssh/servconf.h b/usr.bin/ssh/servconf.h
index 4c02c0f5218..e159c70721a 100644
--- a/usr.bin/ssh/servconf.h
+++ b/usr.bin/ssh/servconf.h
@@ -11,7 +11,7 @@
* called by a name other than "ssh" or "Secure Shell".
*/
-/* RCSID("$OpenBSD: servconf.h,v 1.41 2001/04/13 22:46:53 beck Exp $"); */
+/* RCSID("$OpenBSD: servconf.h,v 1.42 2001/05/18 14:13:29 markus Exp $"); */
#ifndef SERVCONF_H
#define SERVCONF_H
@@ -92,7 +92,7 @@ typedef struct {
int password_authentication; /* If true, permit password
* authentication. */
int kbd_interactive_authentication; /* If true, permit */
- int challenge_reponse_authentication;
+ int challenge_response_authentication;
int permit_empty_passwd; /* If false, do not permit empty
* passwords. */
int use_login; /* If true, login(1) is used */
diff --git a/usr.bin/ssh/sshconnect1.c b/usr.bin/ssh/sshconnect1.c
index d42676676bf..c0fe86293be 100644
--- a/usr.bin/ssh/sshconnect1.c
+++ b/usr.bin/ssh/sshconnect1.c
@@ -13,7 +13,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: sshconnect1.c,v 1.31 2001/04/17 08:14:01 markus Exp $");
+RCSID("$OpenBSD: sshconnect1.c,v 1.32 2001/05/18 14:13:29 markus Exp $");
#include <openssl/bn.h>
#include <openssl/evp.h>
@@ -616,7 +616,7 @@ send_afs_tokens(void)
* Note that the client code is not tied to s/key or TIS.
*/
int
-try_challenge_reponse_authentication(void)
+try_challenge_response_authentication(void)
{
int type, i;
int payload_len;
@@ -1024,8 +1024,8 @@ ssh_userauth1(const char *local_user, const char *server_user, char *host,
}
/* Try challenge response authentication if the server supports it. */
if ((supported_authentications & (1 << SSH_AUTH_TIS)) &&
- options.challenge_reponse_authentication && !options.batch_mode) {
- if (try_challenge_reponse_authentication())
+ options.challenge_response_authentication && !options.batch_mode) {
+ if (try_challenge_response_authentication())
return;
}
/* Try password authentication if the server supports it. */
diff --git a/usr.bin/ssh/sshconnect2.c b/usr.bin/ssh/sshconnect2.c
index 14e3d401a78..75bd53d0877 100644
--- a/usr.bin/ssh/sshconnect2.c
+++ b/usr.bin/ssh/sshconnect2.c
@@ -23,7 +23,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: sshconnect2.c,v 1.72 2001/04/18 23:43:26 markus Exp $");
+RCSID("$OpenBSD: sshconnect2.c,v 1.73 2001/05/18 14:13:29 markus Exp $");
#include <openssl/bn.h>
#include <openssl/md5.h>
@@ -229,7 +229,7 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host,
int type;
int plen;
- if (options.challenge_reponse_authentication)
+ if (options.challenge_response_authentication)
options.kbd_interactive_authentication = 1;
debug("send SSH2_MSG_SERVICE_REQUEST");
@@ -787,6 +787,7 @@ input_userauth_info_req(int type, int plen, void *ctxt)
packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);
packet_put_int(num_prompts);
+ debug2("input_userauth_info_req: num_prompts %d", num_prompts);
for (i = 0; i < num_prompts; i++) {
prompt = packet_get_string(NULL);
echo = packet_get_char();
diff --git a/usr.bin/ssh/sshd.c b/usr.bin/ssh/sshd.c
index 2c7b201f040..296a2cea9af 100644
--- a/usr.bin/ssh/sshd.c
+++ b/usr.bin/ssh/sshd.c
@@ -40,7 +40,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.195 2001/04/15 16:58:03 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.196 2001/05/18 14:13:29 markus Exp $");
#include <openssl/dh.h>
#include <openssl/bn.h>
@@ -1239,7 +1239,7 @@ do_ssh1_kex(void)
if (options.afs_token_passing)
auth_mask |= 1 << SSH_PASS_AFS_TOKEN;
#endif
- if (options.challenge_reponse_authentication == 1)
+ if (options.challenge_response_authentication == 1)
auth_mask |= 1 << SSH_AUTH_TIS;
if (options.password_authentication)
auth_mask |= 1 << SSH_AUTH_PASSWORD;
diff --git a/usr.bin/ssh/sshd/Makefile b/usr.bin/ssh/sshd/Makefile
index 5ccce8d9fc9..859d8e11879 100644
--- a/usr.bin/ssh/sshd/Makefile
+++ b/usr.bin/ssh/sshd/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.38 2001/03/29 21:17:40 markus Exp $
+# $OpenBSD: Makefile,v 1.39 2001/05/18 14:13:29 markus Exp $
.PATH: ${.CURDIR}/..
@@ -12,7 +12,8 @@ CFLAGS+=-DHAVE_LOGIN_CAP
SRCS= sshd.c auth-rhosts.c auth-passwd.c auth-rsa.c auth-rh-rsa.c \
sshpty.c sshlogin.c servconf.c serverloop.c \
auth.c auth1.c auth2.c auth-options.c session.c \
- auth-chall.c auth2-chall.c groupaccess.c
+ auth-chall.c auth2-chall.c groupaccess.c \
+ auth-skey.c auth-bsdauth.c
.include <bsd.own.mk> # for KERBEROS and AFS