X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/8efc0c151a0f57612e1aa0abb5b7d536db4cf76a..HEAD:/auth-skey.c diff --git a/auth-skey.c b/auth-skey.c index 06f81b89..cb43dba4 100644 --- a/auth-skey.c +++ b/auth-skey.c @@ -1,149 +1,107 @@ +/* $OpenBSD: auth-skey.c,v 1.27 2007/01/21 01:41:54 stevesk Exp $ */ +/* + * 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("$Id$"); -#include "ssh.h" -#include +#ifdef SKEY -/* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */ +#include +#include +#include -#define ROUND(x) (((x)[0] << 24) + (((x)[1]) << 16) + (((x)[2]) << 8) + \ - ((x)[3])) +#include -/* - * hash_collapse() - */ -static u_int32_t -hash_collapse(s) - u_char *s; +#include "xmalloc.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "ssh-gss.h" +#include "monitor_wrap.h" + +static void * +skey_init_ctx(Authctxt *authctxt) +{ + return authctxt; +} + +int +skey_query(void *ctx, char **name, char **infotxt, + u_int* numprompts, char ***prompts, u_int **echo_on) { - int len, target; - u_int32_t i; - - if ((strlen(s) % sizeof(u_int32_t)) == 0) - target = strlen(s); /* Multiple of 4 */ - else - target = strlen(s) - (strlen(s) % sizeof(u_int32_t)); - - for (i = 0, len = 0; len < target; len += 4) - i ^= ROUND(s + len); - - return i; + Authctxt *authctxt = ctx; + char challenge[1024]; + struct skey skey; + + if (_compat_skeychallenge(&skey, authctxt->user, challenge, + sizeof(challenge)) == -1) + return -1; + + *name = xstrdup(""); + *infotxt = xstrdup(""); + *numprompts = 1; + *prompts = xcalloc(*numprompts, sizeof(char *)); + *echo_on = xcalloc(*numprompts, sizeof(u_int)); + + xasprintf(*prompts, "%s%s", challenge, SKEY_PROMPT); + + return 0; } -char * -skey_fake_keyinfo(char *username) + +int +skey_respond(void *ctx, u_int numresponses, char **responses) { - int i; - u_int ptr; - u_char hseed[SKEY_MAX_SEED_LEN], flg = 1, *up; - char pbuf[SKEY_MAX_PW_LEN+1]; - static char skeyprompt[SKEY_MAX_CHALLENGE+1]; - char *secret = NULL; - size_t secretlen = 0; - SHA1_CTX ctx; - char *p, *u; - - /* - * Base first 4 chars of seed on hostname. - * Add some filler for short hostnames if necessary. - */ - if (gethostname(pbuf, sizeof(pbuf)) == -1) - *(p = pbuf) = '.'; - else - for (p = pbuf; *p && isalnum(*p); p++) - if (isalpha(*p) && isupper(*p)) - *p = tolower(*p); - if (*p && pbuf - p < 4) - (void)strncpy(p, "asjd", 4 - (pbuf - p)); - pbuf[4] = '\0'; - - /* Hash the username if possible */ - if ((up = SHA1Data(username, strlen(username), NULL)) != NULL) { - struct stat sb; - time_t t; - int fd; - - /* Collapse the hash */ - ptr = hash_collapse(up); - memset(up, 0, strlen(up)); - - /* See if the random file's there, else use ctime */ - if ((fd = open(_SKEY_RAND_FILE_PATH_, O_RDONLY)) != -1 - && fstat(fd, &sb) == 0 && - sb.st_size > (off_t)SKEY_MAX_SEED_LEN && - lseek(fd, ptr % (sb.st_size - SKEY_MAX_SEED_LEN), - SEEK_SET) != -1 && read(fd, hseed, - SKEY_MAX_SEED_LEN) == SKEY_MAX_SEED_LEN) { - close(fd); - secret = hseed; - secretlen = SKEY_MAX_SEED_LEN; - flg = 0; - } else if (!stat(_PATH_MEM, &sb) || !stat("/", &sb)) { - t = sb.st_ctime; - secret = ctime(&t); - secretlen = strlen(secret); - flg = 0; - } - } - - /* Put that in your pipe and smoke it */ - if (flg == 0) { - /* Hash secret value with username */ - SHA1Init(&ctx); - SHA1Update(&ctx, secret, secretlen); - SHA1Update(&ctx, username, strlen(username)); - SHA1End(&ctx, up); - - /* Zero out */ - memset(secret, 0, secretlen); - - /* Now hash the hash */ - SHA1Init(&ctx); - SHA1Update(&ctx, up, strlen(up)); - SHA1End(&ctx, up); - - ptr = hash_collapse(up + 4); - - for (i = 4; i < 9; i++) { - pbuf[i] = (ptr % 10) + '0'; - ptr /= 10; - } - pbuf[i] = '\0'; - - /* Sequence number */ - ptr = ((up[2] + up[3]) % 99) + 1; - - memset(up, 0, 20); /* SHA1 specific */ - free(up); - - (void)snprintf(skeyprompt, sizeof skeyprompt, - "otp-%.*s %d %.*s", - SKEY_MAX_HASHNAME_LEN, - skey_get_algorithm(), - ptr, SKEY_MAX_SEED_LEN, - pbuf); - } else { - /* Base last 8 chars of seed on username */ - u = username; - i = 8; - p = &pbuf[4]; - do { - if (*u == 0) { - /* Pad remainder with zeros */ - while (--i >= 0) - *p++ = '0'; - break; - } - - *p++ = (*u++ % 10) + '0'; - } while (--i != 0); - pbuf[12] = '\0'; - - (void)snprintf(skeyprompt, sizeof skeyprompt, - "otp-%.*s %d %.*s", - SKEY_MAX_HASHNAME_LEN, - skey_get_algorithm(), - 99, SKEY_MAX_SEED_LEN, pbuf); - } - return skeyprompt; + 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 +}; + +KbdintDevice mm_skey_device = { + "skey", + skey_init_ctx, + mm_skey_query, + mm_skey_respond, + skey_free_ctx +}; +#endif /* SKEY */