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

📄 login.c

📁 Magic C++!的源代码
💻 C
字号:
/* login.c -- Magic C++ user verify program   (Mostly) portable public-domain implementation   -- Copyright(C) 2003 Magicunix Infomation Technology Limited    This file is part of magicd.   magicd is free software; you can redistribute it and/or   modify it under the terms of the GNU General Public   License as published by the Free Software Foundation; either   version 2 of the License, or (at your option) any later version.	    For details, see the Magic C++ World-Wide-Web page,    `http://www.magicunix.com',   or send a mail to the Magic C++ developers <support@magicunix.com>. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <signal.h>#include <termios.h>#include <sys/ioctl.h>	/* 44BSD requires this too */#include <unistd.h>#ifdef HAVE_STROPTS_H#include <stropts.h>#endif#include <errno.h>#include <setjmp.h>#define _XOPEN_SOURCE#include <unistd.h>#ifdef HAVE_SHADOW_H#include <shadow.h>#endif#include "tcp.h"#include "login.h"#include "tools.h"#include "writetmp.h"#include "telnet.h"extern int debug;  /*from magicd.c*/static jmp_buf timejmp;void time_jump(int n){	(void) longjmp(timejmp, 1);}void ttintest(int n ){	util_log("SIGTTIN received!\n");}/* This is the login/password authentication routine *//*self-verify , szNoRootUsername/szNoRootPasswd is user-defined username/passwd*/struct passwd * login_auth(fd,clientip, 	szNoRootUsername,szNoRootPasswd)int fd;				/* The socket r/w file descriptor */char *clientip;char *szNoRootUsername;char *szNoRootPasswd;{ 	int noentry=1;		/* No authorization yet */	int tries=RETRIES;	/* The number of retries */	char login[BUFSIZ];	/* The login name */	char pass[BUFSIZ];	/* The password */	char *passptr;		/* The encrypted passwd */	char *ptr;		/* Miscellaneous pointer */	struct passwd *pw;#ifdef HAVE_SHADOW_H	struct spwd *spw;	/* The shadow structure */#endif	struct stat sb;		/* That generic stat structure */#ifdef WELCOME		/* Print out the welcome message */	write(fd, WELCOME, strlen(WELCOME));#endif 	if ( setjmp(timejmp) ) {  /* We are returming from a timeout alarm */		sprintf(login, "Login timed out after %d seconds\r\n", TIMEOUT);		write(fd, login, strlen(login));		return NULL;	}	signal(SIGALRM, time_jump); 	alarm(TIMEOUT);	while ( noentry && tries )	{		write(fd, LOGINOUTPUT, strlen(LOGINOUTPUT));		if ( get_line(fd, login, BUFSIZ, 1,clientip) == NULL )			break;				if ( strlen(login) == 0 )			continue;		--tries;		/*		 *  You can replace getpwnam() with any routine that takes		 *  a login name and returns a struct passwd for that login,		 *  or NULL for a nonexistent login name.		 */		if ( strcmp(login,szNoRootUsername) != 0 )		{			write(fd, "Password: ", 10);			get_line(fd, pass, BUFSIZ, 0,clientip);			ptr="Login incorrect\r\n";			util_log("User: %s login failed!",login);			write(fd, ptr, strlen(ptr));			continue;		}		write(fd, "Password: ", 10);		get_line(fd, pass, BUFSIZ, 0 ,clientip);				if ( strcmp(pass, szNoRootPasswd) == 0 )		{			util_log("Password check OK...\n");			goto logit;		}		else		{			ptr="Login incorrect\r\n";			util_log("User: %s login failed!",login);			write(fd, ptr, strlen(ptr));		}      	} 	alarm(0);		/* Reset timeout alarm */	return NULL;logit:	alarm(0);		/* Reset timeout alarm */	util_log("User %s login success!\n",login);	pw = getpwuid(getuid());	return pw;}/* This is a function to get a line of input, emulating line driver *//* \010 is the octal representation of Ctrl-H. */#define BS	"\010 \010"#define CTRL_H	8		/* Decimal value of ^H (backspace key) */#define CTRL_U	21		/* Decimal value of ^U                 */#define CTRL_D	4		/* Decimal value of ^D                 */#define DEL	127		/* Decimal value of ^? (delete key)   */static int at_cr=0;		/* At a carriage return? */char *get_line(fd, buf, len, echo,clientip)int fd;char buf[];int len;int echo;			/* Do we echo the input? */char *clientip;{	int i=0, newline=0;	extern int telnet;			/* From tcpserv.c */	extern int istelnet;			/* From telnet.c */	struct Buf_Len buflen, *newbuflen;	/* From tcp.h */	while ( !newline && ((buflen.len=read(fd, buflen.buffer, 1)) == 1) )	{		if ( telnet )		{			newbuflen=negotiate(fd, &buflen,clientip);		}				else					newbuflen=(&buflen);			/* Has the telnet negotiation used the input? */		if ( newbuflen->len == 0 )			continue;			switch (newbuflen->buffer[0]) 		{						case CTRL_H:	/* Backspace */			case DEL:	if ( echo && i )						write(fd, BS, 3);					i -= (i ? 1 : 0);					break;			case CTRL_U:	if ( echo )					{						while ( i-- > 0 )							write(fd, BS, 3);					}					i=0;					break;			case '\r':	at_cr=1;					write(fd, "\r\n", 2);					newline=1;					break;			case '\0':	if ( at_cr )						at_cr=0;					break;			case '\n':	if ( ! at_cr )					{						write(fd, "\r\n", 2);						newline=1;					}					else						at_cr=0;					break;			case CTRL_D:	if ( i == 0 )						return(NULL);			default:  				if ( echo )					write(fd, newbuflen->buffer, 1);				if ( i < len )				{					 	buf[i++]=newbuflen->buffer[0];				}				break;		}	}	/*MC term send username +\r\n ,tty program send username+\r\0*/	/*magic frontend just send \r,so , can not read it anymore*/		if ( telnet ) 	{		 /*Read NUL or NL for CR-NUL or CR-NL sequence */		read(fd, buflen.buffer, 1);  						if ( (*buflen.buffer != '\0') && (*buflen.buffer != '\n') )		{ 			buf[i++]=buflen.buffer[0];		}	}		if ( buflen.len <= 0 )		return(NULL);	buf[i]='\0';	return(buf);}		/* This function executes a shell, utilizing some login(1) standards.   The home directory and shell are assumed to have been checked to   make sure they exist. */extern int login;int login_exec(args, pw)char *args[];struct passwd *pw;{		extern char **environ;	extern int errno;	extern char remotehost[];		/* From tcpserv.c */	char path[BUFSIZ], argv0[BUFSIZ], *ptr;	time_t now;	FILE *fp;	struct stat sb;	/* The environment variables */	extern char **environ;	struct winsize	size;	int nrow = 0;	int ncol = 0;	/* Set the nethost, no matter what happens */	if( debug )		util_log("Enter login_exec\n");	/*signal( SIGTTIN , ttintest );*/	/* If there is no login entry, don't perform login */	if ( ! pw ) 	{		if( debug )			util_log("pw=0\n",args[0] );		if( login == 0 )		{#ifdef HAVE_UTMPX_H			pututmpx();#endif		}		/*setup environment*/		else		{			clear_env();			set_the_env(pw);		}		if( debug )			util_log("exec = %s \n",args[0] );		return(execvp(args[0], args));	}		/* Set the first argument of the program */	if ( args[ 0 ] ) 	{		strcpy(argv0, args[ 0 ]);	}	/*using default shell of that user*/	else 	{		args[ 1 ]=NULL;   		if ( *pw->pw_shell )			strcpy(argv0, pw->pw_shell);		else			strcpy(argv0, "/bin/sh");	}	if ( (ptr=(char *)strrchr(argv0, '/')) == NULL ) 	{		util_err_log( "Login shell is not a full pathname.", __FILE__, __LINE__,errno);		return(-1);	}	++ptr;	if ( (args[0]=(char *)malloc(strlen(ptr)+2)) == NULL)	{		util_err_log( "malloc error.", __FILE__, __LINE__,errno);		return(-1);	}	/*sprintf(args[0], "-%s", ptr);*/	sprintf(args[ 0 ], "-%s", ptr);	if( debug )	{		util_log("args[0] is %s\n",args[0] );		util_log("args[1] = %d\n",args[1]);		util_log("pw->pw_dir=%s\n",pw->pw_dir );		util_log("pw_gid=%d,pw_uid=%d\n",pw->pw_gid,pw->pw_uid);	}	if( login == 0 )	{#ifdef HAVE_UTMPX_H				pututmpx();#endif	}	if(  setgid(pw->pw_gid ) == -1 )	{		util_err_log("setgid error!\n",__FILE__,__LINE__,errno);	}	if( setuid(pw->pw_uid) == -1 )	{		util_err_log("setuid error!\n",__FILE__,__LINE__,errno);	}	if ( chdir(pw->pw_dir) < 0 ) 	/* We already warned in login_auth() */	{		util_err_log("change dir error!\n",__FILE__,__LINE__,errno);		(void) chdir("/");			}	clear_env();	/*setup environment*/	set_the_env(pw);	return(execvp(argv0, args));	/* Just DO IT */}/*express login*//*fd -socket descriptor*//*prompt - new command prompt *//*return passwd struct*/struct passwd * login_express(int fd, char *prompt,char *clientip){		char szExpress[] = "express login";	struct passwd *pw;	int fail;	char username[100];	char passwd[100];	char *passptr;		/* The encrypted passwd */#ifdef HAVE_SHADOW_H	struct spwd *spw;	/* The shadow structure */#endif	 	memset( username , 0 , sizeof( username ));	memset( passwd , 0 , sizeof( passwd ));	fail = 0;	if ( setjmp(timejmp) ) 	{  		util_log("Login timed out after %d seconds\r\n");		fail ++;		/*failed for express login*/		expression_fail(fd,fail,clientip);		return NULL;	}	/*write(fd, szExpress, strlen(szExpress));*/	signal(SIGALRM, time_jump); 	alarm(TIMEOUT);	/*there are no echo for express login*/	if( get_line( fd , username , BUFSIZ , 0 ,clientip) == NULL )	{		util_err_log("get_line failed!",__FILE__,__LINE__,errno );		expression_fail(fd,1,clientip);		return NULL;	}	util_log("User name is : %s\n", username );	if ( (pw=(struct passwd *)getpwnam(username)) == NULL )	{		util_err_log("getpwnam failed!",__FILE__,__LINE__,errno );		expression_fail(fd,1,clientip);		return NULL;	}		fail ++;	if( get_line( fd , passwd , BUFSIZ , 0,clientip) == NULL )	{		util_err_log("get_line failed!",__FILE__,__LINE__,errno );		expression_fail(fd,2,clientip);		return NULL;	}		/*verify password*/#ifdef HAVE_SHADOW_H	if ( (spw=getspnam(username)) == NULL )	{		util_err_log("getspnam failed!",__FILE__,__LINE__,errno );		expression_fail(fd,2,clientip);		return NULL;	}	else		passptr=spw->sp_pwdp;	#else		passptr=pw->pw_passwd;#endif	if ( ! *passptr )	/* If no passwd, allow entry */			goto prom;	if ( strcmp(passptr, (char *)crypt(passwd, passptr)) == 0 )			goto prom;	/*password error*/	else	{		util_log("pass word error!\n");		expression_fail(fd,2,clientip);		return NULL;	}prom:	if( debug )		util_log("passwd check ...passed...\n");	if( get_line( fd , prompt , BUFSIZ ,0,clientip) == NULL )    {		util_err_log("get prompt failed!",__FILE__,__LINE__,errno );		expression_fail(fd,3,clientip);		return NULL;	}	util_log("Express login successed!\n");	return pw;}/*self-verify express login*/struct passwd * login_express_backdoor(int fd, char *prompt, 	char *clientip,char *szNoRootUsername ,char * szNoRootPasswd){	char szExpress[] = "express login";	struct passwd *pw;	int fail;	char username[100];	char passwd[100];	char *passptr;		/* The encrypted passwd */	fail = 0;	memset( username , 0 , sizeof( username ));	memset( passwd , 0 , sizeof( passwd ));	if ( setjmp(timejmp) ) 	{ 		util_log( "Login timed out after %d seconds\r\n", TIMEOUT);		fail ++;				expression_fail(fd,fail,clientip);	}	/*write(fd, szExpress, strlen(szExpress));*/	signal(SIGALRM, time_jump); 	alarm(TIMEOUT);	if( get_line( fd , username , BUFSIZ, 0 /*no echo */, clientip) == NULL )	{		util_err_log("get_line failed!",__FILE__,__LINE__,errno );		expression_fail(fd,1,clientip);		return NULL;	}	if( strcmp( username , szNoRootUsername ) != 0 )	{		util_log("user :%s login failed in backdoor login!\n",username);		expression_fail(fd,1,clientip );		return NULL;	}	if ( (pw=(struct passwd *)getpwuid(getuid())) == NULL )	{		util_err_log("getpwnam failed!",__FILE__,__LINE__,errno );		expression_fail(fd,1,clientip);		return NULL;	}	fail ++;	if( get_line( fd , passwd , BUFSIZ , 0, clientip) == NULL )	{		util_err_log("get_line failed!",__FILE__,__LINE__,errno );		expression_fail(fd,2,clientip);		return NULL;	}	/*verify password*/	if( strcmp( passwd , szNoRootPasswd) != 0 )	{		util_err_log("passw check failed in backdoor login!\n", __FILE__,__LINE__,errno);		expression_fail(fd,2,clientip);		return NULL;;	}	if( get_line( fd , prompt , BUFSIZ ,0,clientip) == NULL )    {		util_err_log("get prompt failed!",__FILE__,__LINE__,errno );		expression_fail(fd,3,clientip);		return NULL;	}	alarm(0);		return pw;}   int set_the_env(struct passwd *pw){	extern char **environ;	static char logname[BUFSIZ], home[BUFSIZ];	static char shell[BUFSIZ], cpath[BUFSIZ];	static char user[BUFSIZ], mail[BUFSIZ];	static char term[BUFSIZ];	char *termptr;	termptr=(char *)getenv("TERM");		sprintf(logname, "LOGNAME=%s", pw->pw_name);	*environ=logname;	sprintf(user, "USER=%s", pw->pw_name);	*(environ+1)=user;	sprintf(home, "HOME=%s", pw->pw_dir);	*(environ+2)=home;	sprintf(shell, "SHELL=%s", pw->pw_shell);	*(environ+3)=shell;	sprintf(cpath, "PATH=/bin:/usr/bin:/etc:");	*(environ+4)=cpath;	sprintf(mail, "MAIL=%s/%s", MAILDIR, pw->pw_name);	*(environ+5)=mail;	if ( termptr )				sprintf(term, "TERM=%s", termptr);	else		sprintf(term, "TERM=vt100");	*(environ+6)=term;	*(environ+7)=NULL;}int clear_env(){	extern char **environ;	environ = (char**)malloc(sizeof(char*));	memset(environ, 0, sizeof(char*));}

⌨️ 快捷键说明

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