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

📄 radiusd.c

📁 国际标准协议的
💻 C
📖 第 1 页 / 共 5 页
字号:
			}
			if(check_item->attribute == PW_PASSWORD &&
				     auth_item->attribute == PW_CHAP_PASSWORD) {
				break;
			}

			auth_item = auth_item->next;
		}
		if(auth_item == (VALUE_PAIR *)NULL) {
			result = -1;
			continue;
		}

		/*
		 * Special handling for passwords which are encrypted,
		 * and sometimes authenticated against the UNIX passwd database.
		 * Also they can come using the Three-Way CHAP.
		 *
		 */
		if(check_item->attribute == PW_PASSWORD) {
			if(auth_item->attribute == PW_CHAP_PASSWORD) {
				/* Use MD5 to verify */
				ptr = string;
				*ptr++ = *auth_item->strvalue;
				strcpy(ptr, check_item->strvalue);
				ptr += strlen(check_item->strvalue);
				memcpy(ptr, authreq->vector, AUTH_VECTOR_LEN);
				md5_calc(pw_digest, string,
					1 + CHAP_VALUE_LENGTH +
					strlen(check_item->strvalue));
				/* Compare them */
				if(memcmp(pw_digest, auth_item->strvalue + 1,
						CHAP_VALUE_LENGTH) != 0) {
					result = -1;
				}
			}
			else {
				/* Decrypt the password */
				memcpy(string,
					auth_item->strvalue, AUTH_PASS_LEN);
				for(i = 0;i < AUTH_PASS_LEN;i++) {
					string[i] ^= pw_digest[i];
				}

				/* Just for test */
				/*-----------------
				sprintf(msg,"Decrypt passwd str: %s\n",string);
				msg[127]='\0';
				log_err(msg);
				------------------*/
				string[AUTH_PASS_LEN] = '\0';
				/* Test Code for Challenge */
				if(strcmp(string, "challenge") == 0) {
					send_challenge(authreq, 
				"You want me to challenge you??\r\nOkay I will",
						"1",activefd);
					pairfree(authreq->request);
					memset(authreq, 0, sizeof(AUTH_REQ));
					free(authreq);
					return;
				}
				if(strcmp(check_item->strvalue, "UNIX") == 0) {
					if(unix_pass(name_str, string,user_reply) != 0) {
						result = -1;
						user_msg = (char *)NULL;
						/* Just for test */
						sprintf(msg,"Unix Password error\n");
						msg[127]='\0';
						log_err(msg);
					}
				}
				else if(strcmp(check_item->strvalue, string) != 0) {
					result = -1;
					user_msg = (char *)NULL;
					/* Just for test */	
					sprintf(msg,"DBase Password error\n");
					msg[127]='\0';
					log_err(msg);
				}
			}
		}
		else {
			switch(check_item->type) {

			case PW_TYPE_STRING:
				if(strcmp(check_item->strvalue,
						auth_item->strvalue) != 0) {
					result = -1;
				}
				break;

			case PW_TYPE_INTEGER:
			case PW_TYPE_IPADDR:
				if(check_item->lvalue != auth_item->lvalue) {
					result = -1;
				}
				break;

			default:
				result = -1;
				break;
			}
		}
		check_item = check_item->next;
	}
} /* end of if(auth_type_pair) */


/*Just for test*/
/*-------
sprintf(msg,"Auth:1 result - %d\n",result);
msg[127]='\0';
log_err(msg);
-------*/
if(result == 0) {
	/* Check the simultaneous user */
	if(check_simultaneous_file(authreq->request) != 0) {	
	/*-------
	if(check_simultaneous_cache(authreq->request) != 0) {
	-------*/
		result = -1;
	}	
}
/*Just for test*/
/*------
sprintf(msg,"Auth:2 result - %d\n",result);
msg[127]='\0';
log_err(msg);
------*/
	if(result != 0) {
		send_reject(authreq, user_msg, activefd);
	}
	else {
		send_accept(authreq, user_reply, user_msg, activefd);
	}

	pairfree(authreq->request);
	memset(authreq, 0, sizeof(AUTH_REQ));
	free(authreq);
	pairfree(user_check);
	pairfree(user_reply);
	return;
}/* end of if(authreq->proxy_state) */
}

/*************************************************************************
 *
 *	Function: send_reject
 *
 *	Purpose: Reply to the request with a REJECT.  Also attach
 *		 any user message provided.
 *
 *************************************************************************/

send_reject(authreq, msg, activefd)
AUTH_REQ	*authreq;
char		*msg;
int		activefd;
{
	AUTH_HDR		*auth;
	struct	sockaddr	saremote;
	struct	sockaddr_in	*sin;
	char			*ip_hostname();
	char			digest[AUTH_VECTOR_LEN];
	int			secretlen;
	int			total_length;
	u_char			*ptr;
	int			len;

	auth = (AUTH_HDR *)send_buffer;

	/* Build standard response header */
	if(authreq->code == PW_PASSWORD_REQUEST) {
		auth->code = PW_PASSWORD_REJECT;
	}
	else {
		auth->code = PW_AUTHENTICATION_REJECT;
	}
	auth->id = authreq->id;
	memcpy(auth->vector, authreq->vector, AUTH_VECTOR_LEN);
	total_length = AUTH_HDR_LEN;

	/* Append the user message */
	if(msg != (char *)NULL) {
		len = strlen(msg);
		if(len > 0 && len < AUTH_STRING_LEN) {
			ptr = auth->data;
			*ptr++ = PW_PORT_MESSAGE;
			*ptr++ = len + 2;
			memcpy(ptr, msg, len);
			ptr += len;
			total_length += len + 2;
		}
	}

	/* Set total length in the header */
	auth->length = htons(total_length);

	/* Calculate the response digest */
	secretlen = strlen(authreq->secret);
	memcpy(send_buffer + total_length, authreq->secret, secretlen);
	md5_calc(digest, (char *)auth, total_length + secretlen);
	memcpy(auth->vector, digest, AUTH_VECTOR_LEN);
	memset(send_buffer + total_length, 0, secretlen);

	sin = (struct sockaddr_in *) &saremote;
        memset ((char *) sin, '\0', sizeof (saremote));
	sin->sin_family = AF_INET;
	sin->sin_addr.s_addr = htonl(authreq->ipaddr);
	sin->sin_port = htons(authreq->udp_port);

	DEBUG("Sending Reject of id %d to %lx (%s)\n",
		authreq->id, (u_long)authreq->ipaddr,
		ip_hostname(authreq->ipaddr));
	
	/* Send it to the user */
	sendto(activefd, (char *)auth, (int)total_length, (int)0,
			(struct sockaddr *) &saremote, sizeof(struct sockaddr_in));
}

/*************************************************************************
 *
 *	Function: send_challenge
 *
 *	Purpose: Reply to the request with a CHALLENGE.  Also attach
 *		 any user message provided and a state value.
 *
 *************************************************************************/

send_challenge(authreq, msg, state, activefd)
AUTH_REQ	*authreq;
char		*msg;
char		*state;
int		activefd;
{
	AUTH_HDR		*auth;
	struct	sockaddr_in	saremote;
	struct	sockaddr_in	*sin;
	char			*ip_hostname();
	char			digest[AUTH_VECTOR_LEN];
	int			secretlen;
	int			total_length;
	u_char			*ptr;
	int			len;

	auth = (AUTH_HDR *)send_buffer;

	/* Build standard response header */
	auth->code = PW_ACCESS_CHALLENGE;
	auth->id = authreq->id;
	memcpy(auth->vector, authreq->vector, AUTH_VECTOR_LEN);
	total_length = AUTH_HDR_LEN;

	/* Append the user message */
	if(msg != (char *)NULL) {
		len = strlen(msg);
		if(len > 0 && len < AUTH_STRING_LEN) {
			ptr = auth->data;
			*ptr++ = PW_PORT_MESSAGE;
			*ptr++ = len + 2;
			memcpy(ptr, msg, len);
			ptr += len;
			total_length += len + 2;
		}
	}

	/* Append the state info */
	if((state != (char *)NULL) && (strlen(state) > 0)) {
		len = strlen(state);
		*ptr++ = PW_STATE;
		*ptr++ = len + 2;
		memcpy(ptr, state, len);
		ptr += len;
		total_length += len + 2;
	}

	/* Set total length in the header */
	auth->length = htons(total_length);

	/* Calculate the response digest */
	secretlen = strlen(authreq->secret);
	memcpy(send_buffer + total_length, authreq->secret, secretlen);
	md5_calc(digest, (char *)auth, total_length + secretlen);
	memcpy(auth->vector, digest, AUTH_VECTOR_LEN);
	memset(send_buffer + total_length, 0, secretlen);

	sin = (struct sockaddr_in *) &saremote;
        memset ((char *) sin, '\0', sizeof (saremote));
	sin->sin_family = AF_INET;
	sin->sin_addr.s_addr = htonl(authreq->ipaddr);
	sin->sin_port = htons(authreq->udp_port);

	DEBUG("Sending Challenge of id %d to %lx (%s)\n",
		authreq->id, (u_long)authreq->ipaddr,
		ip_hostname(authreq->ipaddr));
	
	/* Send it to the user */
	sendto(activefd, (char *)auth, (int)total_length, (int)0,
			(struct sockaddr *) &saremote, sizeof(struct sockaddr_in));
}

/*************************************************************************
 *
 *	Function: send_pwack
 *
 *	Purpose: Reply to the request with an ACKNOWLEDGE.
 *		 User password has been successfully changed.
 *
 *************************************************************************/

send_pwack(authreq, activefd)
AUTH_REQ	*authreq;
int		activefd;
{
	AUTH_HDR		*auth;
	struct	sockaddr	saremote;
	struct	sockaddr_in	*sin;
	char			*ip_hostname();
	char			digest[AUTH_VECTOR_LEN];
	int			secretlen;

	auth = (AUTH_HDR *)send_buffer;

	/* Build standard response header */
	auth->code = PW_PASSWORD_ACK;
	auth->id = authreq->id;
	memcpy(auth->vector, authreq->vector, AUTH_VECTOR_LEN);
	auth->length = htons(AUTH_HDR_LEN);

	/* Calculate the response digest */
	secretlen = strlen(authreq->secret);
	memcpy(send_buffer + AUTH_HDR_LEN, authreq->secret, secretlen);
	md5_calc(digest, (char *)auth, AUTH_HDR_LEN + secretlen);
	memcpy(auth->vector, digest, AUTH_VECTOR_LEN);
	memset(send_buffer + AUTH_HDR_LEN, 0, secretlen);

	sin = (struct sockaddr_in *) &saremote;
        memset ((char *) sin, '\0', sizeof (saremote));
	sin->sin_family = AF_INET;
	sin->sin_addr.s_addr = htonl(authreq->ipaddr);
	sin->sin_port = htons(authreq->udp_port);

	DEBUG("Sending PW Ack of id %d to %lx (%s)\n",
		authreq->id, (u_long)authreq->ipaddr,
		ip_hostname(authreq->ipaddr));
	
	/* Send it to the user */
	sendto(activefd, (char *)auth, (int)AUTH_HDR_LEN, (int)0,
			&saremote, sizeof(struct sockaddr_in));
}

/*************************************************************************
 *
 *	Function: send_accept
 *
 *	Purpose: Reply to the request with an ACKNOWLEDGE.  Also attach
 *		 reply attribute value pairs and any user message provided.
 *
 *************************************************************************/

send_accept(authreq, reply, msg, activefd)
AUTH_REQ	*authreq;
VALUE_PAIR	*reply;
char		*msg;
int		activefd;
{
	AUTH_HDR		*auth;
	u_short			total_length;
	struct	sockaddr	saremote;
	struct	sockaddr_in	*sin;
	u_char			*ptr;
	int			len;
	UINT4			lvalue;
	u_char			digest[16];
	int			secretlen;
	char			*ip_hostname();
	
	VALUE_PAIR	*temp_ptr;

	auth = (AUTH_HDR *)send_buffer;

	temp_ptr=reply;

/*	
	do
	{
		if(strcmp(temp_ptr->name,"Session-Timeout")==0)
		{
			printf("\nname is %s",temp_ptr->name);
			printf("attribute is %d\n",temp_ptr->attribute);
			printf("type is %d\n",temp_ptr->type);
			printf("lvalue is %d\n",temp_ptr->lvalue);
			printf("strvalue is %s\n",temp_ptr->strvalue);
			break;
		}
		temp_ptr=temp_ptr->next;
	}while(temp_ptr!=NULL);
*/	

	/* Build standard header */
	auth->code = PW_AUTHENTICATION_ACK;
	auth->id = authreq->id;
	memcpy(auth->vector, authreq->vector, AUTH_VECTOR_LEN);

	DEBUG("Sending Ack of id %d to %lx (%s)\n",
		authreq->id, (u_long)authreq->ipaddr,
		ip_hostname(authreq->ipaddr));

	total_length = AUTH_HDR_LEN;

	/* Load up the configuration values for the user */
	ptr = auth->data;
	while(reply != (VALUE_PAIR *)NULL) {
		debug_pair(stdout, reply);
		*ptr++ = reply->attribute;

		switch(reply->type) {

		case PW_TYPE_STRING:
			len = strlen(reply->strvalue);
			if (len >= AUTH_STRING_LEN) {
				len = AUTH_STRING_LEN - 1;
			}
			*ptr++ = len + 2;
			memcpy(ptr, reply->strvalue,len);
			ptr += len;
			total_length += len + 2;
			break;
			
		case PW_TYPE_INTEGER:
		case PW_TYPE_IPADDR:
			*ptr++ = sizeof(UINT4) + 2;
			lvalue = htonl(reply->lvalue);
			memcpy(ptr, &lvalue, sizeof(UINT4));
			ptr += sizeof(UINT4);
			total_length += sizeof(UINT4) + 2;
			break;

		default:
			break;
		}

		reply = reply->next;
	}

	/* Append the user message */
	if(msg != (char *)NULL) {
		len = strlen(msg);
		if(len > 0 && len < AUTH_STRING_LEN) {
			*ptr++ = PW_PORT_MESSAGE;
			*ptr++ = len + 2;
			memcpy(ptr, msg, len);
			ptr += len;
			total_length += len + 2;
		}
	}

	auth->length = htons(total_length);

	/* Append secret and calculate the response digest */
	secretlen = strlen(authreq->secret);
	memcpy(send_buffer + total_length, authreq->secret, secretlen);
	md5_calc(digest, (char *)auth, total_length + secretlen);
	memcpy(auth->vector, digest, AUTH_VECTOR_LEN);
	memset(send_buffer + total_length, 0, secretlen);

	sin = (struct sockaddr_in *) &saremote;
        memset ((char *) sin, '\0', sizeof (saremote));
	sin->sin_family = AF_INET;
	sin->sin_addr.s_addr = htonl(authreq->ipaddr);
	sin->sin_port = htons(authreq->udp_port);

	/* Send it to the user */
	sendto(activefd, (char *)auth, (int)total_length, (int)0,
			&saremote, sizeof(struct sockaddr_in));
}



/*************************************************************************
 *
 *	Function: unix_pass
 *
 *	Purpose: Check the users password against the standard UNIX
 *		 password table.
 *
 *************************************************************************/

unix_pass(name, passwd,user_reply)
char	*name;
char	*passwd;
VALUE_PAIR	*user_reply;
{
	int		sockfd, n, i,x=0;
	BYTE		recvline[1500+1];
	struct sockaddr_in	servaddr;
	VALUE_PAIR	session_timeout,*tempptr;
		
	TRANSACTION	tst;
	TRANSACTION	rfs;

	BYTE	recvbuf[1500];
	FILE	*outfile;
	char	msg[128];
	
	time_t	logtime;
	char	thetime[30];

	time(&logtime);
	strcpy(thetime,ctime(&logtime));
	thetime[24]=0;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	
	if(sockfd==-1)
	{
		sprintf(msg,"\nUnix_pass could not open socket!! %s",thetime);
		msg[127]='\0';
		log_err_inf(msg);

		printf("\nUnix_pass could not open socket!! %s",strerror(errno));
		perror("ERROR!!");
		return(-1);
	}

	servaddr.sin_family = AF_INET;
	servaddr.sin_port= htons(XIAOFEI_TCP_PORT);
	servaddr.sin_addr.s_addr=inet_addr(XIAOFEI_IP_ADDR);

	if(connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))<0)
		{
		sprintf(msg,"\nRADIUSD.C无法连接消费系统 %s",thetime);
		msg[127]='\0';
		log_err_inf(msg);
	
		close(sockfd);
		return(-1);

⌨️ 快捷键说明

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