Subject: Re: challenge/response password program
To: None <current-users@sun-lamp.cs.berkeley.edu>
From: Ty Sarna <tsarna@endicor.com>
List: current-users
Date: 05/19/1994 07:15:17
In article <9405181416.AA18841@entropic.com> Ken Hornstein <kenh@wrl.EPI.COM> writes:
> Have you looked at S/KEY?  I haven't tried building it under NetBSD, but since
> you have source it should be pretty easy to do it.  It's not exactly a
> challenge-response, but I think it will do what you want.

S/KEY 1.1b ports to -current with only a few minor annoyances. Appended
are quick patches to /usr/bin/{login,su} to allow s/key authentication.
You will need the s/key binaries and libskey.a built and installed,
and need to compile login+su with -DSKEY and link them with -lskey.

With these patches you can enter "s/key" at a {su,login} Password:
prompt and then be prompted for a s/key one-time password, or if you're
on a secure login you can just enter your regular password.

I'd be willing to do a port of s/key to NetBSD for proper integration if
the core team is agreeable...  I think that would be a Really Really
Good Thing, what with the recent spate of password snooping. 


BTW, the tests for skey_haskey() below are correct.  Contrary to common
sense, a true return from skey_haskey() means the user does NOT have a
key!


*** login/login.c.orig	Wed May 18 19:32:50 1994
--- login/login.c	Wed May 18 19:43:22 1994
***************
*** 79,84 ****
--- 79,85 ----
  void	 sleepexit __P((int));
  char	*stypeof __P((char *));
  void	 timedout __P((int));
+ int	 pwcheck __P((char *, char *, char *, char *));
  #ifdef KERBEROS
  int	 klogin __P((struct passwd *, char *, char *, char *));
  #endif
***************
*** 257,265 ****
  			if (rval == 0)
  				authok = 1;
  			else if (rval == 1)
! 				rval = strcmp(crypt(p, salt), pwd->pw_passwd);
  #else
! 			rval = strcmp(crypt(p, salt), pwd->pw_passwd);
  #endif
  		}
  		bzero(p, strlen(p));
--- 258,266 ----
  			if (rval == 0)
  				authok = 1;
  			else if (rval == 1)
! 				rval = pwcheck(username, p, salt, pwd->pw_passwd);
  #else
! 			rval = pwcheck(username, p, salt, pwd->pw_passwd);
  #endif
  		}
  		bzero(p, strlen(p));
***************
*** 427,432 ****
--- 428,451 ----
  	execlp(pwd->pw_shell, tbuf, 0);
  	(void)fprintf(stderr, "%s: %s\n", pwd->pw_shell, strerror(errno));
  	exit(1);
+ }
+ 
+ int
+ pwcheck(user, p, salt, passwd)
+ 	char *user, *p, *salt, *passwd;
+ {
+ #ifdef SKEY
+ 	if (strcasecmp(p, "s/key") == 0) {
+ 		if (skey_haskey(user)) {
+ 			fprintf(stderr, "You have no s/key. ");
+ 			return 1;
+ 		} else {
+ 			fprintf(stderr, "\n");
+ 			return skey_authenticate(user);
+ 		}
+ 	}
+ #endif
+ 	return strcmp(crypt(p, salt), passwd);
  }
  
  #ifdef	KERBEROS
*** su/su.c.orig	Wed May 18 18:53:22 1994
--- su/su.c	Wed May 18 19:13:07 1994
***************
*** 169,175 ****
--- 169,190 ----
  		/* if target requires a password, verify it */
  		if (*pwd->pw_passwd) {
  			p = getpass("Password:");
+ #ifdef SKEY
+ 			if (strcasecmp(p, "s/key") == 0) {
+ 				if (skey_haskey(user)) {
+ 					fprintf(stderr, "Sorry, you have no s/key.\n");
+ 					exit(1);
+ 				} else {
+ 					fprintf(stderr, "\n");
+ 					if (skey_authenticate(user)) {
+ 						goto badlogin;
+ 					}
+ 				}
+ 
+ 			} else
+ #endif
  			if (strcmp(pwd->pw_passwd, crypt(p, pwd->pw_passwd))) {
+ badlogin:
  				fprintf(stderr, "Sorry\n");
  				syslog(LOG_AUTH|LOG_WARNING,
  					"BAD SU %s to %s%s", username,


-- 
Ty Sarna	     "It pays to be obvious, especially if you have a 
tsarna@endicor.com    reputation for subtlety" -- Salvor Hardin

------------------------------------------------------------------------------