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

📄 su.c

📁 一次性口令认证系统SKEY的实现
💻 C
字号:
/* * Copyright (c) 1980 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[] = "@(#)su.c	5.5 (Berkeley) 1/18/87";#endif not lint#include <stdio.h>#include <pwd.h>#include <grp.h>#include <syslog.h>#include <sys/types.h>#include <sys/time.h>#include <sys/resource.h>#include <sgtty.h>#include <fcntl.h>#include "skey.h"char	userbuf[16]	= "USER=";char	homebuf[128]	= "HOME=";char	shellbuf[128]	= "SHELL=";char	pathbuf[128]	= "PATH=:/usr/ucb:/bin:/usr/bin";char	*cleanenv[] = { userbuf, homebuf, shellbuf, pathbuf, 0, 0 };char	*user = "root";char	*shell = "/bin/sh";int	fulllogin;int	fastlogin;extern char	**environ;struct	passwd *pwd;char	*crypt();char	*getpass();char	*getenv();char	*getlogin();main(argc,argv)	int argc;	char *argv[];{	char *password;	char buf[1000];	FILE *fp;	register char *p;	struct skey skey;	int i;	char *pp;	void rip();	char pbuf[256];	char skeyprompt[80];	struct sgttyb ttyf,ttysave;	int fflags,lword,lwordsav;	openlog("su", LOG_ODELAY, LOG_AUTH);again:	if (argc > 1 && strcmp(argv[1], "-f") == 0) {		fastlogin++;		argc--, argv++;		goto again;	}	if (argc > 1 && strcmp(argv[1], "-") == 0) {		fulllogin++;		argc--, argv++;		goto again;	}	if (argc > 1 && argv[1][0] != '-') {		user = argv[1];		argc--, argv++;	}	if ((pwd = getpwuid(getuid())) == NULL) {		fprintf(stderr, "Who are you?\n");		exit(1);	}	strcpy(buf, pwd->pw_name);	if ((pwd = getpwnam(user)) == NULL) {		fprintf(stderr, "Unknown login: %s\n", user);		exit(1);	}	/*	 * Only allow those in group zero to su to root.	 */	if (pwd->pw_uid == 0) {		struct	group *gr;		int i;		if ((gr = getgrgid(0)) != NULL) {			for (i = 0; gr->gr_mem[i] != NULL; i++)				if (strcmp(buf, gr->gr_mem[i]) == 0)					goto userok;			fprintf(stderr, "You do not have permission to su %s\n",				user);			exit(1);		}	userok:		setpriority(PRIO_PROCESS, 0, -2);	}#define Getlogin()  (((p = getlogin()) && *p) ? p : buf)	if (pwd->pw_passwd[0] == '\0' || getuid() == 0)		goto ok;#ifdef	OLD	password = getpass("Password:");	if (strcmp(pwd->pw_passwd, crypt(password, pwd->pw_passwd)) != 0) {		fprintf(stderr, "Sorry\n");		if (pwd->pw_uid == 0) {			syslog(LOG_CRIT, "BAD SU %s on %s",					Getlogin(), ttyname(2));		}		exit(2);	}#endif	/* Attempt a S/Key challenge */	i = skeychallenge(&skey,user,skeyprompt);	printf("%s\n",skeyprompt);	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(pbuf,sizeof(pbuf),stdin);	rip(pbuf);	if(strlen(pbuf) == 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(pbuf,sizeof(pbuf),stdin);		rip(pbuf);	} 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,pbuf) == 0){		/* S/Key authentication succeeded */		if(skey.n < 5)			printf("Warning! Change password soon\n");		goto ok;	} else {		/* Try regular password check */		pp = crypt(pbuf,pwd->pw_passwd);		if(strcmp(pp,pwd->pw_passwd) == 0)			goto ok;	/* Success */	}	fprintf(stderr, "Sorry\n");	if (pwd->pw_uid == 0) {		syslog(LOG_CRIT, "BAD SU %s on %s",				Getlogin(), ttyname(2));	}	exit(2);ok:	endpwent();	if (pwd->pw_uid == 0) {		syslog(LOG_NOTICE, "%s on %s", Getlogin(), ttyname(2));		closelog();	}	if (setgid(pwd->pw_gid) < 0) {		perror("su: setgid");		exit(3);	}	if (initgroups(user, pwd->pw_gid)) {		fprintf(stderr, "su: initgroups failed\n");		exit(4);	}	if (setuid(pwd->pw_uid) < 0) {		perror("su: setuid");		exit(5);	}	if (pwd->pw_shell && *pwd->pw_shell)		shell = pwd->pw_shell;	if (fulllogin) {		cleanenv[4] = getenv("TERM");		environ = cleanenv;	}	if (fulllogin || strcmp(user, "root") != 0)		setenv("USER", pwd->pw_name, userbuf);	setenv("SHELL", shell, shellbuf);	setenv("HOME", pwd->pw_dir, homebuf);	setpriority(PRIO_PROCESS, 0, 0);	if (fastlogin) {		*argv-- = "-f";		*argv = "su";	} else if (fulllogin) {		if (chdir(pwd->pw_dir) < 0) {			fprintf(stderr, "No directory\n");			exit(6);		}		*argv = "-su";	} else		*argv = "su";	execv(shell, argv);	fprintf(stderr, "No shell\n");	exit(7);}setenv(ename, eval, buf)	char *ename, *eval, *buf;{	register char *cp, *dp;	register char **ep = environ;	/*	 * this assumes an environment variable "ename" already exists	 */	while (dp = *ep++) {		for (cp = ename; *cp == *dp && *cp; cp++, dp++)			continue;		if (*cp == 0 && (*dp == '=' || *dp == 0)) {			strcat(buf, eval);			*--ep = buf;			return;		}	}}char *getenv(ename)	char *ename;{	register char *cp, *dp;	register char **ep = environ;	while (dp = *ep++) {		for (cp = ename; *cp == *dp && *cp; cp++, dp++)			continue;		if (*cp == 0 && (*dp == '=' || *dp == 0))			return (*--ep);	}	return ((char *)0);}

⌨️ 快捷键说明

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