diff options
author | Markus Friedl <markus@cvs.openbsd.org> | 2001-05-18 14:13:30 +0000 |
---|---|---|
committer | Markus Friedl <markus@cvs.openbsd.org> | 2001-05-18 14:13:30 +0000 |
commit | 887cfdd77aaa2210e1da65fcd2a5a4452b0cbc29 (patch) | |
tree | 93af6307b283f25bcbce9a9c6c8baa89c9a36649 /usr.bin/ssh | |
parent | 87a316979eadfa099f50a4ed7b87a1ccce28a79c (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.c | 116 | ||||
-rw-r--r-- | usr.bin/ssh/auth-chall.c | 110 | ||||
-rw-r--r-- | usr.bin/ssh/auth-skey.c | 97 | ||||
-rw-r--r-- | usr.bin/ssh/auth.h | 27 | ||||
-rw-r--r-- | usr.bin/ssh/auth1.c | 9 | ||||
-rw-r--r-- | usr.bin/ssh/auth2-chall.c | 279 | ||||
-rw-r--r-- | usr.bin/ssh/auth2.c | 16 | ||||
-rw-r--r-- | usr.bin/ssh/readconf.c | 10 | ||||
-rw-r--r-- | usr.bin/ssh/readconf.h | 4 | ||||
-rw-r--r-- | usr.bin/ssh/servconf.c | 10 | ||||
-rw-r--r-- | usr.bin/ssh/servconf.h | 4 | ||||
-rw-r--r-- | usr.bin/ssh/sshconnect1.c | 8 | ||||
-rw-r--r-- | usr.bin/ssh/sshconnect2.c | 5 | ||||
-rw-r--r-- | usr.bin/ssh/sshd.c | 4 | ||||
-rw-r--r-- | usr.bin/ssh/sshd/Makefile | 5 |
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 |