[BACK]Return to auth-skey.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Annotation of src/usr.bin/ssh/auth-skey.c, Revision 1.7

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