X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/bcbf86ecce0d10003d08a40b67f2db96702c132a..HEAD:/auth-skey.c diff --git a/auth-skey.c b/auth-skey.c index 1e3cec86..cb43dba4 100644 --- a/auth-skey.c +++ b/auth-skey.c @@ -1,5 +1,6 @@ +/* $OpenBSD: auth-skey.c,v 1.27 2007/01/21 01:41:54 stevesk Exp $ */ /* - * Copyright (c) 1999,2000 Markus Friedl. All rights reserved. + * 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 @@ -23,193 +24,84 @@ */ #include "includes.h" -RCSID("$OpenBSD: auth-skey.c,v 1.8 2000/09/07 20:27:49 deraadt Exp $"); #ifdef SKEY -#include "ssh.h" -#include "packet.h" -#include -/* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */ +#include -/* - * try skey authentication, - * return 1 on success, 0 on failure, -1 if skey is not available - */ +#include +#include -int -auth_skey_password(struct passwd * pw, const char *password) +#include + +#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) { - if (strncasecmp(password, "s/key", 5) == 0) { - char *skeyinfo = skey_keyinfo(pw->pw_name); - if (skeyinfo == NULL) { - debug("generating fake skeyinfo for %.100s.", - pw->pw_name); - skeyinfo = skey_fake_keyinfo(pw->pw_name); - } - if (skeyinfo != NULL) - packet_send_debug(skeyinfo); - /* Try again. */ - return 0; - } else if (skey_haskey(pw->pw_name) == 0 && - skey_passcheck(pw->pw_name, (char *) password) != -1) { - /* Authentication succeeded. */ - return 1; - } - /* Fall back to ordinary passwd authentication. */ - return -1; + return authctxt; } -/* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */ +int +skey_query(void *ctx, char **name, char **infotxt, + u_int* numprompts, char ***prompts, u_int **echo_on) +{ + Authctxt *authctxt = ctx; + char challenge[1024]; + struct skey skey; -#define ROUND(x) (((x)[0] << 24) + (((x)[1]) << 16) + (((x)[2]) << 8) + \ - ((x)[3])) + if (_compat_skeychallenge(&skey, authctxt->user, challenge, + sizeof(challenge)) == -1) + return -1; -/* - * hash_collapse() - */ -static u_int32_t -hash_collapse(s) - u_char *s; + *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; +} + +int +skey_respond(void *ctx, u_int numresponses, char **responses) { - 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; + + 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; } -char * -skey_fake_keyinfo(char *username) +static void +skey_free_ctx(void *ctx) { - 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; - SHA_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 */ - up = malloc(SHA_DIGEST_LENGTH); - if (up != NULL) { - struct stat sb; - time_t t; - int fd; - - SHA1_Init(&ctx); - SHA1_Update(&ctx, username, strlen(username)); - SHA1_Final(up, &ctx); - - /* 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); - fd = -1; - 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; - } - if (fd != -1) - close(fd); - } - - /* Put that in your pipe and smoke it */ - if (flg == 0) { - /* Hash secret value with username */ - SHA1_Init(&ctx); - SHA1_Update(&ctx, secret, secretlen); - SHA1_Update(&ctx, username, strlen(username)); - SHA1_Final(up, &ctx); - - /* Zero out */ - memset(secret, 0, secretlen); - - /* Now hash the hash */ - SHA1_Init(&ctx); - SHA1_Update(&ctx, up, strlen(up)); - SHA1_Final(up, &ctx); - - 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, SHA_DIGEST_LENGTH); /* 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; + /* 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 */