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

📄 login.c++

📁 fax相关的东西
💻 C++
字号:
/*	$Id: Login.c++,v 1.12 2006/03/27 21:36:28 aidan Exp $ *//* * Copyright (c) 1995-1996 Sam Leffler * Copyright (c) 1995-1996 Silicon Graphics, Inc. * HylaFAX is a trademark of Silicon Graphics * * Permission to use, copy, modify, distribute, and sell this software and  * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. *  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.   *  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE  * OF THIS SOFTWARE. */#include "HylaFAXServer.h"#include "Sys.h"#include <unistd.h>#include <ctype.h>#include <fcntl.h>#include <pwd.h>#if HAS_CRYPT_H#include <crypt.h>#endifvoidHylaFAXServer::loginRefused(const char* why){    if (++loginAttempts >= maxLoginAttempts) {	reply(530, "Login incorrect (closing connection).");	logNotice("Repeated login failures for user %s from %s [%s]"	    , (const char*) the_user	    , (const char*) remotehost	    , (const char*) remoteaddr	);	dologout(0);    } else {	reply(530, "User %s access denied.", (const char*) the_user);	logNotice("HylaFAX LOGIN REFUSED (%s) FROM %s [%s], %s"	    , why	    , (const char*) remotehost	    , (const char*) remoteaddr	    , (const char*) the_user	);    }}/* * USER command. Sets global passwd state if named * account exists and is acceptable; sets askpasswd if a * PASS command is expected.  If logged in previously, * need to reset state.  User account must be accessible * from client host according to the contents of the * userAccessFile. */voidHylaFAXServer::userCmd(const char* name){    if (IS(LOGGEDIN)) {	if (IS(PRIVILEGED) && the_user == name) {// revert to unprivileged mode	    state &= ~S_PRIVILEGED;	    reply(230, "User %s logged in.", name);	    return;	}        end_login();    }    the_user = name;    state &= ~S_PRIVILEGED;    adminwd = "*";			// make sure no admin privileges    passwd = "*";			// just in case...    if (checkUser(name)) {	if (passwd != "") {	    state |= S_WAITPASS;	    reply(331, "Password required for %s.", name);	    /*	     * Delay before reading passwd after first failed	     * attempt to slow down password-guessing programs.	     */	    if (loginAttempts)		sleep(loginAttempts);	} else	    login(230);    } else	loginRefused("user denied");}#ifdef HAVE_PAMintpamconv(int num_msg, STRUCT_PAM_MESSAGE **msg, struct pam_response **resp, void *appdata){	char *password =(char*) appdata;	struct pam_response* replies;	if (num_msg != 1 || msg[0]->msg_style != PAM_PROMPT_ECHO_OFF)	    return PAM_CONV_ERR;	if (password == NULL)	    /*	     * Solaris doesn't have PAM_CONV_AGAIN defined.	     */	    #ifdef PAM_CONV_AGAIN		return PAM_CONV_AGAIN;	    #else		return PAM_CONV_ERR;	    #endif	replies=(struct pam_response*)calloc(num_msg, sizeof(struct pam_response));	replies[0].resp = strdup(password);	replies[0].resp_retcode = 0;	*resp = replies;	return PAM_SUCCESS;}#endif //HAVE_PAMboolHylaFAXServer::pamIsAdmin(const char* user){	bool retval = false;#ifdef HAVE_PAM	int i;	static struct group* grinfo = getgrnam(admingroup);	const char *curruser = (user == NULL ? the_user.c_str() : user);	if (grinfo != NULL) {		for (i=0; grinfo->gr_mem[i] != NULL; i++) {			if (strcmp(curruser, grinfo->gr_mem[i]) == 0) retval = true;		}	}#endif //HAVE_PAM	return(retval);}boolHylaFAXServer::pamCheck(const char* user, const char* pass){	bool retval = false;#ifdef HAVE_PAM	if (pamh == NULL)	    return false;	if (user == NULL) user = the_user;	if (pass == NULL) pass = passwd.c_str();	struct pam_conv conv = {		pamconv,		(void*)pass	};       	int pamret;	/*	 * Solaris has proprietary pam_[sg]et_item() extension.	 * Sun defines PAM_MSG_VERSION therefore is possible to use	 * it in order to recognize the extensions of Solaris	 */	#ifdef PAM_MSG_VERSION	    pamret = pam_set_item(pamh, PAM_CONV, (const void *)&conv);	#else	    pamret = pam_set_item(pamh, PAM_CONV, &conv);	#endif	if (pamret == PAM_SUCCESS)	    pamret = pam_authenticate(pamh, 0);	if (pamret == PAM_SUCCESS)	    pamret = pam_acct_mgmt(pamh, 0);	if (pamret == PAM_SUCCESS)		retval = true;	pamEnd(pamret);#endif	return retval;}void HylaFAXServer::pamEnd(int pamret){#ifdef HAVE_PAM    if (pamret == PAM_SUCCESS)    {	if (pamIsAdmin())	    state |= S_PRIVILEGED;	char *newname=NULL;	/*	 * Solaris has proprietary pam_[sg]et_item() extension.	 * Sun defines PAM_MSG_VERSION therefore is possible to use	 * it in order to recognize the extensions of Solaris	 */	#ifdef PAM_MSG_VERSION	    pamret = pam_get_item(pamh, PAM_USER, (void **)&newname);	#else	    pamret = pam_get_item(pamh, PAM_USER, (const void **)&newname);	#endif	if (pamret == PAM_SUCCESS && newname != NULL)	    the_user = strdup(newname);	struct passwd* uinfo=getpwnam((const char *)the_user);	if (uinfo != NULL) {	    uid = uinfo->pw_uid;	}	    }    pamret = pam_end(pamh, pamret);    pamh = NULL;#endif //HAVE_PAM}voidHylaFAXServer::passCmd(const char* pass){    if (IS(LOGGEDIN)) {        reply(503, "Already logged in as USER %s.", (const char*) the_user);        return;    }    if (!IS(WAITPASS)) {        reply(503, "Login with USER first.");        return;    }    state &= ~S_WAITPASS;    /*     * Disable long reply messages for old (broken) FTP     * clients if the first character of the password     * is a ``-''.     */    if (pass[0] == '-') {	state &= ~S_LREPLIES;	pass++;    } else	state |= S_LREPLIES;    if (pass[0] == '\0' || !(strcmp(crypt(pass, passwd), passwd) == 0 || pamCheck(the_user, pass))) {	if (++loginAttempts >= maxLoginAttempts) {	    reply(530, "Login incorrect (closing connection).");	    logNotice("Repeated login failures for user %s from %s [%s]"		, (const char*) the_user		, (const char*) remotehost		, (const char*) remoteaddr	    );	    dologout(0);	}	reply(530, "Login incorrect.");	logInfo("Login failed from %s [%s], %s"	    , (const char*) remotehost	    , (const char*) remoteaddr	    , (const char*) the_user	);	return;    }    login(230);}/* * Login is shared between SNPP and HylaFAX RFC 959 protocol, * but different protocols use different codes for success. * We make the caller tell us what success is. */voidHylaFAXServer::login(int code){    loginAttempts = 0;		// this time successful    state |= S_LOGGEDIN;    uid_t ouid = geteuid();    (void) seteuid(0);    bool isSetup = (chroot(".") >= 0 && chdir("/") >= 0);    /*     * Install the client's fax-uid as the effective gid     * so that created files automatically are given the     * correct ``ownership'' (we store the owner's fax-uid     * in the group-id field of the inode).     */    if (isSetup)	(void) setegid(uid);    (void) seteuid(ouid);    if (!isSetup) {	reply(550, "Cannot set privileges.");	end_login();	return;    }#ifdef HAVE_PAM    pam_chrooted = true;#endif    (void) isShutdown(false);	// display any shutdown messages    reply(code, "User %s logged in.", (const char*) the_user);    if (TRACE(LOGIN))	logInfo("FAX LOGIN FROM %s [%s], %s"	    , (const char*) remotehost	    , (const char*) remoteaddr	    , (const char*) the_user	);    (void) umask(077);    if (tracingLevel & (TRACE_INXFERS|TRACE_OUTXFERS))        xferfaxlog = Sys::open(xferfaxLogFile, O_WRONLY|O_APPEND|O_CREAT, 0600);    initDefaultJob();		// setup connection-related state    dirSetup();			// initialize directory handling	if (pamIsAdmin()) state |= S_PRIVILEGED;}voidHylaFAXServer::adminCmd(const char* pass){    fxAssert(IS(LOGGEDIN), "ADMIN command permitted when not logged in");    // NB: null adminwd is permitted    if ((strcmp(crypt(pass, adminwd), adminwd) != 0) && !pamIsAdmin()) {	if (++adminAttempts >= maxAdminAttempts) {	    reply(530, "Password incorrect (closing connection).");	    logNotice("Repeated admin failures from %s [%s]"		, (const char*) remotehost		, (const char*) remoteaddr	    );	    dologout(0);	} else {	    reply(530, "Password incorrect.");	    logInfo("ADMIN failed from %s [%s], %s"		, (const char*) remotehost		, (const char*) remoteaddr		, (const char*) the_user	    );	}	return;    }    if (TRACE(SERVER))	logInfo("FAX ADMIN FROM %s [%s], %s"	    , (const char*) remotehost	    , (const char*) remoteaddr	    , (const char*) the_user	);    adminAttempts = 0;    state |= S_PRIVILEGED;    reply(230, "Administrative privileges established.");}/* * Terminate login as previous user, if any, * resetting state; used when USER command is * given or login fails. */voidHylaFAXServer::end_login(void){    if (IS(LOGGEDIN)) {	uid_t ouid = geteuid();	seteuid(0);	seteuid(ouid);    }    state &= ~(S_LOGGEDIN|S_PRIVILEGED|S_WAITPASS);    passwd = "*";    adminwd = "*";}/* * Record logout in wtmp file, cleanup state, * and exit with supplied status. */voidHylaFAXServer::dologout(int status){    if (IS(LOGGEDIN))	end_login();    if (trigSpec != "") {	fxStr emsg;	cancelTrigger(emsg);    }    for (u_int i = 0, n = tempFiles.length(); i < n; i++)	(void) Sys::unlink(tempFiles[i]);    if (xferfaxlog != -1)        Sys::close(xferfaxlog);    if (clientFd != -1)	Sys::close(clientFd);    if (clientFIFOName != "")	Sys::unlink(clientFIFOName);    for (JobDictIter iter(blankJobs); iter.notDone(); iter++) {	Job* job = iter.value();	fxStr file("/" | job->qfile);	Sys::unlink(file);    }    _exit(status);		// beware of flushing buffers after a SIGPIPE}

⌨️ 快捷键说明

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