Listing 1: snklogin.c
/* Listing 1
* snklogin.c - front end to standard login program
* which first authenticates the user using the
* SecureNet encryption key.
* Mark Dapoz Wed Dec 2 15:41:47 MET 1992
*/
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <ctype.h>
#include <signal.h>
#include <setjmp.h>
#include <syslog.h>
#include <pwd.h>
#include "snk.h"
#include "pathnames.h"
#include "des.h"
char snkkey[8];
int pflag=0, iflag=0, hflag=0;
char *from_host = "unknown host";
char *from_ip = "location unknown";
char *user = NULL;
jmp_buf env;
main(argc, argv)
int argc;
char **argv;
{
char challenge[9], response[9], snkkey[8], reply[16];
char id[16], in_id[9], *p, message[1024];;
unsigned int oct1, oct2, oct3, oct4,
oct5, oct6, oct7, oct8, cksum;
register int ch;
int i;
int secured=0;
extern char *optarg;
extern int optind;
FILE *in_file;
extern int timeout();
char *real_ipinfo();
char *auth_class=NULL;
int quit();
/* list of hostnames that we allow through */
char *hosts_allow[] = { "viceroy.bsc.no",
"traine.bsc.no",
"overlord.bsc.no",
NULL };
/* list of ip addresses that we allow through */
char *ip_addr_allow[] = { "129.177.80.6",
"129.177.80.64",
"129.177.80.5",
NULL };
signal(SIGALRM, timeout);
/* just die if anything goes wrong */
signal(SIGHUP, quit);
signal(SIGINT, quit);
signal(SIGQUIT, quit);
signal(SIGILL, quit);
signal(SIGABRT, quit);
signal(SIGSEGV, quit);
signal(SIGTERM, quit);
/* zero out the snkkey first */
for (i=0; i<= 7; i++)
snkkey[i] = NULL;
/* send messages to syslog */
openlog(argv[0], LOG_PID | LOG_CONS, LOG_AUTH);
while ((ch = getopt(argc, argv, "c:h:i:p")) != EOF) {
switch((char)ch) {
case 'c':
auth_class=optarg;
break;
case 'h':
hflag++;
from_host=optarg;
break;
case 'i':
iflag++;
from_ip=optarg;
break;
case 'p':
pflag++;
break;
case '?':
default:
break;
}
}
argc -= optind;
argv += optind;
if (argc)
user=argv[0];
/* check for hosts we allow directly in */
if (hflag)
secured+=allow(from_host, hosts_allow);
if (iflag)
secured+=allow(from_ip, ip_addr_allow);
/* restricted access line (remote) */
if (auth_class) {
struct passwd *pw=getpwnam(user);
if (pw && !strcmp(pw->pw_class, auth_class))
secured++;
}
sprintf(message, "Connection from %s (%s)\n",
from_host, from_ip);
fprintf(stderr, "%s", message);
syslog(LOG_NOTICE, message);
/* let some people straight through */
if (secured) {
syslog(LOG_NOTICE,
"Direct access allowed from %s (%s) for %s",
from_host, from_ip, user ? user : "(unknown)");
start_login(secured);
syslog(LOG_ERR,"Can't start login process: %m");
fprintf(stderr,"Problems starting %s...",
_PATH_LOGIN);
quit();
}
/* open the key file */
if ((in_file = fopen(_PATH_KEYFILE, "r")) == NULL) {
perror("keyfile");
syslog(LOG_ERR,"Can't open key file: %m");
fprintf(stderr,"Can't open the key file...");
quit();
}
/* SNK userid supplied on command line */
if (user) {
for (p=user; isalpha(*p) | isdigit(*p); p++);
*p='\0';
strncpy(id,user,sizeof(id));
} else { /* prompt and get the SNK userid */
for(id[0]='\0'; !strlen(id);) {
fprintf(stderr,"\nSNK login: ");
fflush(stderr);
if(setjmp(env) == 0) {
alarm(SNKTIMEOUT);
if (!fgets(id, sizeof(id), stdin))
quit();
alarm(0);
for (p=id; isalpha(*p) | is-
digit(*p); p++);
*p='\0';
} else {
fprintf(stderr,"Timeout...");
quit();
}
}
}
/* get the key associated with the userid and
put the key into snkkey */
while (fgets(message, sizeof(message), in_file) != NULL) {
sscanf(message, "%9s %o %o %o %o %o %o %o %o %x",
in_id, &oct1, &oct2, &oct3, &oct4,
&oct5, &oct6, &oct7, &oct8, &cksum);
if (strlen(in_id) && strncmp(in_id, "#", 1)) {
if ((ismatch(in_id, id))) {
snkkey[0] = oct1;
snkkey[1] = oct2;
snkkey[2] = oct3;
snkkey[3] = oct4;
snkkey[4] = oct5;
snkkey[5] = oct6;
snkkey[6] = oct7;
snkkey[7] = oct8;
break;
}
}
*in_id='\0';
}
fclose(in_file);
/* compute the challenge/response, give them the
challenge, and get the response from the user */
installkey(snkkey, pkey);
buildsnk(pkey, challenge, response);
fprintf(stderr,"Challenge is: %s\nEnter Response: ",
challenge);
if(setjmp(env) == 0) {
alarm(SNKTIMEOUT);
fgets(reply, sizeof(reply), stdin);
alarm(0);
for (p=reply; isalpha(*p) | isdigit(*p); p++);
*p='\0';
} else {
fprintf(stderr,"Timeout...");
quit();
}
for(i=0; i<=7; i++)
if(islower(reply[i]))
reply[i]=toupper(reply[i]);
/* if the reply the user gives doesn't match with the
response we compute, they're out of here! */
if ((strncmp(response, reply, 8)) != 0) {
syslog(LOG_NOTICE,
"Failed SNK login for %s from %s (%s).", id,
from_host, from_ip);
fprintf(stderr,"Incorrect response...");
quit();
} else {
start_login(secured);
syslog(LOG_ERR,"Can't start login process: %m");
fprintf(stderr,"Problems starting %s...",
_PATH_LOGIN);
}
quit();
}
timeout(sig)
int sig;
{
signal(sig, SIG_IGN);
signal(SIGALRM, timeout);
longjmp(env, 1);
}
/* check if something is on the list */
allow(who, list)
char *who;
char *list[];
{
char *p;
for (p=*list; p; p=*(++list)) {
if (!strcmp(who, p))
return(1);
}
return(0);
}
int ismatch (s1, s2)
char *s1, *s2;
{
if (strlen(s1) != strlen(s2))
return(0);
return(!strncmp(s1, s1, 8));
}
quit()
{
fprintf(stderr,"closing connection\n");
fflush(stderr);
exit(1);
}
/* start a normal login process */
start_login(secure)
int secure;
{
register char **argv;
char **addarg();
argv = addarg(0, "login");
if (hflag) {
argv = addarg(argv, "-h");
argv = addarg(argv, from_host);
}
if (pflag)
argv = addarg(argv, "-p");
if (user) {
if (secure) { /* only allow one login attempt */
argv = addarg(argv, "-m");
argv = addarg(argv, "1");
}
argv = addarg(argv, user);
} else
if (user=getenv("USER"))
/* special login id */
if (strcmp(SNKLOGIN, user))
argv = addarg(argv, user);
fprintf(stderr, "\n");
execv(_PATH_LOGIN, argv);
}
char **addarg(argv, val)
register char **argv;
register char *val;
{
register char **cpp;
if (argv == NULL) {
/*
* 10 entries, a leading length, and a null
*/
argv = (char **)malloc(sizeof(*argv) * 12);
if (argv == NULL)
return(NULL);
*argv++ = (char *)10;
*argv = (char *)0;
}
for (cpp = argv; *cpp; cpp++)
;
if (cpp == &argv[(int)argv[-1]]) {
--argv;
*argv = (char *)((int)(*argv) + 10);
argv = (char **)realloc(argv, (int)(*argv) + 2);
if (argv == NULL)
return(NULL);
argv++;
cpp = &argv[(int)argv[-1] - 10];
}
*cpp++ = val;
*cpp = 0;
return(argv);
}
/* end of snklogin.c */
|