summaryrefslogtreecommitdiff
path: root/lib/libskey/skeylogin.c
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>1998-07-05 19:41:36 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>1998-07-05 19:41:36 +0000
commitdcc761a0be9d230cfe94b82aa4aa3e1fb99b89cb (patch)
tree326e99e7aea7514f885ffe4106252392956fbf75 /lib/libskey/skeylogin.c
parentbe860ede3db0a0588b73d8cde106b68305941a5e (diff)
if there is no /etc/host.random, hash on the ctime of /dev/mem or /. This is much better than the old fake challenge.
Diffstat (limited to 'lib/libskey/skeylogin.c')
-rw-r--r--lib/libskey/skeylogin.c178
1 files changed, 94 insertions, 84 deletions
diff --git a/lib/libskey/skeylogin.c b/lib/libskey/skeylogin.c
index 909e181098e..cb20e6e8173 100644
--- a/lib/libskey/skeylogin.c
+++ b/lib/libskey/skeylogin.c
@@ -12,7 +12,7 @@
*
* S/KEY verification check, lookups, and authentication.
*
- * $OpenBSD: skeylogin.c,v 1.28 1998/07/03 02:06:22 angelos Exp $
+ * $OpenBSD: skeylogin.c,v 1.29 1998/07/05 19:41:35 millert Exp $
*/
#include <sys/param.h>
@@ -24,7 +24,6 @@
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/types.h>
-#include <sys/stat.h>
#include <ctype.h>
#include <err.h>
@@ -434,12 +433,13 @@ int
skey_authenticate(username)
char *username;
{
- int i, fd;
+ int i;
u_int ptr;
u_char hseed[SKEY_MAX_SEED_LEN], flg = 1, *up;
char pbuf[SKEY_MAX_PW_LEN+1], skeyprompt[SKEY_MAX_CHALLENGE+1];
+ char *secret;
+ size_t secretlen;
struct skey skey;
- struct stat sb;
SHA1_CTX ctx;
/* Attempt an S/Key challenge */
@@ -461,88 +461,98 @@ skey_authenticate(username)
*p = tolower(*p);
if (*p && pbuf - p < 4)
(void)strncpy(p, "asjd", 4 - (pbuf - p));
- p = &pbuf[4];
- *p = '\0';
-
- /* See if the random file's there */
- if ((fd = open(_SKEY_RAND_FILE_PATH_, O_RDONLY)) != -1) {
- if ((fstat(fd, &sb) != -1) &&
- (sb.st_size > SKEY_MAX_SEED_LEN) &&
- ((up = SHA1Data(username, strlen(username), NULL))
- != NULL)) {
- /* Collapse the hash */
- ptr = hash_collapse(up);
-
- if ((lseek(fd, ptr % (sb.st_size - SKEY_MAX_SEED_LEN), SEEK_SET) != -1) && (read(fd, hseed, SKEY_MAX_SEED_LEN) == SKEY_MAX_SEED_LEN)) {
- memset(up, 0, strlen(up));
-
- /* Hash secret value with username */
- SHA1Init(&ctx);
- SHA1Update(&ctx, hseed,
- SKEY_MAX_SEED_LEN);
- SHA1Update(&ctx, username,
- strlen(username));
- SHA1End(&ctx, up);
-
- /* Zero out */
- memset(hseed, 0, SKEY_MAX_SEED_LEN);
-
- /* 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);
- flg = 0;
-
- (void)sprintf(skeyprompt,
- "otp-%.*s %d %.*s",
- SKEY_MAX_HASHNAME_LEN,
- skey_get_algorithm(),
- ptr, SKEY_MAX_SEED_LEN,
- pbuf);
- /* Done */
- } else
- free(up);
- }
-
- close(fd);
+ 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 (((fd = open(_PATH_MEM, O_RDONLY)) != -1 ||
+ (fd = open("/", O_RDONLY)) != -1) &&
+ fstat(fd, &sb) == 0 ) {
+ close(fd);
+ t = sb.st_ctime;
+ secret = ctime(&t);
+ secretlen = strlen(secret);
+ flg = 0;
+ }
}
- if (flg)
- {
- /* Base last 8 chars of seed on username */
- u = username;
- i = 8;
- 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)sprintf(skeyprompt, "otp-%.*s %d %.*s",
- SKEY_MAX_HASHNAME_LEN, skey_get_algorithm(),
- 99, SKEY_MAX_SEED_LEN, pbuf);
- }
+ /* 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)sprintf(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)sprintf(skeyprompt, "otp-%.*s %d %.*s",
+ SKEY_MAX_HASHNAME_LEN,
+ skey_get_algorithm(),
+ 99, SKEY_MAX_SEED_LEN, pbuf);
+ }
}
(void)fprintf(stderr, "%s\n", skeyprompt);