summaryrefslogtreecommitdiff
path: root/lib/libskey
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>1996-09-27 15:39:01 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>1996-09-27 15:39:01 +0000
commitd5dd91cdf59d18f9cfff6072a73247438e00ea4e (patch)
tree6b4b783a2372708f840c8f51cf8935d0262edf80 /lib/libskey
parent5fe26c50cba816ee0bd96be58ac1a22d8244265d (diff)
Deal with both MD4 and MD5 s/key's
Diffstat (limited to 'lib/libskey')
-rw-r--r--lib/libskey/Makefile16
-rw-r--r--lib/libskey/put.c349
-rw-r--r--lib/libskey/shlib_version2
-rw-r--r--lib/libskey/skey.h27
-rw-r--r--lib/libskey/skeylogin.c159
-rw-r--r--lib/libskey/skeysubr.c327
6 files changed, 483 insertions, 397 deletions
diff --git a/lib/libskey/Makefile b/lib/libskey/Makefile
index 7e616b17dc6..31cbc14f78b 100644
--- a/lib/libskey/Makefile
+++ b/lib/libskey/Makefile
@@ -1,7 +1,17 @@
-# $Id: Makefile,v 1.1 1995/10/18 08:43:11 deraadt Exp $
+# $Id: Makefile,v 1.2 1996/09/27 15:38:57 millert Exp $
LIB= skey
-SRCS= skeylogin.c skeysubr.c md4.c put.c
-CFLAGS+= -DUSE_ECHO
+SRCS= skeylogin.c skeysubr.c put.c
+HDRS= skey.h
+#CFLAGS+= -DSKEY_MDX_DEFAULT=4
+
+includes:
+ @cd ${.CURDIR}; for i in $(HDRS); do \
+ j="cmp -s $$i ${DESTDIR}/usr/include/`basename $$i` || \
+ install -c -o ${BINOWN} -g ${BINGRP} -m 444 $$i \
+ ${DESTDIR}/usr/include"; \
+ echo $$j; \
+ eval "$$j"; \
+ done
.include <bsd.lib.mk>
diff --git a/lib/libskey/put.c b/lib/libskey/put.c
index 1a493f1e35c..83d65d795cd 100644
--- a/lib/libskey/put.c
+++ b/lib/libskey/put.c
@@ -8,7 +8,7 @@
*
* Dictionary lookup and extraction.
*
- * $Id: put.c,v 1.1 1995/10/18 08:43:11 deraadt Exp $
+ * $Id: put.c,v 1.2 1996/09/27 15:38:58 millert Exp $
*/
#include <stdio.h>
@@ -2078,36 +2078,40 @@ char Wp[2048][4] = {
* Returns a pointer to a static buffer
*/
char *
- btoe (engout, c)
- char *c, *engout;
+btoe (engout, c)
+ char *c, *engout;
{
- char cp[9]; /* add in room for the parity 2 bits */
- int p, i;
+ char cp[10]; /* add in room for the parity 2 bits + extract() slop */
+ int p, i;
- engout[0] = '\0';
- memcpy (cp, c, 8);
- /* compute parity */
- for (p = 0, i = 0; i < 64; i += 2)
- p += extract (cp, i, 2);
+ engout[0] = '\0';
- cp[8] = (char) p << 6;
+ /* workaround for extract() reads beyond end of data */
+ (void) memset(cp, 0, sizeof(cp));
+ (void) memcpy(cp, c, 8);
- strncat (engout, &Wp[extract (cp, 0, 11)][0], 4);
- strcat (engout, " ");
- strncat (engout, &Wp[extract (cp, 11, 11)][0], 4);
- strcat (engout, " ");
- strncat (engout, &Wp[extract (cp, 22, 11)][0], 4);
- strcat (engout, " ");
- strncat (engout, &Wp[extract (cp, 33, 11)][0], 4);
- strcat (engout, " ");
- strncat (engout, &Wp[extract (cp, 44, 11)][0], 4);
- strcat (engout, " ");
- strncat (engout, &Wp[extract (cp, 55, 11)][0], 4);
+ /* compute parity */
+ for (p = 0, i = 0; i < 64; i += 2)
+ p += extract (cp, i, 2);
+
+ cp[8] = (char) p << 6;
+
+ (void) strncat (engout, &Wp[extract (cp, 0, 11)][0], 4);
+ (void) strcat (engout, " ");
+ (void) strncat (engout, &Wp[extract (cp, 11, 11)][0], 4);
+ (void) strcat (engout, " ");
+ (void) strncat (engout, &Wp[extract (cp, 22, 11)][0], 4);
+ (void) strcat (engout, " ");
+ (void) strncat (engout, &Wp[extract (cp, 33, 11)][0], 4);
+ (void) strcat (engout, " ");
+ (void) strncat (engout, &Wp[extract (cp, 44, 11)][0], 4);
+ (void) strcat (engout, " ");
+ (void) strncat (engout, &Wp[extract (cp, 55, 11)][0], 4);
#ifdef notdef
- printf ("engout is %s\n\r", engout);
+ (void) fprintf (stderr, "engout is %s\n\r", engout);
#endif
- return (engout);
+ return (engout);
}
/* convert English to binary
@@ -2117,70 +2121,66 @@ char *
* -2 words OK but parity is wrong
*/
int
- etob (out, e)
- char *out;
- char *e;
+etob (out, e)
+ char *out;
+ char *e;
{
- char *word;
- int i, p, v, l, low, high;
- char b[9];
- char input[36];
+ char *word;
+ int i, p, v, l, low, high;
+ char b[9];
+ char input[36];
- if (e == NULL)
- return -1;
+ if (e == NULL)
+ return -1;
- strncpy (input, e, sizeof (input));
- memset (b, 0, sizeof (b));
- memset (out, 0, 8);
- for (i = 0, p = 0; i < 6; i++, p += 11)
- {
- if ((word = strtok (i == 0 ? input : NULL, " ")) == NULL)
- return -1;
+ (void) strncpy (input, e, sizeof (input));
+ (void) memset (b, 0, sizeof (b));
+ (void) memset (out, 0, 8);
+ for (i = 0, p = 0; i < 6; i++, p += 11) {
+ if ((word = strtok (i == 0 ? input : NULL, " ")) == NULL)
+ return -1;
- l = strlen (word);
- if (l > 4 || l < 1)
- return -1;
- else if (l < 4)
- {
- low = 0;
- high = 570;
- }
- else
- {
- low = 571;
- high = 2047;
- }
- standard (word);
+ l = strlen (word);
+ if (l > 4 || l < 1) {
+ return -1;
+ } else if (l < 4) {
+ low = 0;
+ high = 570;
+ } else {
+ low = 571;
+ high = 2047;
+ }
+ standard (word);
- if ((v = wsrch (word, low, high)) < 0)
- return 0;
+ if ((v = wsrch (word, low, high)) < 0)
+ return 0;
- insert (b, v, p, 11);
- }
+ insert (b, v, p, 11);
+ }
- /* now check the parity of what we got */
- for (p = 0, i = 0; i < 64; i += 2)
- p += extract (b, i, 2);
+ /* now check the parity of what we got */
+ for (p = 0, i = 0; i < 64; i += 2)
+ p += extract (b, i, 2);
- if ((p & 3) != extract (b, 64, 2))
- return -2;
+ if ((p & 3) != extract (b, 64, 2))
+ return -2;
- memcpy (out, b, 8);
+ (void) memcpy (out, b, 8);
- return 1;
+ return 1;
}
/* Display 8 bytes as a series of 16-bit hex digits */
char *
- put8 (out, s)
- char *out;
- char *s;
+put8 (out, s)
+ char *out;
+ char *s;
{
- sprintf (out, "%02X%02X %02X%02X %02X%02X %02X%02X",
- s[0] & 0xff, s[1] & 0xff, s[2] & 0xff,
- s[3] & 0xff, s[4] & 0xff, s[5] & 0xff,
- s[6] & 0xff, s[7] & 0xff);
- return out;
+ (void) sprintf (out, "%02X%02X %02X%02X %02X%02X %02X%02X",
+ s[0] & 0xff, s[1] & 0xff, s[2] & 0xff,
+ s[3] & 0xff, s[4] & 0xff, s[5] & 0xff,
+ s[6] & 0xff, s[7] & 0xff);
+ return out;
}
#ifdef notdef
@@ -2188,135 +2188,130 @@ char *
* Provided as a possible alternative to btoe()
*/
char *
- btoc (cp)
- char *cp;
+btoc (cp)
+ char *cp;
{
- int i;
- static char out[31];
+ int i;
+ static char out[31];
- /* code out put by characters 6 bits each added to 0x21 (!) */
- for (i = 0; i <= 10; i++)
- {
- /* last one is only 4 bits not 6 */
- out[i] = '!' + extract (cp, 6 * i, i >= 10 ? 4 : 6);
- }
- out[i] = '\0';
- return (out);
+ /* code out put by characters 6 bits each added to 0x21 (!) */
+ for (i = 0; i <= 10; i++) {
+ /* last one is only 4 bits not 6 */
+ out[i] = '!' + extract (cp, 6 * i, i >= 10 ? 4 : 6);
+ }
+ out[i] = '\0';
+ return (out);
}
-
#endif
/* Internal subroutines for word encoding/decoding */
/* Dictionary binary search */
static int
- wsrch (w, low, high)
- char *w;
- int low, high;
+wsrch (w, low, high)
+ char *w;
+ int low, high;
{
- int i, j;
+ int i, j;
+
+ for (;;) {
+ i = (low + high) / 2;
- for (;;)
- {
- i = (low + high) / 2;
- if ((j = strncmp (w, Wp[i], 4)) == 0)
- return i; /* Found it */
- if (high == low + 1)
- {
- /* Avoid effects of integer truncation in /2 */
- if (strncmp (w, Wp[high], 4) == 0)
- return high;
- else
- return -1;
- }
- if (low >= high)
- return -1; /* I don't *think* this can happen... */
- if (j < 0)
- high = i; /* Search lower half */
- else
- low = i; /* Search upper half */
- }
+ if ((j = strncmp (w, Wp[i], 4)) == 0)
+ return i; /* Found it */
+
+ if (high == low + 1) {
+ /* Avoid effects of integer truncation in /2 */
+ if (strncmp (w, Wp[high], 4) == 0)
+ return high;
+ else
+ return -1;
+ }
+
+ if (low >= high)
+ return -1; /* I don't *think* this can happen... */
+ if (j < 0)
+ high = i; /* Search lower half */
+ else
+ low = i; /* Search upper half */
+ }
}
+
static void
- insert (s, x, start, length)
- char *s;
- int x;
- int start, length;
+insert (s, x, start, length)
+ char *s;
+ int x;
+ int start, length;
{
- unsigned char cl;
- unsigned char cc;
- unsigned char cr;
- unsigned long y;
- int shift;
+ unsigned char cl;
+ unsigned char cc;
+ unsigned char cr;
+ unsigned long y;
+ int shift;
- assert (length <= 11);
- assert (start >= 0);
- assert (length >= 0);
- assert (start + length <= 66);
+ assert (length <= 11);
+ assert (start >= 0);
+ assert (length >= 0);
+ assert (start + length <= 66);
- shift = ((8 - ((start + length) % 8)) % 8);
- y = (long) x << shift;
- cl = (y >> 16) & 0xff;
- cc = (y >> 8) & 0xff;
- cr = y & 0xff;
- if (shift + length > 16)
- {
- s[start / 8] |= cl;
- s[start / 8 + 1] |= cc;
- s[start / 8 + 2] |= cr;
- }
- else if (shift + length > 8)
- {
- s[start / 8] |= cc;
- s[start / 8 + 1] |= cr;
- }
- else
- {
- s[start / 8] |= cr;
- }
+ shift = ((8 - ((start + length) % 8)) % 8);
+ y = (long) x << shift;
+ cl = (y >> 16) & 0xff;
+ cc = (y >> 8) & 0xff;
+ cr = y & 0xff;
+ if (shift + length > 16) {
+ s[start / 8] |= cl;
+ s[start / 8 + 1] |= cc;
+ s[start / 8 + 2] |= cr;
+ } else if (shift + length > 8) {
+ s[start / 8] |= cc;
+ s[start / 8 + 1] |= cr;
+ } else {
+ s[start / 8] |= cr;
+ }
}
static void
- standard (word)
- register char *word;
+standard (word)
+ register char *word;
{
- while (*word)
- {
- if (!isascii (*word))
- break;
- if (islower (*word))
- *word = toupper (*word);
- if (*word == '1')
- *word = 'L';
- if (*word == '0')
- *word = 'O';
- if (*word == '5')
- *word = 'S';
- word++;
- }
+ while (*word) {
+ if (!isascii(*word))
+ break;
+ if (islower(*word))
+ *word = toupper(*word);
+ if (*word == '1')
+ *word = 'L';
+ if (*word == '0')
+ *word = 'O';
+ if (*word == '5')
+ *word = 'S';
+ word++;
+ }
}
/* Extract 'length' bits from the char array 's' starting with bit 'start' */
static unsigned long
- extract (s, start, length)
- char *s;
- int start, length;
+extract (s, start, length)
+ char *s;
+ int start, length;
{
- unsigned char cl;
- unsigned char cc;
- unsigned char cr;
- unsigned long x;
+ unsigned char cl;
+ unsigned char cc;
+ unsigned char cr;
+ unsigned long x;
+
+ assert (length <= 11);
+ assert (start >= 0);
+ assert (length >= 0);
+ assert (start + length <= 66);
- assert (length <= 11);
- assert (start >= 0);
- assert (length >= 0);
- assert (start + length <= 66);
+ cl = s[start / 8];
+ cc = s[start / 8 + 1];
+ cr = s[start / 8 + 2];
+ x = ((long) (cl << 8 | cc) << 8 | cr);
+ x = x >> (24 - (length + (start % 8)));
+ x = (x & (0xffff >> (16 - length)));
- cl = s[start / 8];
- cc = s[start / 8 + 1];
- cr = s[start / 8 + 2];
- x = ((long) (cl << 8 | cc) << 8 | cr);
- x = x >> (24 - (length + (start % 8)));
- x = (x & (0xffff >> (16 - length)));
- return (x);
+ return (x);
}
diff --git a/lib/libskey/shlib_version b/lib/libskey/shlib_version
index 97c9f92d6b8..3d7c908e43d 100644
--- a/lib/libskey/shlib_version
+++ b/lib/libskey/shlib_version
@@ -1,2 +1,2 @@
major=0
-minor=0
+minor=1
diff --git a/lib/libskey/skey.h b/lib/libskey/skey.h
index 1d7f596a9ea..e9de0d4c84d 100644
--- a/lib/libskey/skey.h
+++ b/lib/libskey/skey.h
@@ -11,7 +11,7 @@
*
* Main client header
*
- * $Id: skey.h,v 1.2 1995/12/20 09:48:23 deraadt Exp $
+ * $Id: skey.h,v 1.3 1996/09/27 15:38:59 millert Exp $
*/
#if defined(__TURBOC__) || defined(__STDC__) || defined(LATTICE)
@@ -33,23 +33,21 @@
/* Server-side data structure for reading keys file during login */
struct skey
{
- FILE *keyfile;
- char buf[256];
- char *logname;
- int n;
- char *seed;
- char *val;
- long recstart; /* needed so reread of buffer is efficient */
-
-
+ FILE *keyfile;
+ char buf[256];
+ char *logname;
+ int n;
+ char *seed;
+ char *val;
+ long recstart; /* needed so reread of buffer is efficient */
};
/* Client-side structure for scanning data stream for challenge */
struct mc
{
- char buf[256];
- int skip;
- int cnt;
+ char buf[256];
+ int skip;
+ int cnt;
};
void f __ARGS ((char *x));
@@ -75,4 +73,5 @@ int getskeyprompt __ARGS ((struct skey *, char *, char *));
int atob8 __ARGS((char *, char *));
int btoa8 __ARGS((char *, char *));
int htoi __ARGS((char));
-
+int skey_get_MDX __ARGS(());
+int skey_set_MDX __ARGS((int));
diff --git a/lib/libskey/skeylogin.c b/lib/libskey/skeylogin.c
index 000a61b6200..e72bc313241 100644
--- a/lib/libskey/skeylogin.c
+++ b/lib/libskey/skeylogin.c
@@ -8,7 +8,7 @@
*
* S/KEY verification check, lookups, and authentication.
*
- * $Id: skeylogin.c,v 1.2 1995/12/20 09:48:24 deraadt Exp $
+ * $Id: skeylogin.c,v 1.3 1996/09/27 15:38:59 millert Exp $
*/
#include <sys/param.h>
@@ -20,7 +20,6 @@
#include <sys/timeb.h>
#include <sys/resource.h>
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -44,7 +43,7 @@ int skeylookup __ARGS((struct skey *, char *));
* record.
*/
int
-getskeyprompt(mp,name,prompt)
+getskeyprompt(mp, name, prompt)
struct skey *mp;
char *name;
char *prompt;
@@ -52,16 +51,17 @@ getskeyprompt(mp,name,prompt)
int rval;
sevenbit(name);
- rval = skeylookup(mp,name);
- strcpy(prompt,"s/key 55 latour1\n");
+ rval = skeylookup(mp, name);
+ (void)strcpy(prompt, "s/key MD0 55 latour1\n");
switch (rval) {
case -1: /* File error */
return -1;
case 0: /* Lookup succeeded, return challenge */
- sprintf(prompt,"s/key %d %s\n",mp->n - 1,mp->seed);
+ (void)sprintf(prompt, "s/key MD%d %d %s\n", skey_get_MDX(),
+ mp->n - 1, mp->seed);
return 0;
case 1: /* User not found */
- fclose(mp->keyfile);
+ (void)fclose(mp->keyfile);
return -1;
}
return -1; /* Can't happen */
@@ -87,10 +87,11 @@ skeychallenge(mp,name, ss)
case -1: /* File error */
return -1;
case 0: /* Lookup succeeded, issue challenge */
- sprintf(ss, "s/key %d %s",mp->n - 1,mp->seed);
+ (void)sprintf(ss, "s/key MD%d %d %s", skey_get_MDX(),
+ mp->n - 1, mp->seed);
return 0;
case 1: /* User not found */
- fclose(mp->keyfile);
+ (void)fclose(mp->keyfile);
return -1;
}
return -1; /* Can't happen */
@@ -107,59 +108,68 @@ skeylookup(mp,name)
struct skey *mp;
char *name;
{
- int found;
- int len;
- long recstart;
+ int found, len;
+ long recstart = 0;
char *cp;
struct stat statbuf;
- /* See if the _PATH_KEYFILE exists, and create it if not */
-
- if (stat(_PATH_KEYFILE,&statbuf) == -1 && errno == ENOENT) {
- mp->keyfile = fopen(_PATH_KEYFILE,"w+");
+ /* See if _PATH_KEYFILE exists, and create it if not */
+ if (stat(_PATH_KEYFILE, &statbuf) == -1 && errno == ENOENT) {
+ mp->keyfile = fopen(_PATH_KEYFILE, "w+");
if (mp->keyfile)
chmod(_PATH_KEYFILE, 0644);
} else {
/* Otherwise open normally for update */
- mp->keyfile = fopen(_PATH_KEYFILE,"r+");
+ mp->keyfile = fopen(_PATH_KEYFILE, "r+");
}
if (mp->keyfile == NULL)
return -1;
/* Look up user name in database */
len = strlen(name);
- if( len > 8 ) len = 8; /* Added 8/2/91 - nmh */
+ /* XXX - do we really want to limit it to 8 char usernames? */
+ if (len > 8)
+ len = 8; /* Added 8/2/91 - nmh */
found = 0;
while (!feof(mp->keyfile)) {
recstart = ftell(mp->keyfile);
mp->recstart = recstart;
- if (fgets(mp->buf,sizeof(mp->buf),mp->keyfile) != mp->buf) {
+ if (fgets(mp->buf, sizeof(mp->buf), mp->keyfile) != mp->buf) {
break;
}
rip(mp->buf);
if (mp->buf[0] == '#')
continue; /* Comment */
- if ((mp->logname = strtok(mp->buf," \t")) == NULL)
+ if ((mp->logname = strtok(mp->buf, " \t")) == NULL)
continue;
- if ((cp = strtok(NULL," \t")) == NULL)
+ if ((cp = strtok(NULL, " \t")) == NULL)
continue;
+ /* Set MDX if specified, else use MD4 */
+ if (cp[0] == 'M' && cp[1] == 'D') {
+ skey_set_MDX(atoi(&cp[2]));
+ if ((cp = strtok(NULL, " \t")) == NULL)
+ continue;
+ } else {
+ skey_set_MDX(4);
+ }
mp->n = atoi(cp);
- if ((mp->seed = strtok(NULL," \t")) == NULL)
+ if ((mp->seed = strtok(NULL, " \t")) == NULL)
continue;
- if ((mp->val = strtok(NULL," \t")) == NULL)
+ if ((mp->val = strtok(NULL, " \t")) == NULL)
continue;
- if (strlen(mp->logname) == len
- && strncmp(mp->logname,name,len) == 0){
+ if (strlen(mp->logname) == len &&
+ strncmp(mp->logname, name, len) == 0) {
found = 1;
break;
}
}
if (found) {
- fseek(mp->keyfile,recstart,0);
+ (void)fseek(mp->keyfile, recstart, SEEK_SET);
return 0;
} else
return 1;
}
+
/* Verify response to a s/key challenge.
*
* Return codes:
@@ -184,10 +194,10 @@ skeyverify(mp,response)
time(&now);
tm = localtime(&now);
- strftime(tbuf, sizeof(tbuf), " %b %d,%Y %T", tm);
+ (void)strftime(tbuf, sizeof(tbuf), " %b %d,%Y %T", tm);
if (response == NULL) {
- fclose(mp->keyfile);
+ (void)fclose(mp->keyfile);
return -1;
}
rip(response);
@@ -195,47 +205,44 @@ skeyverify(mp,response)
/* Convert response to binary */
if (etob(key, response) != 1 && atob8(key, response) != 0) {
/* Neither english words or ascii hex */
- fclose(mp->keyfile);
+ (void)fclose(mp->keyfile);
return -1;
}
/* Compute fkey = f(key) */
- memcpy(fkey,key,sizeof(key));
- fflush (stdout);
-
+ (void)memcpy(fkey,key,sizeof(key));
+ (void)fflush(stdout);
f(fkey);
+
/*
* in order to make the window of update as short as possible
* we must do the comparison here and if OK write it back
* other wise the same password can be used twice to get in
* to the system
*/
+ (void)setpriority(PRIO_PROCESS, 0, -4);
- setpriority(PRIO_PROCESS, 0, -4);
-
- /* reread the file record NOW*/
-
- fseek(mp->keyfile,mp->recstart,0);
- if (fgets(mp->buf,sizeof(mp->buf),mp->keyfile) != mp->buf){
- setpriority(PRIO_PROCESS, 0, 0);
- fclose(mp->keyfile);
+ /* reread the file record NOW */
+ (void)fseek(mp->keyfile, mp->recstart, SEEK_SET);
+ if (fgets(mp->buf, sizeof(mp->buf), mp->keyfile) != mp->buf) {
+ (void)setpriority(PRIO_PROCESS, 0, 0);
+ (void)fclose(mp->keyfile);
return -1;
}
rip(mp->buf);
mp->logname = strtok(mp->buf," \t");
cp = strtok(NULL," \t") ;
+ cp = strtok(NULL," \t") ;
mp->seed = strtok(NULL," \t");
mp->val = strtok(NULL," \t");
/* And convert file value to hex for comparison */
atob8(filekey,mp->val);
/* Do actual comparison */
- fflush (stdout);
-
if (memcmp(filekey,fkey,8) != 0){
/* Wrong response */
- setpriority(PRIO_PROCESS, 0, 0);
- fclose(mp->keyfile);
+ (void)setpriority(PRIO_PROCESS, 0, 0);
+ (void)fclose(mp->keyfile);
return 1;
}
@@ -246,50 +253,47 @@ skeyverify(mp,response)
*/
btoa8(mp->val,key);
mp->n--;
- fseek(mp->keyfile,mp->recstart,0);
- fprintf(mp->keyfile, "%s %04d %-16s %s %-21s\n",
- mp->logname,mp->n,mp->seed, mp->val, tbuf);
+ (void)fseek(mp->keyfile, mp->recstart, SEEK_SET);
+ (void)fprintf(mp->keyfile, "%s MD%d %04d %-16s %s %-21s\n",
+ mp->logname, skey_get_MDX(), mp->n, mp->seed, mp->val, tbuf);
- fclose(mp->keyfile);
+ (void)fclose(mp->keyfile);
- setpriority(PRIO_PROCESS, 0, 0);
+ (void)setpriority(PRIO_PROCESS, 0, 0);
return 0;
}
-
/*
- * skey_haskey ()
+ * skey_haskey()
*
* Returns: 1 user doesnt exist, -1 fle error, 0 user exists.
*
*/
-
int
-skey_haskey (username)
+skey_haskey(username)
char *username;
{
- int i;
struct skey skey;
- return (skeylookup (&skey, username));
+ return(skeylookup(&skey, username));
}
/*
- * skey_keyinfo ()
+ * skey_keyinfo()
*
* Returns the current sequence number and
* seed for the passed user.
*
*/
char *
-skey_keyinfo (username)
+skey_keyinfo(username)
char *username;
{
int i;
- static char str [50];
+ static char str[50];
struct skey skey;
- i = skeychallenge (&skey, username, str);
+ i = skeychallenge(&skey, username, str);
if (i == -1)
return 0;
@@ -297,7 +301,7 @@ skey_keyinfo (username)
}
/*
- * skey_passcheck ()
+ * skey_passcheck()
*
* Check to see if answer is the correct one to the current
* challenge.
@@ -305,26 +309,25 @@ skey_keyinfo (username)
* Returns: 0 success, -1 failure
*
*/
-
int
-skey_passcheck (username, passwd)
+skey_passcheck(username, passwd)
char *username, *passwd;
{
int i;
struct skey skey;
- i = skeylookup (&skey, username);
+ i = skeylookup(&skey, username);
if (i == -1 || i == 1)
return -1;
- if (skeyverify (&skey, passwd) == 0)
+ if (skeyverify(&skey, passwd) == 0)
return skey.n;
return -1;
}
/*
- * skey_authenticate ()
+ * skey_authenticate()
*
* Used when calling program will allow input of the user's
* response to the challenge.
@@ -332,33 +335,33 @@ skey_passcheck (username, passwd)
* Returns: 0 success, -1 failure
*
*/
-
int
-skey_authenticate (username)
+skey_authenticate(username)
char *username;
{
int i;
char pbuf[256], skeyprompt[50];
struct skey skey;
- /* Attempt a S/Key challenge */
- i = skeychallenge (&skey, username, skeyprompt);
+ /* Attempt an S/Key challenge */
+ i = skeychallenge(&skey, username, skeyprompt);
if (i == -2)
return 0;
- printf("[%s]\n", skeyprompt);
- fflush(stdout);
+ (void)fprintf(stderr, "[%s]\n", skeyprompt);
+ (void)fflush(stderr);
- printf("Response: ");
- readskey(pbuf, sizeof (pbuf));
+ (void)fputs("Response: ", stderr);
+ readskey(pbuf, sizeof(pbuf));
rip(pbuf);
/* Is it a valid response? */
- if (i == 0 && skeyverify (&skey, pbuf) == 0) {
+ if (i == 0 && skeyverify(&skey, pbuf) == 0) {
if (skey.n < 5) {
- printf ("\nWarning! Key initialization needed soon. ");
- printf ("(%d logins left)\n", skey.n);
+ (void)fprintf(stderr,
+ "\nWarning! Key initialization needed soon. (%d logins left)\n",
+ skey.n);
}
return 0;
}
@@ -382,13 +385,13 @@ skeyzero(mp, response)
* Seek to the right place and write comment character
* which effectively zero's out the entry.
*/
- fseek(mp->keyfile, mp->recstart, 0);
+ (void)fseek(mp->keyfile, mp->recstart, SEEK_SET);
if (fputc('#', mp->keyfile) == EOF) {
fclose(mp->keyfile);
return -1;
}
- fclose(mp->keyfile);
+ (void)fclose(mp->keyfile);
return 0;
}
diff --git a/lib/libskey/skeysubr.c b/lib/libskey/skeysubr.c
index 232927a1ed5..9cd20eef327 100644
--- a/lib/libskey/skeysubr.c
+++ b/lib/libskey/skeysubr.c
@@ -10,7 +10,7 @@
*
* S/KEY misc routines.
*
- * $Id: skeysubr.c,v 1.1 1995/10/18 08:43:11 deraadt Exp $
+ * $Id: skeysubr.c,v 1.2 1996/09/27 15:39:00 millert Exp $
*/
#include <stdio.h>
@@ -18,64 +18,109 @@
#include <string.h>
#include <signal.h>
#include <termios.h>
+#include <md4.h>
+#include <md5.h>
-#include "md4.h"
#include "skey.h"
-struct termios newtty;
-struct termios oldtty;
+/* Default MDX function to use (currently 4 or 5) */
+#ifndef SKEY_MDX_DEFAULT
+#define SKEY_MDX_DEFAULT 5
+#endif
static void trapped __ARGS((int sig));
-static void set_term __ARGS((void));
-static void unset_term __ARGS((void));
-static void echo_off __ARGS((void));
+static void f_MD4 __ARGS ((char *x));
+static void f_MD5 __ARGS ((char *x));
+static int keycrunch_MD4 __ARGS ((char *result, char *seed, char *passwd));
+static int keycrunch_MD5 __ARGS ((char *result, char *seed, char *passwd));
-/* Crunch a key:
- * concatenate the seed and the password, run through MD4 and
+static int skey_MDX = 0;
+static int skey_echo;
+
+/*
+ * Crunch a key:
+ * concatenate the seed and the password, run through MD4/5 and
* collapse to 64 bits. This is defined as the user's starting key.
*/
int
-keycrunch(result,seed,passwd)
-char *result; /* 8-byte result */
-char *seed; /* Seed, any length */
-char *passwd; /* Password, any length */
+keycrunch(result, seed, passwd)
+ char *result; /* 8-byte result */
+ char *seed; /* Seed, any length */
+ char *passwd; /* Password, any length */
+{
+ switch (skey_get_MDX()) {
+ /*
+ * Need a default case to appease gc even though
+ * skey_set_MDX() guantaees we get back 4 or 5
+ */
+ case 4 : return(keycrunch_MD4(result, seed, passwd));
+ default : return(keycrunch_MD5(result, seed, passwd));
+ }
+ /* NOTREACHED */
+}
+
+static int
+keycrunch_MD4(result, seed, passwd)
+ char *result; /* 8-byte result */
+ char *seed; /* Seed, any length */
+ char *passwd; /* Password, any length */
{
char *buf;
- MDstruct md;
+ MD4_CTX md;
+ u_int32_t results[4];
unsigned int buflen;
- int i;
- register long tmp;
-
+
buflen = strlen(seed) + strlen(passwd);
if ((buf = (char *)malloc(buflen+1)) == NULL)
return -1;
- strcpy(buf,seed);
- strcat(buf,passwd);
+ (void)strcpy(buf, seed);
+ (void)strcat(buf, passwd);
/* Crunch the key through MD4 */
sevenbit(buf);
- MDbegin(&md);
- MDupdate(&md,(unsigned char *)buf,8*buflen);
+ MD4Init(&md);
+ MD4Update(&md, (unsigned char *)buf, buflen);
+ MD4Final((unsigned char *)results ,&md);
+ (void)free(buf);
+
+ /* Fold result from 128 to 64 bits */
+ results[0] ^= results[2];
+ results[1] ^= results[3];
+
+ (void)memcpy((void *)result, (void *)results, 8);
+
+ return 0;
+}
+
+static int
+keycrunch_MD5(result, seed, passwd)
+ char *result; /* 8-byte result */
+ char *seed; /* Seed, any length */
+ char *passwd; /* Password, any length */
+{
+ char *buf;
+ MD5_CTX md;
+ u_int32_t results[4];
+ unsigned int buflen;
+
+ buflen = strlen(seed) + strlen(passwd);
+ if ((buf = (char *)malloc(buflen+1)) == NULL)
+ return -1;
+ (void)strcpy(buf, seed);
+ (void)strcat(buf, passwd);
- free(buf);
+ /* Crunch the key through MD5 */
+ sevenbit(buf);
+ MD5Init(&md);
+ MD5Update(&md, (unsigned char *)buf, buflen);
+ MD5Final((unsigned char *)results ,&md);
+ (void)free(buf);
/* Fold result from 128 to 64 bits */
- md.buffer[0] ^= md.buffer[2];
- md.buffer[1] ^= md.buffer[3];
-
- /* Default (but slow) code that will convert to
- * little-endian byte ordering on any machine
- */
- for (i=0; i<2; i++) {
- tmp = md.buffer[i];
- *result++ = tmp;
- tmp >>= 8;
- *result++ = tmp;
- tmp >>= 8;
- *result++ = tmp;
- tmp >>= 8;
- *result++ = tmp;
- }
+ results[0] ^= results[2];
+ results[1] ^= results[3];
+
+ (void)memcpy((void *)result, (void *)results, 8);
return 0;
}
@@ -85,36 +130,51 @@ void
f(x)
char *x;
{
- MDstruct md;
- register long tmp;
+ switch (skey_get_MDX()) {
+ /*
+ * Need a default case to appease gc even though
+ * skey_set_MDX() guantaees we get back 4 or 5
+ */
+ case 4 : return(f_MD4(x));
+ default : return(f_MD5(x));
+ }
+ /* NOTREACHED */
+}
+
+void
+f_MD4(x)
+ char *x;
+{
+ MD4_CTX md;
+ u_int32_t results[4];
+
+ MD4Init(&md);
+ MD4Update(&md, (unsigned char *)x, 8);
+ MD4Final((unsigned char *)results, &md);
+
+ /* Fold 128 to 64 bits */
+ results[0] ^= results[2];
+ results[1] ^= results[3];
+
+ (void)memcpy((void *)x, (void *)results, 8);
+}
+
+void
+f_MD5(x)
+ char *x;
+{
+ MD5_CTX md;
+ u_int32_t results[4];
- MDbegin(&md);
- MDupdate(&md,(unsigned char *)x,64);
+ MD5Init(&md);
+ MD5Update(&md, (unsigned char *)x, 8);
+ MD5Final((unsigned char *)results, &md);
/* Fold 128 to 64 bits */
- md.buffer[0] ^= md.buffer[2];
- md.buffer[1] ^= md.buffer[3];
-
- /* Default (but slow) code that will convert to
- * little-endian byte ordering on any machine
- */
- tmp = md.buffer[0];
- *x++ = tmp;
- tmp >>= 8;
- *x++ = tmp;
- tmp >>= 8;
- *x++ = tmp;
- tmp >>= 8;
- *x++ = tmp;
-
- tmp = md.buffer[1];
- *x++ = tmp;
- tmp >>= 8;
- *x++ = tmp;
- tmp >>= 8;
- *x++ = tmp;
- tmp >>= 8;
- *x = tmp;
+ results[0] ^= results[2];
+ results[1] ^= results[3];
+
+ (void)memcpy((void *)x, (void *)results, 8);
}
/* Strip trailing cr/lf from a line of text */
@@ -122,31 +182,46 @@ void
rip(buf)
char *buf;
{
- char *cp;
-
- if ((cp = strchr(buf,'\r')) != NULL)
- *cp = '\0';
+ buf += strcspn(buf, "\r\n");
- if ((cp = strchr(buf,'\n')) != NULL)
- *cp = '\0';
+ if (*buf)
+ *buf = '\0';
}
char *
-readpass (buf,n)
+readpass(buf, n)
char *buf;
int n;
{
- set_term();
- echo_off();
+ struct termios term;
+ void (*old_handler) __P(());
- fgets(buf, n, stdin);
+ /* Catch SIGINT and save old signal handler */
+ old_handler = signal(SIGINT, trapped);
+ /* Turn off echoing */
+ (void) tcgetattr(fileno(stdin), &term);
+ if ((skey_echo = (term.c_lflag & ECHO))) {
+ term.c_lflag &= ~ECHO;
+ (void)tcsetattr(fileno(stdin), TCSAFLUSH|TCSASOFT, &term);
+ }
+
+ (void)fgets(buf, n, stdin);
rip(buf);
- printf("\n");
+
+ (void)putc('\n', stderr);
+ (void)fflush(stderr);
+
+ /* Restore echo and signal handler */
+ if (skey_echo) {
+ term.c_lflag |= ECHO;
+ (void)tcsetattr(fileno(stdin), TCSAFLUSH|TCSASOFT, &term);
+ }
+ if (old_handler != SIG_ERR)
+ (void)signal(SIGINT, old_handler);
sevenbit(buf);
- unset_term();
return buf;
}
@@ -155,10 +230,11 @@ readskey(buf, n)
char *buf;
int n;
{
- fgets (buf, n, stdin);
-
+ (void)fgets(buf, n, stdin);
rip(buf);
- printf ("\n");
+
+ (void)putc('\n', stderr);
+ (void)fflush(stderr);
sevenbit (buf);
@@ -166,43 +242,26 @@ readskey(buf, n)
}
static void
-set_term()
-{
- fflush(stdout);
- tcgetattr(fileno(stdin), &newtty);
- tcgetattr(fileno(stdin), &oldtty);
-
- signal (SIGINT, trapped);
-}
-
-static void
-echo_off()
+trapped(sig)
+ int sig;
{
- newtty.c_lflag &= ~(ICANON | ECHO | ECHONL);
- newtty.c_cc[VMIN] = 1;
- newtty.c_cc[VTIME] = 0;
- newtty.c_cc[VINTR] = 3;
+ (void)fputs("^C\n", stderr);
+ (void)fflush(stderr);
- tcsetattr(fileno(stdin), TCSADRAIN, &newtty);
-}
+ /* Turn on echo if we turned it off */
+ if (skey_echo) {
+ struct termios term;
-static void
-unset_term()
-{
- tcsetattr(fileno(stdin), TCSADRAIN, &oldtty);
-}
+ (void) tcgetattr(fileno(stdin), &term);
+ term.c_lflag |= ECHO;
+ (void)tcsetattr(fileno(stdin), TCSAFLUSH|TCSASOFT, &term);
+ }
-static void
-trapped(sig)
- int sig;
-{
- signal(SIGINT, trapped);
- printf("^C\n");
- unset_term();
exit(-1);
}
-/* Convert 8-byte hex-ascii string to binary array
+/*
+ * Convert 8-byte hex-ascii string to binary array
* Returns 0 on success, -1 on error
*/
int
@@ -241,14 +300,13 @@ btoa8(out, in)
if (in == NULL || out == NULL)
return -1;
- for (i=0;i<8;i++) {
- sprintf(out,"%02x",*in++ & 0xff);
+ for (i=0; i < 8; i++) {
+ (void)sprintf(out, "%02x", *in++ & 0xff);
out += 2;
}
return 0;
}
-
/* Convert hex digit to binary integer */
int
htoi(c)
@@ -263,6 +321,7 @@ htoi(c)
return -1;
}
+/* Skip leading spaces from the string */
char *
skipspace(cp)
register char *cp;
@@ -276,10 +335,10 @@ skipspace(cp)
return cp;
}
-/* removebackspaced over charaters from the string */
+/* Remove backspaced over charaters from the string */
void
backspace(buf)
-char *buf;
+ char *buf;
{
char bs = 0x8;
char *cp = buf;
@@ -290,10 +349,9 @@ char *buf;
if (out == buf) {
cp++;
continue;
- }
- else {
- cp++;
- out--;
+ } else {
+ cp++;
+ out--;
}
} else {
*out++ = *cp++;
@@ -303,11 +361,7 @@ char *buf;
*out = '\0';
}
-/* sevenbit ()
- *
- * Make sure line is all seven bits.
- */
-
+/* Make sure line is all seven bits */
void
sevenbit(s)
char *s;
@@ -315,3 +369,28 @@ sevenbit(s)
while (*s)
*s++ &= 0x7f;
}
+
+/* Set MDX type (returns previous) */
+int
+skey_set_MDX(new)
+ int new;
+{
+ int old;
+
+ if (new != 4 && new != 5)
+ return -1;
+
+ old = skey_get_MDX();
+ skey_MDX = new;
+ return old;
+}
+
+/* Get current MDX type */
+int
+skey_get_MDX()
+{
+ if (skey_MDX == 0)
+ skey_MDX = SKEY_MDX_DEFAULT;
+
+ return skey_MDX;
+}