#include "includes.h"
#ifdef SKEY
RCSID("$Id: auth-skey.c,v 1.6 2000/04/14 10:30:29 markus Exp $");

#include "ssh.h"
#include "packet.h"
#include <sha1.h>

/* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */

/*
 * try skey authentication,
 * return 1 on success, 0 on failure, -1 if skey is not available
 */

int
auth_skey_password(struct passwd * pw, const char *password)
{
	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;
}

/* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */

#define ROUND(x)   (((x)[0] << 24) + (((x)[1]) << 16) + (((x)[2]) << 8) + \
		    ((x)[3]))

/*
 * hash_collapse()
 */
static u_int32_t
hash_collapse(s)
	u_char *s;
{
	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;
}

char *
skey_fake_keyinfo(char *username)
{
	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;
	char md[SHA_DIGEST_LENGTH];

	/*
	 * 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_End(&ctx, up);

		/* 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_End(&ctx, up);
		
		/* Zero out */
		memset(secret, 0, secretlen);

		/* Now hash the hash */
		SHA1_Init(&ctx);
		SHA1_Update(&ctx, up, strlen(up));
		SHA1_End(&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, 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;
}

#endif /* SKEY */
