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

📄 passchange.c

📁 RADIUS协议的认证计费服务
💻 C
字号:
/* * RADIUS Remote Authentication Dial In User Service * * * Livingston Enterprises, Inc. 6920 Koll Center Parkway Pleasanton, CA  94566 * * Copyright 1992 Livingston Enterprises, Inc. * * Permission to use, copy, modify, and distribute this software for any * purpose and without fee is hereby granted, provided that this copyright * and permission notice appear on all copies and supporting documentation, * the name of Livingston Enterprises, Inc. not be used in advertising or * publicity pertaining to distribution of the program without specific * prior permission, and notice be given in supporting documentation that * copying and distribution is by permission of Livingston Enterprises, Inc. *  * Livingston Enterprises, Inc. makes no representations about the suitability * of this software for any purpose.  It is provided "as is" without express * or implied warranty. * *//* * Copyright [C] The Regents of the University of Michigan and Merit Network, * Inc. 1992, 1993, 1994, 1995, 1996, 1997, 1998 All Rights Reserved * * Permission to use, copy, and modify this software and its documentation  * for any purpose and without fee is hereby granted, provided:  * * 1) that the above copyright notice and this permission notice appear in all *    copies of the software and derivative works or modified versions thereof,  * * 2) that both the copyright notice and this permission and disclaimer notice  *    appear in all supporting documentation, and  * * 3) that all derivative works made from this material are returned to the *    Regents of the University of Michigan and Merit Network, Inc. with *    permission to copy, to display, to distribute, and to make derivative *    works from the provided material in whole or in part for any purpose. * * Users of this code are requested to notify Merit Network, Inc. of such use * by sending email to aaa-admin@merit.edu * * Please also use aaa-admin@merit.edu to inform Merit Network, Inc of any * derivative works. * * Distribution of this software or derivative works or the associated * documentation is not allowed without an additional license. * * Licenses for other uses are available on an individually negotiated * basis.  Contact aaa-license@merit.edu for more information. * * THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE REGENTS OF THE * UNIVERSITY OF MICHIGAN AND MERIT NETWORK, INC. DO NOT WARRANT THAT THE * FUNCTIONS CONTAINED IN THE SOFTWARE WILL MEET LICENSEE'S REQUIREMENTS OR * THAT OPERATION WILL BE UNINTERRUPTED OR ERROR FREE.  The Regents of the * University of Michigan and Merit Network, Inc. shall not be liable for any * special, indirect, incidental or consequential damages with respect to any * claim by Licensee or any third party arising from use of the software. * * Merit AAA Server Support * Merit Network, Inc. * 4251 Plymouth Road, Suite C. * Ann Arbor, Michigan, USA 48105-2785 * * attn:  John Vollbrecht * voice: 734-764-9430 * fax:   734-647-3185 * email: aaa-admin@merit.edu * *//* * * Public entry points in this file: * * pw_expired * */static char     rcsid[] = "$Id: passchange.c,v 1.1.1.1 2001/08/10 20:49:28 bonze Exp $";#include	<sys/types.h>#include	<sys/param.h>#include	<sys/socket.h>#include	<sys/time.h>#include	<sys/file.h>#include	<net/if.h>#include	<netinet/in.h>#include	<stdio.h>#include	<netdb.h>#include	<errno.h>#include	<memory.h>#include	<signal.h>#include	<syslog.h>#include	"radius.h"extern UINT4    expiration_seconds;extern UINT4    warning_seconds;extern int      debug_flag;extern int      allow_pw_changing;static int      set_expiration PROTO((VALUE_PAIR *, VALUE_PAIR *, UINT4));static int      rad_passchange PROTO((AUTH_REQ *, int, char *));static AATV     passwd_aatv = DEF_AATV_DIRECT("PASSWD", rad_passchange);AATVPTR         rad_passwd_aatv = & passwd_aatv;/************************************************************************* * *	Function: rad_passchange * *	Purpose: Change a users password * *************************************************************************/static intrad_passchange (authreq, value, afpar)AUTH_REQ       *authreq;int             value;char           *afpar;{	int             result;	VALUE_PAIR     *namepair;	VALUE_PAIR     *newpasspair;	VALUE_PAIR     *oldpasspair;	VALUE_PAIR     *curpass;	VALUE_PAIR     *user_check;	VALUE_PAIR     *user_deny;	VALUE_PAIR     *user_reply;	char            pw_digest[AUTH_VECTOR_LEN];	char            string[64];	char            passbuf[AUTH_PASS_LEN];	int             i;	int             secretlen;	static char    *func = "rad_passchange";	dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: entered", func));	/*	 *	The allow_pw_changing global variable is defined in the	 *	engine and set by a command line option.	 */	if (allow_pw_changing == 0)	{		return EV_NAK;	}	/* Get the username */	namepair = get_vp (authreq->cur_request, PW_USER_NAME);	if (namepair == (VALUE_PAIR *) NULL)	{		logit (LOG_DAEMON, LOG_ERR,			"%s: from %s - No User name supplied",			func, ip_hostname (authreq->ipaddr));		return EV_NAK;	}	/*	 * Look the user up in the database	 */	if (user_find (NULL, namepair->strvalue, 0, &user_check,			&user_deny, &user_reply, 0) != 0)	{		logit (LOG_DAEMON, LOG_ERR,			"%s: from %s - Invalid User: %s", func,			ip_hostname (authreq->ipaddr), namepair->strvalue);		return EV_NAK;	}	/*	 * Validate the user -	 * 	 * We have to unwrap this in a special way to decrypt the old and new	 * passwords.  The MD5 calculation is based on the old password.  The	 * vector is different.  The old password is encrypted using the	 * encrypted new password as its vector.  The new password is	 * encrypted using the random encryption vector in the request	 * header.	 */	/* Extract the attr-value pairs for the old and new passwords */	newpasspair = get_vp (authreq->cur_request, PW_USER_PASSWORD);	oldpasspair = get_vp (authreq->cur_request, PW_OLD_PASSWORD);	/* Verify that both encrypted passwords were supplied */	if (newpasspair == (VALUE_PAIR *) NULL ||		oldpasspair == (VALUE_PAIR *) NULL)	{		/* Missing one of the passwords */		logit (LOG_DAEMON, LOG_ERR,			"%s: from %s - Missing Password: %s", func,			ip_hostname (authreq->ipaddr), namepair->strvalue);		list_free (user_check);		list_free (user_deny);		list_free (user_reply);		return EV_NAK;	}	/* Get the current password from the database */	curpass = get_vp_ci (user_check, CI_USER_PASSWORD, 0);	if ((curpass == (VALUE_PAIR *) NULL) ||		(curpass->strvalue == (char *) NULL))	{		/* Missing our local copy of the password */		logit (LOG_DAEMON, LOG_ERR,			"%s: from %s - Missing Local Password: %s", func,			ip_hostname (authreq->ipaddr), namepair->strvalue);		list_free (user_check);		list_free (user_deny);		list_free (user_reply);		return EV_NAK;	}	if (strcmp (curpass->strvalue, "UNIX") == 0) /* Old Livinstong traces */	{		/* Can't change passwords that aren't in users file */		logit (LOG_DAEMON, LOG_ERR,			"%s: from %s: system password change not allowed: %s\n",			func, ip_hostname (authreq->ipaddr),			namepair->strvalue);		list_free (user_check);		list_free (user_deny);		list_free (user_reply);		return EV_NAK;	}	/* Decrypt the old password */	secretlen = strlen (curpass->strvalue);	memcpy (string, curpass->strvalue, secretlen);	memcpy (string + secretlen, newpasspair->strvalue, AUTH_VECTOR_LEN);	md5_calc (pw_digest, string, AUTH_VECTOR_LEN + secretlen);	memcpy ((char *) passbuf, oldpasspair->strvalue, AUTH_PASS_LEN);	for (i = 0; i < AUTH_PASS_LEN; i++)	{		passbuf[i] ^= pw_digest[i];	}	/* Did they supply the correct password ??? */	if (strncmp (passbuf, curpass->strvalue, AUTH_PASS_LEN) != 0)	{		logit (LOG_DAEMON, LOG_ERR,			"%s: from %s - Incorrect Password: %s", func,			ip_hostname (authreq->ipaddr), namepair->strvalue);		list_free (user_check);		list_free (user_deny);		list_free (user_reply);		return EV_NAK;	}	/* Decrypt the new password */	memcpy (string, curpass->strvalue, secretlen);	memcpy (string + secretlen, (char *) authreq->repvec, AUTH_VECTOR_LEN);	md5_calc (pw_digest, string, AUTH_VECTOR_LEN + secretlen);	memcpy ((char *) passbuf, newpasspair->strvalue, AUTH_PASS_LEN);	for (i = 0; i < AUTH_PASS_LEN; i++)	{		passbuf[i] ^= pw_digest[i];	}#ifdef ASCEND	/* Update the users password in the memory cache. */	if (change_pw (namepair->strvalue, 0, curpass, passbuf) != 0)	{		logit (LOG_DAEMON, LOG_ERR,			"%s: from %s - Cannot change cached password: %s",			func, ip_hostname (authreq->ipaddr),			namepair->strvalue);		list_free (user_check);		list_free (user_deny);		list_free (user_reply);		return EV_NAK;	}	/*	 *	Also change it in the check list so it gets	 *	reflected in the file update.	 */#endif	/* ASCEND */	/* Update the users password. */	avpair_string_mod (curpass, passbuf, -1); 	/* Add a new expiration date if we are aging passwords */	if (expiration_seconds != (UINT4) 0)	{		set_expiration (user_check, user_reply, expiration_seconds);	}#ifdef ASCEND	/* Update the cached expiration time */	update_expire (namepair->strvalue, 0, user_check);#endif	/* ASCEND */	/* Update the database */	if (user_update (namepair->strvalue, user_check,			user_deny, user_reply) != 0)	{		result = EV_NAK;	}	else	{		result = EV_ACK;	}	list_free (user_check);	list_free (user_deny);	list_free (user_reply);	return result;} /* end of rad_passchange () *//************************************************************************* * *	Function: set_expiration * *	Purpose: Set the new expiration time by updating or adding *		 the Expiration attribute-value pair. * *************************************************************************/static intset_expiration (user_check, user_reply, expiration)VALUE_PAIR     *user_check;VALUE_PAIR     *user_reply;UINT4           expiration;{	VALUE_PAIR     *exppair;	VALUE_PAIR     *prev;	VALUE_PAIR     *vp;	UINT4		zero = 0;	struct timeval  tp;	struct timezone tzp;	static char    *func = "set_expiration";	dprintf(2, (LOG_AUTH, LOG_DEBUG, "%s: entered", func));	if (user_check == (VALUE_PAIR *) NULL)	{		return (-1);	}	/* Look for an existing expiration entry */	exppair = user_check;	prev = (VALUE_PAIR *) NULL;	while (exppair != (VALUE_PAIR *) NULL)	{		if (exppair->attribute == CI_EXPIRATION)		{			break;		}		prev = exppair;		exppair = exppair->next;	}	if (exppair == (VALUE_PAIR *) NULL)	{		exppair = avpair_add (&prev->next, CI_EXPIRATION, &zero, 0);	}	/* calculate a new expiration */	vp = NULL_VP;#ifdef ASCEND	for (vp = user_reply; vp != NULL_VP; vp = vp->next)	{		if (vp->attribute == CI_ASCEND_PW_LIFETIME &&			vp->ap->vendor_id == VC_ASCEND)		{			break;		}	}#endif	/* ASCEND */	gettimeofday (&tp, &tzp);	if (vp == NULL_VP)	{		exppair->lvalue = tp.tv_sec + expiration;	}	else	{		exppair->lvalue = tp.tv_sec + vp->lvalue * SECONDS_PER_DAY;	}	return (0);} /* end of set_expiration () *//************************************************************************* * *	Function: pw_expired * *	Purpose: Tests to see if the user's password has expired. * *	Return: Number of days before expiration if a warning is required *		otherwise zero for success and -1 for failure. * *************************************************************************/intpw_expired (exptime, check_items)UINT4           exptime;VALUE_PAIR     *check_items;{	int             exp_remain_int;	UINT4           exp_remain;	UINT4           warn_secs;	VALUE_PAIR     *item;	struct timeval  tp;	struct timezone tzp;	warn_secs = warning_seconds;#ifdef ASCEND	/* Items in the users file take precedence over configuration values */	for (item = check_items; item != NULL_VP; item = item->next)	{		if (item->attribute == CI_ASCEND_PW_WARNING &&			item->ap->vendor_id == VC_ASCEND)		{			warn_secs = item->lvalue * SECONDS_PER_DAY;		}	}#endif	/* ASCEND */	if (expiration_seconds == (UINT4) 0)	{		return -1;	}	gettimeofday (&tp, &tzp);	if (tp.tv_sec > exptime)	{		return -1;	}	if (warn_secs != (UINT4) 0)	{		if (tp.tv_sec > exptime - warning_seconds)		{			exp_remain = exptime - tp.tv_sec;			exp_remain /= (UINT4) SECONDS_PER_DAY;			exp_remain_int = exp_remain + 1;			return (exp_remain_int);		}	}	return 0;} /* end of pw_expired () */

⌨️ 快捷键说明

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