⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 login.c

📁 一次性口令认证系统SKEY的实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1980,1987 Regents of the University of California. * All rights reserved.  The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */#ifndef lintchar copyright[] ="@(#) Copyright (c) 1980 Regents of the University of California.\n\ All rights reserved.\n";#endif not lint#ifndef lintstatic char sccsid[] = "@(#)login.c	5.20 (Berkeley) 10/1/87";#endif not lint/* * login [ name ] * login -r hostname	(for rlogind) * login -h hostname	(for telnetd, etc.) * login -f name	(for pre-authenticated login: datakit, xterm, etc.) */#include <sys/param.h>#ifdef	QUOTA#include <sys/quota.h>#endif#include <sys/stat.h>#include <sys/time.h>#include <sys/resource.h>#include <sys/file.h>#include <sgtty.h>#include <utmp.h>#include <signal.h>#include <pwd.h>#include <stdio.h>#include <lastlog.h>#include <errno.h>#include <ttyent.h>#include <syslog.h>#include <grp.h>#include <netdb.h>#include "skey.h"#define TTYGRPNAME	"tty"		/* name of group to own ttys */#define TTYGID(gid)	tty_gid(gid)	/* gid that owns all ttys */#define	SCMPN(a, b)	strncmp(a, b, sizeof(a))#define	SCPYN(a, b)	strncpy(a, b, sizeof(a))#define NMAX	sizeof(utmp.ut_name)#define HMAX	sizeof(utmp.ut_host)#define	FALSE	0#define	TRUE	-1char	nolog[] =	"/etc/nologin";char	qlog[]  =	".hushlogin";char	maildir[30] =	"/usr/spool/mail/";char	lastlog[] =	"/usr/adm/lastlog";struct	passwd nouser = {"", "#nope", -1, -1, "", "", "", "", "" };struct	sgttyb ttyb;struct	utmp utmp;char	minusnam[16] = "-";char	*envinit[1];			/* now set by setenv calls *//* * This bounds the time given to login.  We initialize it here * so it can be patched on machines where it's too small. */int	timeout = 300;char	term[64];struct	passwd *pwd;char	*strcat(), *rindex(), *index();int	timedout();char	*ttyname();char	*crypt();char	*getpass();char	*stypeof();extern	int errno;struct	tchars tc = {	CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK};struct	ltchars ltc = {	CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT};struct winsize win = { 0, 0, 0, 0 };int	rflag;int	usererr = -1;char	rusername[NMAX+1], lusername[NMAX+1];char	rpassword[NMAX+1];char	name[NMAX+1];char	me[MAXHOSTNAMELEN];char	*rhost;main(argc, argv)	char *argv[];{	extern	char **environ;	register char *namep;	int pflag = 0, hflag = 0, fflag = 0, t, f, c;	int invalid, quietlog;	FILE *nlfd;	char *ttyn, *tty, host[256];	int ldisc = 0, zero = 0, i;	char *p, *domain, *index();	char skeyprompt[80];	int pwok;	host[0] = '\0';	skeyprompt[0] = '\0';	signal(SIGALRM, timedout);	alarm(timeout);	signal(SIGQUIT, SIG_IGN);	signal(SIGINT, SIG_IGN);	setpriority(PRIO_PROCESS, 0, 0);#ifdef	QUOTA	quota(Q_SETUID, 0, 0, 0);#endif	/*	 * -p is used by getty to tell login not to destroy the environment	 * -r is used by rlogind to cause the autologin protocol; 	 * -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	 */	(void) gethostname(me, sizeof(me));	domain = index(me, '.');	while (argc > 1) {		if (strcmp(argv[1], "-r") == 0) {			if (rflag || hflag || fflag) {				printf("Other options not allowed with -r\n");				exit(1);			}			if (argv[2] == 0)				exit(1);			rflag = 1;			usererr = doremotelogin(argv[2]);			strncpy(host,argv[2],sizeof(host));			if (domain != NULL && (p = index(argv[2], '.')) && strcmp(p, domain) == 0)				*p = 0;			SCPYN(utmp.ut_host, argv[2]);			argc -= 2;			argv += 2;			continue;		}		if (strcmp(argv[1], "-h") == 0) {			if (getuid() == 0) {				if (rflag || hflag) {				    printf("Only one of -r and -h allowed\n");				    exit(1);				}				hflag = 1;				strncpy(host,argv[2],sizeof(host));				if (domain != NULL && (p = index(argv[2], '.')) &&				    strcmp(p, domain) == 0)					*p = 0;				SCPYN(utmp.ut_host, argv[2]);			}			argc -= 2;			argv += 2;			continue;		}		if (strcmp(argv[1], "-f") == 0 && argc > 2) {			if (rflag) {				printf("Only one of -r and -f allowed\n");				exit(1);			}			fflag = 1;			SCPYN(utmp.ut_name, argv[2]);			argc -= 2;			argv += 2;			continue;		}		if (strcmp(argv[1], "-p") == 0) {			argc--;			argv++;			pflag = 1;			continue;		}		break;	}	ioctl(0, TIOCLSET, &zero);	ioctl(0, TIOCNXCL, 0);	ioctl(0, FIONBIO, &zero);	ioctl(0, FIOASYNC, &zero);	ioctl(0, TIOCGETP, &ttyb);	/*	 * If talking to an rlogin process,	 * propagate the terminal type and	 * baud rate across the network.	 */	if (rflag)		doremoteterm(term, &ttyb);	ttyb.sg_erase = CERASE;	ttyb.sg_kill = CKILL;	ioctl(0, TIOCSLTC, &ltc);	ioctl(0, TIOCSETC, &tc);	ioctl(0, TIOCSETP, &ttyb);	for (t = getdtablesize(); t > 2; t--)		close(t);	ttyn = ttyname(0);	if (ttyn == (char *)0 || *ttyn == '\0')		ttyn = "/dev/tty??";	tty = rindex(ttyn, '/');	if (tty == NULL)		tty = ttyn;	else		tty++;	openlog("login", LOG_ODELAY, LOG_AUTH);	t = 0;	invalid = FALSE;	pwok = authfile(host);	do {		ldisc = 0;		ioctl(0, TIOCSETD, &ldisc);		if (fflag == 0)			SCPYN(utmp.ut_name, "");		/*		 * Name specified, take it.		 */		if (argc > 1) {			SCPYN(utmp.ut_name, argv[1]);			argc = 0;		}		/*		 * If remote login take given name,		 * otherwise prompt user for something.		 */		if (rflag && !invalid)			SCPYN(utmp.ut_name, lusername);		else {			getloginname(&utmp);			if (utmp.ut_name[0] == '-') {				puts("login names may not start with '-'.");				invalid = TRUE;				continue;			}		}		invalid = FALSE;		if (!strcmp(pwd->pw_shell, "/bin/csh")) {			ldisc = NTTYDISC;			ioctl(0, TIOCSETD, &ldisc);		}		if (fflag) {			int uid = getuid();			if (uid != 0 && uid != pwd->pw_uid)				fflag = 0;			/*			 * Disallow automatic login for root.			 */			if (pwd->pw_uid == 0)				fflag = 0;		}		/*		 * If no remote login authentication and		 * a password exists for this user, prompt		 * for one and verify it.		 */		if (usererr == -1 && fflag == 0 && *pwd->pw_passwd != '\0') {			char *pp;			struct skey skey;			int i;			char buf[256],*cp;			void rip();			struct sgttyb ttyf,ttysave;			int fflags,lword,lwordsav;#ifdef	OLD			setpriority(PRIO_PROCESS, 0, -4);			pp = getpass("Password:");			namep = crypt(pp, pwd->pw_passwd);			setpriority(PRIO_PROCESS, 0, 0);			if (strcmp(namep, pwd->pw_passwd))				invalid = TRUE;#endif			invalid = TRUE;	/* Guilty til proven innocent */			if(feof(stdin)) exit(0) ;			/* Attempt a s/key challenge */			i = skeychallenge(&skey,utmp.ut_name, skeyprompt);			printf("%s\n",skeyprompt);			if(!pwok)				printf("(s/key required)\n");			printf("Password:");			fflush(stdout);			/* Set normal line editing */			fflags = fcntl(fileno(stdin),F_GETFL,0);			fcntl(fileno(stdin),F_SETFL,fflags & ~FNDELAY);			ioctl(fileno(stdin),TIOCLGET,&lword);			ioctl(fileno(stdin),TIOCLGET,&lwordsav);			lword |= LCRTERA|LCRTKIL;			ioctl(fileno(stdin),TIOCLSET,&lword);			/* Turn off echoing */			ioctl(fileno(stdin), TIOCGETP, &ttyf);			ioctl(fileno(stdin), TIOCGETP, &ttysave);			ttyf.sg_flags &= ~(ECHO|RAW|CBREAK);			ttyf.sg_flags |= CRMOD;			ioctl(fileno(stdin),TIOCSETP,&ttyf);						/* Read password */			fgets(buf,sizeof(buf),stdin);			rip(buf);			if(feof(stdin)) exit(0);			if(strlen(buf) == 0){				/* Null line entered; turn echoing back on				 * and read again				 */				printf(" (echo on)\nPassword:");				fflush(stdout);				ttyf.sg_flags |= (ECHO|CRTBS);				ioctl(fileno(stdin),TIOCSETP,&ttyf);				fgets(buf,sizeof(buf),stdin);				rip(buf);				if(feof(stdin)) exit(0);			} else {				printf("\n");			}			/* Restore previous tty modes */			fcntl(fileno(stdin),F_SETFL,fflags);			ioctl(fileno(stdin),TIOCSETP,&ttysave);			ioctl(fileno(stdin),TIOCLSET,&lwordsav);			if(i == 0 && skeyverify(&skey,buf) == 0 && 				(pwd->pw_passwd[0] != '*' && pwd->pw_passwd[0] != '#' ) ){				/* S/Key authentication succeeded */				if(skey.n < 5)					printf("Warning! Change password soon\n");				invalid = FALSE;			} else if(pwok){				/* Try regular password check, if allowed */				pp = crypt(buf,pwd->pw_passwd);				if(strcmp(pp,pwd->pw_passwd) == 0)					invalid = FALSE; /* Success */			}		}		/*		 * If user not super-user, check for logins disabled.		 */		if (pwd->pw_uid != 0 && (nlfd = fopen(nolog, "r")) > 0) {			while ((c = getc(nlfd)) != EOF)				putchar(c);			fflush(stdout);			sleep(5);			exit(0);		}		/*		 * If valid so far and root is logging in,		 * see if root logins on this terminal are permitted.		 */		if (!invalid && pwd->pw_uid == 0 && !rootterm(tty)) {			if (utmp.ut_host[0])				syslog(LOG_CRIT,				    "ROOT LOGIN REFUSED ON %s FROM %.*s",				    tty, HMAX, utmp.ut_host);			else				syslog(LOG_CRIT,				    "ROOT LOGIN REFUSED ON %s", tty);			invalid = TRUE;		}		if (invalid) {			printf("Login incorrect\n");			if (++t >= 5) {				if (utmp.ut_host[0])					syslog(LOG_ERR,			    "REPEATED LOGIN FAILURES ON %s FROM %.*s, %.*s",					    tty, HMAX, utmp.ut_host,					    NMAX, utmp.ut_name);				else					syslog(LOG_ERR,				    "REPEATED LOGIN FAILURES ON %s, %.*s",						tty, NMAX, utmp.ut_name);				ioctl(0, TIOCHPCL, (struct sgttyb *) 0);				close(0), close(1), close(2);				sleep(10);				exit(1);			}		}		if (*pwd->pw_shell == '\0')			pwd->pw_shell = "/bin/sh";		if (chdir(pwd->pw_dir) < 0 && !invalid ) {			if (chdir("/") < 0) {				printf("No directory!\n");				invalid = TRUE;			} else {				printf("No directory! %s\n",				   "Logging in with home=/");				pwd->pw_dir = "/";			}		}		/*		 * Remote login invalid must have been because		 * of a restriction of some sort, no extra chances.		 */		if (!usererr && invalid)			exit(1);	} while (invalid);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -