Subject: bin/3714: skeyinfo.sh is *bad*, use c instead
To: None <gnats-bugs@gnats.netbsd.org>
From: Andrew Brown <codewarrior@daemon.org>
List: netbsd-bugs
Date: 06/06/1997 00:42:52
>Number:         3714
>Category:       bin
>Synopsis:       shell script cannot give proper functionality
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Thu Jun  5 21:50:01 1997
>Last-Modified:
>Originator:     Andrew Brown
>Organization:
none
>Release:        1.2
>Environment:
System: NetBSD noc 1.2 NetBSD 1.2 (null) #1: Sun Feb 16 15:43:11 PST 1997 root@noc:/usr/src/sys/arch/i386/compile/null i386
>Description:

     in the interests of security, my /etc/skeykeys file (yes, i still
   use skey) is r/w for root only.  this renders skeyinfo.sh useless.
   users would still like to be able to find out their next prompt, so
   instead of making the shell script suid root (defeats the permissions
   mode), i wrote simple a c program.  :)

     btw - why does the skey.h include file not get installed in
   /usr/include?  it would make the code below somewhat cleaner.

>How-To-Repeat:

     just read skeyinfo.sh.  it's a shell script.  :P

>Fix:

  use this code for skeyinfo.c and arrange for it to be installed suid
root in place of /usr/bin/skeyinfo.

#include <pwd.h>
#include <stdio.h>

/* 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 */


};
/* stolen from skey.h */

int
main(argc,argv)
     int argc;
     char *argv[];
{
  struct skey skey;
  char name[100],prompt[100];
  int uid;
  struct passwd *pw=NULL;

  argc--;
  argv++;
  
  if (geteuid()) {
    printf("must be root to read /etc/skeykeys\n");
    exit(1);
  }
  
  uid=getuid();
  if (!argc)
    pw=getpwuid(uid);
  else if (!uid)
    pw=getpwnam(argv[0]);
  else {
    printf("not allowed to look at other users' s/keys...\n");
    exit(1);
  }
  
  if (!pw) {
    if (argc)
      printf("%s: no such user\n",argv[0]);
    else
      printf("who are you?\n");
    exit(1);
  }
  
  strncpy(name,pw->pw_name,100);
  name[99]=0;

  switch (getskeyprompt(&skey,name,prompt)) {
  case 0:         /* Lookup succeeded, return challenge */
    if (argc)
      printf("%s's ",pw->pw_name);
    printf("next %s",prompt);
    break;
  case -1:
    printf("%s %s no s/key\n",
	   argc?name:"You",
	   argc?"has":"have");
    break;
  default:
    printf("unknown error?\n");
    break;
  }
  
  return 0;
}
>Audit-Trail:
>Unformatted: