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

📄 radiusd.c

📁 This program is a RADIUS RFC-compliant daemon, which is derived from original Livingston Enterprise
💻 C
📖 第 1 页 / 共 5 页
字号:
  		/*  		 * Check to see if we have a CHAP password.  		 */  		else if ((auth_item = get_attribute(authreq->request,  			PW_CHAP_PASSWORD)) != (VALUE_PAIR *)NULL) {  			/* Use MD5 to verify */  			ptr = string;  			*ptr++ = *auth_item->strvalue;  			strcpy(ptr, password_item->strvalue);  			ptr += strlen(password_item->strvalue);  			if ((challenge = get_attribute(authreq->request,  				PW_CHAP_CHALLENGE)) != (VALUE_PAIR *)NULL) {  				chlen = challenge->lvalue;  				memcpy(ptr, challenge->strvalue, chlen);  			} else {  				chlen = AUTH_VECTOR_LEN;  				memcpy(ptr, authreq->vector, chlen);  			}  			md5_calc(pw_digest, string, 1 + chlen +  				strlen(password_item->strvalue));  			/* Compare them */  			if(memcmp(pw_digest, auth_item->strvalue + 1,  					CHAP_VALUE_LENGTH) != 0) {  				result = -1;  			} else {  				result = 0;  			}  		}  		else if (strcmp(password_item->strvalue, string) == 0) {  			result = 0;  		}  		else {  			result = -1;  		}  		break;  	case PW_AUTHTYPE_UNIX:  		if(unix_pass(auth_name, string, callfrom) != 0) {  			result = -1;  		}  		break;#ifdef SECURID  	case PW_AUTHTYPE_SECURID:  		if(pass != (char *)NULL) {  			pairfree(user_check,"rad_authenticate");  			return( securid(auth_name, string,  				authreq, user_reply, activefd) );  		}  		else {  			result = -1;  		}  		break;#endif /* SECURID */  	case PW_AUTHTYPE_CRYPT:  		/* password is stored encrypted in string */  		if(password_item == (VALUE_PAIR *)NULL) {  			if(string[0] != '\0') {  				result = -1;  			}  		}  		else if (pass != NULL) {  			encpw = (char*)crypt(string,password_item->strvalue);  			if(strcmp(encpw,password_item->strvalue) != 0) {  				result = -1;  			}  		}  		else {  			result = -1;  		}  		break;  	case PW_AUTHTYPE_REJECT:  		result = -1;  		break;#if defined(PAM) && defined(HAVE_LIBPAM)        case PW_AUTHTYPE_PAM:		if (usepamauth) {                     	if (unix_pam(auth_name, string, pam_auth) != 0) {                       		result = -1;                       		user_msg = (char *)NULL;                    	}		}		else {			log_err("PAM auth not enabled. Please re-run daemon with the correct argument");                       	user_msg = (char *)NULL;			result=-1;		}                break;#endif#ifdef ACTIVCARD  	case PW_AUTHTYPE_ACTIVCARD:  		if (pass != (char *)NULL) {  		      pairfree(user_check,"rad_authenticate");  			/* activcard calls send_*() as needed */  		      return ( activcard_auth(auth_name, string,  			      authreq, user_reply, activefd) );  		}  		else {  		      result = -1;  		}  		break;#endif /* ACTIVCARD */  	case PW_AUTHTYPE_NONE:  		/* No Password or Auth-Type found in check-items */  		debug("entry for user \"%s\" has no Password or Auth-Type check-item\n",authreq->name);  		result = 0;  		break;  	default:  		log_err("Warning: entry for user \"%s\" has unknown Auth-Type = %d\n",authreq->name, authtype);  		result = -1;  		break;  	}  }  if(result != 0) {  	send_reject(authreq, user_msg, activefd);  }  else {  	send_accept(authreq, user_reply, user_msg, activefd);  }  reqfree(authreq,"rad_authenticate");  pairfree(user_check,"rad_authenticate");  pairfree(user_reply,"rad_authenticate");  return(0);}/*************************************************************************  *  *	Function: send_reject  *  *	Purpose: Reply to the request with a REJECT.  Also attach  *		 any user message provided.  *  *************************************************************************/void send_reject(AUTH_REQ *authreq,char *msg,int activefd){  u_char			code;  int			total_length;  code = PW_AUTHENTICATION_REJECT;  report[RR_REJECT]++;  debug("sending reject to %s\n", req2strp(authreq));  total_length = build_packet(authreq,(VALUE_PAIR *)NULL,msg,code,                              FW_REPLY,send_buffer,sizeof(send_buffer));  /* Send it to the user */         send_packet(activefd, authreq->ipaddr, authreq->udp_port,  		(u_char*)send_buffer, total_length);}/*************************************************************************  *  *	Function: send_challenge  *  *	Purpose: Reply to the request with a CHALLENGE.  Also attach  *		 any user message provided and a state value.  *  *************************************************************************/void send_challenge(AUTH_REQ *authreq,char *msg,char *state,int activefd){  VALUE_PAIR *reply;  int len;  int total_length;  report[RR_CHALLENGE]++;  if((state != (char *)NULL) && ((len=strlen(state)) > (size_t)0)) {  	reply = pairalloc("send_challenge");  	memcpy(reply->name,"State",5);  	reply->attribute = PW_STATE;  	reply->type = PW_TYPE_STRING;  	if (len > AUTH_STRING_LEN) {  		len = AUTH_STRING_LEN;  	}  	reply->lvalue = len;  	memcpy(reply->strvalue,state,len);  } else {  	reply = (VALUE_PAIR *)NULL;  }  debug("sending challenge to %s\n", req2strp(authreq));  total_length = build_packet(authreq,reply,msg,PW_ACCESS_CHALLENGE,FW_REPLY,send_buffer,sizeof(send_buffer));         send_packet(activefd,authreq->ipaddr,authreq->udp_port,send_buffer,total_length); }/*************************************************************************  *  *	Function: send_accept  *  *	Purpose: Reply to the request with an ACKNOWLEDGE.  Also attach  *		 reply attribute value pairs and any user message provided.  *  *************************************************************************/void send_accept(AUTH_REQ *authreq,VALUE_PAIR *reply,char *msg,int activefd){  VALUE_PAIR		*menu_attr;  char			state_value[120];  int			total_length;  /* Check to see if the response is a menu */  if((menu_attr = get_attribute(reply, PW_MENU)) != (VALUE_PAIR *)NULL) {  	msg = get_menu(menu_attr->strvalue);  	snprintf(state_value,sizeof(state_value),"MENU=%s", menu_attr->strvalue);  	send_challenge(authreq, msg, state_value, activefd);  	return;  }  report[RR_ACCEPT]++;  debug("sending accept to %s\n", req2strp(authreq));  total_length = build_packet(authreq,reply,msg,PW_AUTHENTICATION_ACK,FW_REPLY,send_buffer,sizeof(send_buffer));  /* Send it to the user */         send_packet(activefd, authreq->ipaddr, authreq->udp_port,  		(u_char*)send_buffer, total_length);}/*************************************************************************  *  *	Function: build_packet  *  *	Purpose: called by routines to build RADIUS packet  *  *	forward = 0     FW_REPLY	replying to client  *		  1     FW_SERVER	forwarding request to remote server  *		  2	FW_CLIENT	forwarding response to client  *  *************************************************************************/int build_packet(AUTH_REQ*authreq,VALUE_PAIR*reply,char*msg,u_char code,int forward,u_char*buffer,size_t buflen ){  AUTH_HDR		*auth;  VALUE_PAIR		*item;  u_short		total_length;  u_char		*ptr;  u_char		*lptr;  int			len;  UINT4			lvalue;  UINT4			vendor;  u_char		digest[16];  int			secretlen;  int			block_len;    auth = (AUTH_HDR *)buffer;  /* Build standard header */  auth->code = code;  auth->id = authreq->id;  total_length = AUTH_HDR_LEN;  /* Load up the configuration values for the user */  ptr = auth->data;  while(reply != (VALUE_PAIR *)NULL) {  	debug_pair(reply);  	*ptr++ = reply->attribute;  	lptr = ptr;                 if (reply->attribute == PW_VENDOR && reply->vendor != 0) {  		ptr++;                         total_length += 6;                         vendor = htonl(reply->vendor);                         memcpy(ptr,&vendor,sizeof(UINT4));                         ptr += 4;                         *ptr++ = reply->vsattribute;                         if (reply->type == PW_TYPE_STRING) {                                 *lptr = reply->lvalue + 8;                         } else {                                 *lptr = 12;                         }                 }  	switch(reply->type) {#if defined(ASCEND_BINARY)	case PW_TYPE_ABINARY:#endif  	case PW_TYPE_STRING:  		len = reply->lvalue;  		if (len > AUTH_STRING_LEN) {  			len = AUTH_STRING_LEN;  		}  		*ptr++ = len + 2;  		memcpy(ptr, reply->strvalue,len);  		ptr += len;  		total_length += len + 2;  		break;  	case PW_TYPE_INTEGER:  	case PW_TYPE_IPADDR:  	case PW_TYPE_DATE:  		*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)) > 0) {  	while(len > 0) {  		if(len > AUTH_STRING_LEN) {  			block_len = AUTH_STRING_LEN;  		}  		else {  			block_len = len;  		}  		*ptr++ = PW_PORT_MESSAGE;  		*ptr++ = block_len + 2;  		memcpy(ptr, msg, block_len);  		msg += block_len;  		ptr += block_len;  		total_length += block_len + 2;  		len -= block_len;  	}  }  /* Copy over any proxy-states, in order */  if (forward == FW_REPLY) {  	item = authreq->request;  	while (item != (VALUE_PAIR *)NULL) {  		if (item->attribute == PW_PROXY) {  			debug_pair(item);  			*ptr++ = PW_PROXY;  			len = item->lvalue;  			*ptr++ = len + 2;  			memcpy(ptr,item->strvalue,len);  			ptr += len;  			total_length += len + 2;  		}  		item = item->next;  	}  }  auth->length = htons(total_length);  if (code == PW_AUTHENTICATION_ACK ||      code == PW_AUTHENTICATION_REJECT ||      code == PW_ACCESS_CHALLENGE ||      code == PW_ACCOUNTING_RESPONSE) {         	/*  	   The Authenticator field in an Response packet is  	   called the Response Authenticator, and contains a  	   one-way MD5 hash calculated over a stream of octets  	   consisting of the Response Code, Identifier, Length,  	   the Request Authenticator field from the Request  	   packet being replied to, and the response attributes  	   if any, followed by the shared secret.  The  	   resulting 16 octet MD5 hash value is stored in the  	   Authenticator field of the Response packet.  	 */  	/* Append secret and calculate the response digest */  	memcpy(auth->vector, authreq->vector, AUTH_VECTOR_LEN);  	secretlen = strlen((const char *)authreq->secret);	if ((size_t)(total_length+secretlen)<=buflen) {  		memcpy(buffer + total_length, authreq->secret, secretlen);  		md5_calc(digest, (u_char *)auth, total_length + secretlen);  		memcpy(auth->vector, digest, AUTH_VECTOR_LEN);  		memset(buffer + total_length, 0, secretlen);	}	else { log_err("build_packet: execeeding buffer size"); }  } else if (code == PW_ACCOUNTING_REQUEST) {	/* Forwarding */  		 memset(auth->vector, 0, AUTH_VECTOR_LEN);  		 secretlen = strlen(authreq->forw_secret);		 if ((size_t)(total_length+secretlen)<=buflen) {                 	memcpy(buffer + total_length, authreq->forw_secret, secretlen);                 	md5_calc(digest, buffer, total_length + secretlen);                 	memcpy(auth->vector,digest,AUTH_VECTOR_LEN);                 	memset(buffer + total_length, 0, secretlen);		 }		 else { log_err("build_packet: execeeding buffer size"); }  } else if (code == PW_AUTHENTICATION_REQUEST) {	/* Forwarding */  	memcpy(auth->vector, authreq->vector, AUTH_VECTOR_LEN);  }  return ((int)total_length);}/*************************************************************************  *  *	Function: decrypt_password  *  *	Purpose: decrypts the User-Password attribute in place in  *		 authreq->request using authreq->vector and  *		 secret and the algorithm specified in the  *		 RADIUS RFC, and returns a pointer to the Password   *		 if successful, otherwise NULL  *  *************************************************************************/char * decrypt_password(AUTH_REQ *authreq,char *secret){  VALUE_PAIR 	*auth_item;  int		i;  int		j;  int		passlen;  char		hold_vector[AUTH_VECTOR_LEN];  char		pw_digest[16];  char		*string;  char		*ptr;  calc_digest(pw_digest, authreq, secret);  /*   * Decrypt the password in the request.   */  if((auth_item = get_attribute(authreq->request,  			PW_PASSWORD)) == (VALUE_PAIR *)NULL) {  	return (char *)NULL;  }  passlen = auth_item->lvalue;  if(passlen > AUTH_MAXPASS_LEN) {  	log_err("decrypt_password: Password length %d > %d max not allowed\n",passlen, AUTH_MAXPASS_LEN);  	passlen = AUTH_MAXPASS_LEN;  }  string = auth_item->strvalue;  ptr = string;  for(i = 0;i < passlen;i += AUTH_PASS_LEN) {  	/*  	 * Store the vector to be used in next segment  	 * of the encrypted password.  	 */  	memcpy(hold_vector, ptr, AUTH_VECTOR_LEN);  	/* Decrypt from the digest */  	for(j = 0;j < AUTH_PASS_LEN;j++) {  		*ptr ^= pw_digest[j];  		ptr++;  	}  	/* Calculate the next digest if necessary */  	if(i + AUTH_PASS_LEN < passlen) {  		calc_next_digest((u_char*)pw_digest, (u_char*)secret, (u_char*)hold_vector);  	}  }  *ptr = '\0';	/* this depends on the fact that auth_item->strvalue  			always has an extra byte available */  return string;}/*************************************************************************  *  *	Function: encrypt_password  *  *	Purpose: encrypts the User-Password attribute in place in  *		 authreq->request using authreq->vector and  *		 secret and the algorithm specified in the  *		 RADIUS RFC, and returns a pointer to the Password   *		 if successful, otherwise NULL  *  *************************************************************************/char * encrypt_password(AUTH_REQ *authreq,char *secret){  VALUE_PAIR 	*auth_item;  int		i;  int		j;

⌨️ 快捷键说明

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