Subject: bin/3270: login: include S/Key challenge in prompt.
To: None <gnats-bugs@gnats.netbsd.org>
From: Simon J. Gerraty <sjg@quick.com.au>
List: netbsd-bugs
Date: 03/02/1997 00:27:56
>Number:         3270
>Category:       bin
>Synopsis:       login: include S/Key challenge in prompt.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sat Mar  1 05:35:01 1997
>Last-Modified:
>Originator:     Simon J. Gerraty
>Organization:
Zen Programming...
>Release:        Feb22
>Environment:
	
System: NetBSD zen.quick.com.au 1.2C NetBSD 1.2C (ZEN) #3: Fri Feb 28 12:18:37 EST 1997 root@zen.quick.com.au:/share/usr.src/sys/arch/i386/compile/ZEN i386


>Description:
	
The patch below, causes login to include a user's S/Key challenge in
the passwd prompt - much the same as ftpd does. 

I have also added a -s option that can be used to force use of S/Key.

Note that, the passwd "s/key" should still be entered if echo of the
response is desired (such as when not cut/pasting).

Eg.

login: sjg
Password [s/key 633 zen.203101]:
[s/key 633 zen.203101]
Response:   

if cut/paste is available, then the s/key response can be entered at
the Password prompt.

>How-To-Repeat:
	
Apply the patch.
>Fix:
	
*** login.c.~1~	Tue Feb 11 23:22:50 1997
--- login.c	Sun Mar  2 00:11:51 1997
***************
*** 113,118 ****
--- 113,122 ----
  struct	passwd *pwd;
  int	failures;
  char	term[64], *envinit[1], *hostname, *username, *tty;
+ #ifdef SKEY
+ int	used_skey = 0;
+ int 	require_skey = 0;
+ #endif
  
  int
  main(argc, argv)
***************
*** 126,132 ****
  	struct utmp utmp;
  	int ask, ch, cnt, fflag, hflag, pflag, quietlog, rootlogin, rval;
  	uid_t uid;
! 	char *domain, *p, *salt, *ttyn;
  	char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];
  	char localhost[MAXHOSTNAMELEN];
  
--- 130,136 ----
  	struct utmp utmp;
  	int ask, ch, cnt, fflag, hflag, pflag, quietlog, rootlogin, rval;
  	uid_t uid;
! 	char *domain, *p, *salt, *ttyn, *pwprompt = 0;
  	char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];
  	char localhost[MAXHOSTNAMELEN];
  
***************
*** 143,148 ****
--- 147,153 ----
  	 * -f is used to skip a second login authentication
  	 * -h is used by other servers to pass the name of the remote
  	 *    host to login so that it may be placed in utmp and wtmp
+ 	 * -s is used to force use of S/Key or equivalent.
  	 */
  	domain = NULL;
  	if (gethostname(localhost, sizeof(localhost)) < 0)
***************
*** 152,158 ****
  
  	fflag = hflag = pflag = 0;
  	uid = getuid();
! 	while ((ch = getopt(argc, argv, "fh:p")) != EOF)
  		switch (ch) {
  		case 'f':
  			fflag = 1;
--- 157,163 ----
  
  	fflag = hflag = pflag = 0;
  	uid = getuid();
! 	while ((ch = getopt(argc, argv, "fh:ps")) != EOF)
  		switch (ch) {
  		case 'f':
  			fflag = 1;
***************
*** 169,174 ****
--- 174,188 ----
  		case 'p':
  			pflag = 1;
  			break;
+ 		case 's':
+ #ifdef SKEY
+ 			/*
+ 			 * If -s given twice, use S/Key or no login
+ 			 * otherwise just insist on S/Key if user has one.
+ 			 */
+ 			++require_skey;
+ #endif
+ 			break;
  		case '?':
  		default:
  			if (!uid)
***************
*** 200,205 ****
--- 214,222 ----
  		tty = ttyn;
  
  	for (cnt = 0;; ask = 1) {
+ #ifdef SKEY
+ 		used_skey = 0;
+ #endif
  #if defined(KERBEROS) || defined(KERBEROS5)
  	        kdestroy();
  #endif
***************
*** 268,274 ****
  
  		(void)setpriority(PRIO_PROCESS, 0, -4);
  
! 		p = getpass("Password:");
  
  		if (pwd) {
  #if defined(KERBEROS) || defined(KERBEROS5)
--- 285,311 ----
  
  		(void)setpriority(PRIO_PROCESS, 0, -4);
  
! #ifdef SKEY
! 		p = NULL;
! 		pwprompt = "Password:";
! 		
! 		if (skey_haskey(username) == 0) {
! 
! 			if (require_skey > 0)
! 				p = "s/key";
! 			else {
! 				extern char *skey_keyinfo();
! 				static char skprompt[80];
! 				char *skinfo = skey_keyinfo(username);
! 				
! 				(void) sprintf(skprompt, "Password [%.*s]:",
! 					       sizeof(skprompt) - 20, skinfo);
! 				pwprompt = skprompt;
! 			}
! 		}
! 		if (p == NULL)
! #endif
! 			p = getpass(pwprompt);
  
  		if (pwd) {
  #if defined(KERBEROS) || defined(KERBEROS5)
***************
*** 286,291 ****
--- 323,331 ----
  			rval = pwcheck(username, p, salt, pwd->pw_passwd);
  #endif
  		}
+ #ifdef SKEY
+ 		if (used_skey == 0)
+ #endif
  			memset(p, 0, strlen(p));
  
  		(void)setpriority(PRIO_PROCESS, 0, 0);
***************
*** 470,483 ****
  pwcheck(user, p, salt, passwd)
  	char *user, *p, *salt, *passwd;
  {
  #ifdef SKEY
! 	if (strcasecmp(p, "s/key") == 0)
! 		if (skey_haskey(user))
  			return 1;
! 		else
! 			return skey_authenticate(user);
  #endif
! 	return strcmp(crypt(p, salt), passwd);
  }
  
  #if defined(KERBEROS) || defined(KERBEROS5)
--- 510,538 ----
  pwcheck(user, p, salt, passwd)
  	char *user, *p, *salt, *passwd;
  {
+ 	int sts = strcmp(crypt(p, salt), passwd);
+ 	
  #ifdef SKEY
! 	if (sts) {				/* wasn't passwd */
! 		if (skey_haskey(user)) {
! 			if (strcasecmp(p, "s/key") == 0) {
! 				(void) fprintf(stderr, "You have no s/key. ");
  				return 1;
! 			}
! 		} else {
! 			if (strcasecmp(p, "s/key") == 0) {
! 				sts = skey_authenticate(user);
! 			} else {
! 				if ((sts = skey_passcheck(user, p)) != -1) {
! 					sts = 0; /* ok */
! 				}
! 			}
! 		}
! 		if (sts == 0)
! 			used_skey = 1;
! 	}
  #endif
! 	return sts;
  }
  
  #if defined(KERBEROS) || defined(KERBEROS5)
*** login.1.~1~	Sat Oct 14 13:14:44 1995
--- login.1	Sun Mar  2 00:19:00 1997
***************
*** 41,47 ****
  .Nd log into the computer
  .Sh SYNOPSIS
  .Nm login
! .Op Fl fp
  .Op Fl h Ar hostname
  .Op Ar user
  .Sh DESCRIPTION
--- 41,47 ----
  .Nd log into the computer
  .Sh SYNOPSIS
  .Nm login
! .Op Fl fps
  .Op Fl h Ar hostname
  .Op Ar user
  .Sh DESCRIPTION
***************
*** 54,62 ****
  .Nm login
  prompts for a user name.
  Authentication of users is done via passwords.
  Alternately, the user can enter the password "s/key", in which case
! S/Key authentication of users is performed, as descibed in
! .Xr skey 1 .
  S/Key is a Trademark of Bellcore.
  .Pp
  The options are as follows:
--- 54,67 ----
  .Nm login
  prompts for a user name.
  Authentication of users is done via passwords.
+ If the user can be authenticated via S/Key, then the S/Key challenge is
+ incorporated in the password prompt.  The user then has the option of
+ entering their normal password or the S/Key response, neither will be
+ echoed. 
  Alternately, the user can enter the password "s/key", in which case
! S/Key authentication is performed, as descibed in
! .Xr skey 1 ,
! and the response will be echoed.
  S/Key is a Trademark of Bellcore.
  .Pp
  The options are as follows:
***************
*** 83,88 ****
--- 88,99 ----
  The
  .Fl p
  option disables this behavior.
+ .It Fl s
+ If the user can be authenticated via S/Key, then require it.
+ If the 
+ .Fl s
+ option is given more than once, user's may only log in if they can be
+ authenticated via S/Key.
  .El
  .Pp
  If the file
>Audit-Trail:
>Unformatted: