/* Login code for S/KEY Authentication. S/KEY is a trademark
* Mink is the former name of the S/KEY authentication system.
* Many references for mink may still be found in this program. */
#include <sys/resource.h>
#define KEYFILE "/etc/skeykeys"
int skeylookup
__ARGS((struct skey
*mp
,char *name
));
#define setpriority(x,y,z) /* nothing */
/* Issue a skey challenge for user 'name'. If successful,
* fill in the caller's skey structure and return 0. If unsuccessful
* (e.g., if name is unknown) return -1.
* The file read/write pointer is left at the start of the
getskeyprompt(mp
,name
,prompt
)
rval
= skeylookup(mp
,name
);
strcpy(prompt
,"s/key 55 latour1\n");
case -1: /* File error */
case 0: /* Lookup succeeded, return challenge */
sprintf(prompt
,"s/key %d %s\n",mp
->n
- 1,mp
->seed
);
case 1: /* User not found */
return -1; /* Can't happen */
/* Return a skey challenge string for user 'name'. If successful,
* fill in the caller's skey structure and return 0. If unsuccessful
* (e.g., if name is unknown) return -1.
* The file read/write pointer is left at the start of the
skeychallenge(mp
,name
, ss
)
rval
= skeylookup(mp
,name
);
case -1: /* File error */
case 0: /* Lookup succeeded, issue challenge */
sprintf(ss
, "s/key %d %s",mp
->n
- 1,mp
->seed
);
case 1: /* User not found */
return -1; /* Can't happen */
/* Find an entry in the One-time Password database.
* -1: error in opening database
* 0: entry found, file R/W pointer positioned at beginning of record
* 1: entry not found, file R/W pointer positioned at EOF
/* See if the KEYFILE exists, and create it if not */
if(stat(KEYFILE
,&statbuf
) == -1 && errno
== ENOENT
){
mp
->keyfile
= fopen(KEYFILE
,"w+");
(void) chmod(KEYFILE
, 0644);
/* Otherwise open normally for update */
mp
->keyfile
= fopen(KEYFILE
,"r+");
/* Look up user name in database */
if( len
> 8 ) len
= 8; /* Added 8/2/91 - nmh */
while(!feof(mp
->keyfile
)){
recstart
= ftell(mp
->keyfile
);
if(fgets(mp
->buf
,sizeof(mp
->buf
),mp
->keyfile
) != mp
->buf
){
if((mp
->logname
= strtok(mp
->buf
," \t")) == NULL
)
if((cp
= strtok(NULL
," \t")) == NULL
)
if((mp
->seed
= strtok(NULL
," \t")) == NULL
)
if((mp
->val
= strtok(NULL
," \t")) == NULL
)
if(strlen(mp
->logname
) == len
&& strncmp(mp
->logname
,name
,len
) == 0){
fseek(mp
->keyfile
,recstart
,0);
/* Verify response to a s/key challenge.
* -1: Error of some sort; database unchanged
* 0: Verify successful, database updated
* 1: Verify failed, database unchanged
* The database file is always closed by this call.
strftime(tbuf
, sizeof(tbuf
), " %b %d,%Y %T", tm
);
/* Convert response to binary */
if(etob(key
,response
) != 1 && atob8(key
,response
) != 0){
/* Neither english words or ascii hex */
/* Compute fkey = f(key) */
memcpy(fkey
,key
,sizeof(key
));
/* 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
setpriority(PRIO_PROCESS
, 0, -4);
gettimeofday(&startval, (char *)0 );
/* 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);
mp
->logname
= strtok(mp
->buf
," \t");
cp
= strtok(NULL
," \t") ;
mp
->seed
= strtok(NULL
," \t");
mp
->val
= strtok(NULL
," \t");
/* And convert file value to hex for comparison */
/* Do actual comparison */
if(memcmp(filekey
,fkey
,8) != 0){
setpriority(PRIO_PROCESS
, 0, 0);
/* Update key in database by overwriting entire record. Note
* that we must write exactly the same number of bytes as in
* the original record (note fixed width field for N)
fseek(mp
->keyfile
,mp
->recstart
,0);
fprintf(mp
->keyfile
,"%s %04d %-16s %s %-21s\n",mp
->logname
,mp
->n
,mp
->seed
,
gettimeofday(&endval, (char *)0 );
microsec = (endval.tv_sec - startval.tv_sec) * 1000000 + (endval.tv_usec - startval.tv_usec);
fprintf(stderr, "window= %d micro seconds \n" , microsec);
setpriority(PRIO_PROCESS
, 0, 0);
/* Convert 8-byte hex-ascii string to binary array
* Returns 0 on success, -1 on error
if(in
== NULL
|| out
== NULL
)
if((in
= skipspace(in
)) == NULL
)
if((val
= htoi(*in
++)) == -1)
if((in
= skipspace(in
)) == NULL
)
if((val
= htoi(*in
++)) == -1)
while(*cp
== ' ' || *cp
== '\t')
/* Convert 8-byte binary array to hex-ascii string */
if(in
== NULL
|| out
== NULL
)
sprintf(out
,"%02x",*in
++ & 0xff);
/* Convert hex digit to binary integer */