Annotation of src/usr.bin/ssh/auth-skey.c, Revision 1.1
1.1 ! markus 1: #include "includes.h"
! 2: RCSID("$Id: auth-passwd.c,v 1.5 1999/09/30 04:30:03 deraadt Exp $");
! 3:
! 4: #include "ssh.h"
! 5: #include <sha1.h>
! 6:
! 7: /* from %OpenBSD: skeylogin.c,v 1.32 1999/08/16 14:46:56 millert Exp % */
! 8:
! 9:
! 10: #define ROUND(x) (((x)[0] << 24) + (((x)[1]) << 16) + (((x)[2]) << 8) + \
! 11: ((x)[3]))
! 12:
! 13: /*
! 14: * hash_collapse()
! 15: */
! 16: static u_int32_t
! 17: hash_collapse(s)
! 18: u_char *s;
! 19: {
! 20: int len, target;
! 21: u_int32_t i;
! 22:
! 23: if ((strlen(s) % sizeof(u_int32_t)) == 0)
! 24: target = strlen(s); /* Multiple of 4 */
! 25: else
! 26: target = strlen(s) - (strlen(s) % sizeof(u_int32_t));
! 27:
! 28: for (i = 0, len = 0; len < target; len += 4)
! 29: i ^= ROUND(s + len);
! 30:
! 31: return i;
! 32: }
! 33: char *
! 34: skey_fake_keyinfo(char *username)
! 35: {
! 36: int i;
! 37: u_int ptr;
! 38: u_char hseed[SKEY_MAX_SEED_LEN], flg = 1, *up;
! 39: char pbuf[SKEY_MAX_PW_LEN+1];
! 40: static char skeyprompt[SKEY_MAX_CHALLENGE+1];
! 41: char *secret = NULL;
! 42: size_t secretlen = 0;
! 43: SHA1_CTX ctx;
! 44: char *p, *u;
! 45:
! 46: /*
! 47: * Base first 4 chars of seed on hostname.
! 48: * Add some filler for short hostnames if necessary.
! 49: */
! 50: if (gethostname(pbuf, sizeof(pbuf)) == -1)
! 51: *(p = pbuf) = '.';
! 52: else
! 53: for (p = pbuf; *p && isalnum(*p); p++)
! 54: if (isalpha(*p) && isupper(*p))
! 55: *p = tolower(*p);
! 56: if (*p && pbuf - p < 4)
! 57: (void)strncpy(p, "asjd", 4 - (pbuf - p));
! 58: pbuf[4] = '\0';
! 59:
! 60: /* Hash the username if possible */
! 61: if ((up = SHA1Data(username, strlen(username), NULL)) != NULL) {
! 62: struct stat sb;
! 63: time_t t;
! 64: int fd;
! 65:
! 66: /* Collapse the hash */
! 67: ptr = hash_collapse(up);
! 68: memset(up, 0, strlen(up));
! 69:
! 70: /* See if the random file's there, else use ctime */
! 71: if ((fd = open(_SKEY_RAND_FILE_PATH_, O_RDONLY)) != -1
! 72: && fstat(fd, &sb) == 0 &&
! 73: sb.st_size > (off_t)SKEY_MAX_SEED_LEN &&
! 74: lseek(fd, ptr % (sb.st_size - SKEY_MAX_SEED_LEN),
! 75: SEEK_SET) != -1 && read(fd, hseed,
! 76: SKEY_MAX_SEED_LEN) == SKEY_MAX_SEED_LEN) {
! 77: close(fd);
! 78: secret = hseed;
! 79: secretlen = SKEY_MAX_SEED_LEN;
! 80: flg = 0;
! 81: } else if (!stat(_PATH_MEM, &sb) || !stat("/", &sb)) {
! 82: t = sb.st_ctime;
! 83: secret = ctime(&t);
! 84: secretlen = strlen(secret);
! 85: flg = 0;
! 86: }
! 87: }
! 88:
! 89: /* Put that in your pipe and smoke it */
! 90: if (flg == 0) {
! 91: /* Hash secret value with username */
! 92: SHA1Init(&ctx);
! 93: SHA1Update(&ctx, secret, secretlen);
! 94: SHA1Update(&ctx, username, strlen(username));
! 95: SHA1End(&ctx, up);
! 96:
! 97: /* Zero out */
! 98: memset(secret, 0, secretlen);
! 99:
! 100: /* Now hash the hash */
! 101: SHA1Init(&ctx);
! 102: SHA1Update(&ctx, up, strlen(up));
! 103: SHA1End(&ctx, up);
! 104:
! 105: ptr = hash_collapse(up + 4);
! 106:
! 107: for (i = 4; i < 9; i++) {
! 108: pbuf[i] = (ptr % 10) + '0';
! 109: ptr /= 10;
! 110: }
! 111: pbuf[i] = '\0';
! 112:
! 113: /* Sequence number */
! 114: ptr = ((up[2] + up[3]) % 99) + 1;
! 115:
! 116: memset(up, 0, 20); /* SHA1 specific */
! 117: free(up);
! 118:
! 119: (void)sprintf(skeyprompt,
! 120: "otp-%.*s %d %.*s",
! 121: SKEY_MAX_HASHNAME_LEN,
! 122: skey_get_algorithm(),
! 123: ptr, SKEY_MAX_SEED_LEN,
! 124: pbuf);
! 125: } else {
! 126: /* Base last 8 chars of seed on username */
! 127: u = username;
! 128: i = 8;
! 129: p = &pbuf[4];
! 130: do {
! 131: if (*u == 0) {
! 132: /* Pad remainder with zeros */
! 133: while (--i >= 0)
! 134: *p++ = '0';
! 135: break;
! 136: }
! 137:
! 138: *p++ = (*u++ % 10) + '0';
! 139: } while (--i != 0);
! 140: pbuf[12] = '\0';
! 141:
! 142: (void)sprintf(skeyprompt, "otp-%.*s %d %.*s",
! 143: SKEY_MAX_HASHNAME_LEN,
! 144: skey_get_algorithm(),
! 145: 99, SKEY_MAX_SEED_LEN, pbuf);
! 146: }
! 147: return skeyprompt;
! 148: }