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

📄 radiusd.c

📁 RADIUS协议的认证计费服务
💻 C
📖 第 1 页 / 共 5 页
字号:
				continue;			}			/* Attribute vp1 is different from vp2. */			*p_why = "string mismatch";			return (0);	/* Not a duplicate */		}		if ((pw_vp1 != NULL_VP) || (pw_vp2 != NULL_VP))		{			logit (LOG_DAEMON, LOG_INFO,			     "%s: More than one password in request (ignored)",				func);		}		else /* Save the passwords for later processing. */		{			pw_vp1 = vp1;			pw_vp2 = vp2;		}	} /* end of for each of the attribute in both requests */	/*	 *	At this point, all that's left to compare are the passwords.	 *	Since this attribute is a User-Password,	 *	just decrypt it and compare the passwords.	 *	 *	Note that the caller is informed what the password	 *	in auth1 was via the p_pw1 and p_pw_vp1 parameters.	 */	if (*p_pw_vp1 == NULL_VP)	{		*p_pw_vp1 = pw_vp1;	/* Save it. */	}	else	{		if (*p_pw_vp1 != pw_vp1)		{			logit (LOG_DAEMON, LOG_CRIT,				"%s: Internal error, *p_pw_vp1 != pw_vp1",				func);			pw1 = (char *) NULL;	/* Force decryption again. */		}	}	/*	 *	Check to see if the password of the incoming request has been	 *	decrypted.	 *	 *	Warning: This code assumes that only ONE User-Password will	 *	be present in a request at a time.	 */	if (pw1 == (char *) NULL)	{		/* 		 *	Indicate that the password of the new		 *	request has been decrypted.		 */		pw1 = pw1_buff;		/* Decrypt the newly arrived password. */		get_passwd (auth1, pw1, (char *) NULL, (char *) NULL);		*p_pw1 = pw1;	}	/* Try to decrypt the password that is on the queue. */	if (get_passwd (auth2, pw2, (char *) NULL, (char *) NULL) != 0)	{		/* Unable to get a password decrypted. Not a match. */	  	*p_why = "queued User-Password fail";		return (0);	/* Assume not a duplicate */	}	/* Compare the passwords. (Passwords shouldn't have NULL's in them.) */	if (strcmp (pw1, pw2) != 0)	/* Passwords aren't the same. */	{		/* Safety, clear the passwords. */	  	memset ((char *) pw1_buff, 0, sizeof (pw1_buff));	  	memset ((char *) pw2, 0, sizeof (pw2));		*p_why = "User-Password mismatch";		return (0);	}	/* Safety, clear the passwords. */	memset ((char *) pw1_buff, 0, sizeof (pw1_buff));	memset ((char *) pw2, 0, sizeof (pw2));	return (1);		/* Everything matches. */} /* end of authreq_dup_check () *//************************************************************************* * *	Function: authreq_q_size * *	Purpose: Indicate current length of authentication or accounting queue. * *************************************************************************/static intauthreq_q_size (authreq)AUTH_REQ       *authreq;{	int             count;	for (count = 0; authreq != (AUTH_REQ *) NULL; authreq = authreq->next)	{		count++;	}	return count;} /* end of authreq_q_size () *//************************************************************************* * *	Function: authreq_holdtime * *	Purpose: Compute cleanup hold time for the given AUTH_REQ. * *	Returns: hold time in seconds. * *************************************************************************/intauthreq_holdtime (authreq)AUTH_REQ       *authreq;{	int             hold_time;	/* By default, use the value configured in the clients file. */	hold_time = authreq->client->reply_holdtime;	if (hold_time == 0)	/* Then, use what's left in the authreq */	{		hold_time = authreq->ttl;	}	/* Calculate the average holding (floored) time now. */	if ((hold_time = cleanup_delay (hold_time)) > 0)	{		return hold_time;	}	return 1;	/* Safety */} /* end of authreq_holdtime () *//************************************************************************* * *	Function: build_acct_req * *	Purpose: Build an acct-request structure, fill out the header and *		 other values and attach attribute-value pairs as needed. * *	Returns: a pointer to an authreq data structure, *		 or NULL, if the queue is too full. * *************************************************************************/AUTH_REQ *build_acct_req (authreq, status, session_id, stime, pairs)AUTH_REQ       *authreq;		/* optional (may be NULL), so ignore */int             status;			/* required! */char           *session_id;		/* optional (may be NULL), so create */time_t          stime;			/* session time */VALUE_PAIR     *pairs;			/* optional (may be NULL), so ignore */{	int             flag;	int             qcount = 0;	UINT4           ip;	/* Dummy value for find_client_by_name() call */	time_t          now = time (0);	AUTH_REQ       *acctreq;	VALUE_PAIR     *vp;	VALUE_PAIR     *name;	VALUE_PAIR     *nas;	VALUE_PAIR    **prev_ptr;	FILE           *debugout = stdout;	char            buf[AUTH_STRING2_LEN];	static int      id = -1;	static char    *func = "build_acct_req";	dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: entered", func));	if (ddt != (FILE *) NULL)	{		debugout = ddt;	}	/*	 *	Allocate the new accounting data structure.	 */	if ((acctreq = (AUTH_REQ *) calloc (1, sizeof (AUTH_REQ)))							== (AUTH_REQ *) NULL)	{		logit (LOG_DAEMON, LOG_ALERT, "%s: FATAL out of memory", func);		abort ();	}	authreq_mf.m++;	/*	 *	Fill header fields	 */	acctreq->ipaddr = get_our_addr ();	acctreq->udp_port = 0;		/* dummy values -- don't care */	acctreq->rep_id = 0;		/* dummy values -- don't care */	acctreq->fwd_id = 0;	acctreq->code = PW_ACCOUNTING_REQUEST;	memset ((char *) acctreq->repvec, 0, sizeof (authreq->repvec));	memset ((char *) acctreq->fwdvec, 0, sizeof (authreq->fwdvec));	if (authreq != (AUTH_REQ *) NULL) /* Pick up client from here. */	{		acctreq->client = authreq->client;	}	else	{		if (find_client_by_name (RADIUS_LOCALSERVER, &ip,					&acctreq->client) < 0)		{			acctreq->client = (CLIENT_ENTRY *) NULL;		}	}	acctreq->ttlslice = MAX_ACCT_REQUEST_TIME; /* About three minutes. */	acctreq->ttl = MAX_ACCT_REQUEST_TIME;	acctreq->timer = DEFAULT_TIMER_VALUE;	acctreq->retry_cnt = 0;	acctreq->seqch_cnt = 0;	acctreq->retry_limit = default_retry_limit;	acctreq->seqch_limit = default_seqch_limit;	acctreq->vers_in = 0;	acctreq->vers_out = 0;	acctreq->flags = 0;	acctreq->realm_filter = (char *) NULL;	if (authreq != (AUTH_REQ *) NULL) /* Pick up state from where we are. */	{		acctreq->state = authreq->state;		acctreq->debug_flag = authreq->debug_flag;	}	else	{		acctreq->state = ST_INIT;		acctreq->debug_flag = 0;	/* No special debugging. */	}	acctreq->sws = 0;	if (global_acct_q.hold > 0)	{		SAR_HOLD(acctreq);	/* Set hold flag in sws. */	}	acctreq->repstatus = -2;	/* invalid value */	acctreq->fsmstatus = EV_NAK;	/* initial value */	acctreq->cur_count = 0;	acctreq->onqueue = now;	acctreq->starthg = now;	acctreq->startlas = now;	acctreq->fsm_aatv = (AATV *) NULL;	acctreq->direct_aatv = (AATV *) NULL;	acctreq->event_q = (EVENT_ENT *) NULL;	acctreq->proc_q = (PROC_ENT *) NULL;	acctreq->next = (AUTH_REQ *) NULL;	acctreq->request = NULL_VP;	acctreq->cur_request = NULL_VP;	acctreq->user_check = NULL_VP;	acctreq->user_deny = NULL_VP;	if (pairs != NULL_VP)	{		dprintf(2, (LOG_DAEMON, LOG_DEBUG, "%s: pairs list:", func));		debug_list (debugout, pairs);	}	flag = 0;	if (authreq != (AUTH_REQ *) NULL)	{		dprintf(2, (LOG_DAEMON, LOG_DEBUG,			"%s: authreq->cur_request:", func));		debug_list (debugout, authreq->cur_request);		if (get_vp (authreq->cur_request,				PW_ACCT_STATUS_TYPE) == NULL_VP)		{			avpair_add (&acctreq->request, PW_ACCT_STATUS_TYPE,				    &status, 0);		}		if (status == PW_STATUS_MODEM_STOP)		{			if (get_vp (authreq->cur_request,					PW_ACCT_SESSION_TIME) == NULL_VP)			{				avpair_add (&acctreq->request,					    PW_ACCT_SESSION_TIME, &stime, 0);			}		}		if ((vp = get_vp (authreq->cur_request,					PW_ACCT_SESSION_ID)) == NULL_VP)		{			flag = 1; /* Since no Acct-Session-Id can be present */		}	}	else /* was NULL */	{		flag = 1;		avpair_add (&acctreq->request, PW_ACCT_STATUS_TYPE, &status, 0);		avpair_add (&acctreq->request, PW_ACCT_SESSION_TIME, &stime, 0);	}	if (flag == 1) /* This ACCT packet needs an Acct-Session-Id */	{		if (session_id == (char *) NULL) /* create unique one */		{			sprintf (buf, "%08X", ++id);		}		else /* use the one given by the caller */		{			memcpy (buf, session_id, 8);		}		avpair_add (&acctreq->request, PW_ACCT_SESSION_ID, buf, 8);	}	if (pairs != NULL_VP)	{		list_copy (&acctreq->request, pairs);	}	if ((authreq != (AUTH_REQ *) NULL) && (authreq->cur_request != NULL_VP))	{		list_copy (&acctreq->request, authreq->cur_request);	}	/* Remove attributes which should never be in ACCT packet (per RFC) */	for (prev_ptr = &acctreq->request, vp = *prev_ptr;		vp != NULL_VP;		vp = *prev_ptr)	{		switch (vp->ap->vendor_id)		{		    default:	/* No special treatment for unknown vendors. */			break;		    case VC_RADIUS:	/* Standard attribute space. */			switch (vp->attribute)			{			    case PW_USER_PASSWORD:			    case PW_CHAP_PASSWORD:			    case PW_REPLY_MESSAGE:			    case PW_STATE:				/* Remove these from the request list. */				*prev_ptr = vp->next;				avpair_free (vp);				continue;			    default:				break;			}			break;		    case VC_MERIT:	/* Merit vendor specific attributes. */			switch (vp->attribute)			{			    case PW_PROXY_ACTION:				/* Remove these from the request list. */				*prev_ptr = vp->next;				avpair_free (vp);				continue;			    default:				break;			}			break;		}		/* Leave all others in request list. */		prev_ptr = &vp->next;	}	list_copy (&acctreq->cur_request, acctreq->request);	debug_list (debugout, acctreq->cur_request);	if (enqueue_authreq (&global_acct_q, acctreq) == (AUTH_REQ *) NULL)	{		name = get_vp (acctreq->cur_request, PW_USER_NAME);		nas = get_vp (acctreq->cur_request, PW_NAS_IDENTIFIER);		vp = get_vp (acctreq->cur_request, PW_NAS_PORT);		logit (LOG_DAEMON, LOG_INFO,			"%s: global_acct_q.limit (%d) exceeded (%d)",			func, global_acct_q.limit, qcount);		logit (LOG_DAEMON, LOG_INFO,			"%s: Acct-Status-Type %d - %s on port %ld of %s",			func, status,			(name != NULL_VP) ? name->strvalue : "'?'",			(vp != NULL_VP) ? vp->lvalue : -1,			(nas != NULL_VP) ? nas->strvalue : "'?'");		/* Mark it free'd so that free_authreq_final() does free it. */		SAR_FREED(acctreq);		free_authreq_final (acctreq);		return (AUTH_REQ *) NULL;	/* Rejected */	}	return acctreq;} /* end of build_acct_req () *//************************************************************************* * *	Function: call_action * *	Purpose: Calls the action function specified by the AATV argument. * *	Returns: The result (return code or "event") of the action function. * *************************************************************************/intcall_action (aatv, authreq, value, afpar)AATV           *aatv;AUTH_REQ       *authreq;int             value;char           *afpar;{	int             i;	int             old_debug = debug_flag;	int             pid;	int             result;	AATV           *previous_aatv = (AATV *) NULL;	PROC_ENT       *pe;	VALUE_PAIR     *vp;	sigset_t        signals;	struct sigaction action;	char            buffer[AUTH_STRING1_LEN];	static char    *func = "call_action";	if (aatv == (AATV *) NULL)	{		dprintf(2, (LOG_DAEMON, LOG_DEBUG,			"%s: configuration error: NULL AATV, value %d and '%s'",			func, value,			(afpar == (char *) NULL) ? "?" : afpar));		return EV_FATAL;	}	dprintf(2, (LOG_DAEMON, LOG_DEBUG,		"%s: AATV '%s', type %d, value %d and '%s'", func, aatv->id,		aatv->aatvfunc_type, value,		(afpar == (char *) NULL) ? "?" : afpar));	if (authreq != (AUTH_REQ *) NULL)	{		if (aatv != authreq->fsm_aatv)		{			if (authreq->fsm_aatv != (AATV *) NULL)			{				authreq->direct_aatv = aatv;			}			else	/* Need to init fsm_aatv value */			{				authreq->fsm_aatv = aatv;			}		}		/*		 *	Modi

⌨️ 快捷键说明

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