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

📄 radiusd.c

📁 This program is a RADIUS RFC-compliant daemon, which is derived from original Livingston Enterprise
💻 C
📖 第 1 页 / 共 5 页
字号:
  int			msg_id;  char			*buf;#endif  salen = sizeof (rad_saremote);  sin = (struct sockaddr_in *) & rad_saremote;  result = recvfrom (fd, (char *) recv_buffer,  	(int) sizeof(recv_buffer),  	(int) 0, (struct sockaddr *)&rad_saremote, &salen);  addr = ntohl(sin->sin_addr.s_addr);  port = ntohs(sin->sin_port);  if (result < AUTH_HDR_LEN) {  	log_err("rad_request: runt packet of %d bytes from %s.%d\n",  		result,ipaddr2strp(addr),port);  	return;  }         /*          * Validate the requesting IP address -          * Not secure, but worth the check for accidental requests          * find_client() logs an error message if needed          */         if(find_client(addr, secret, sizeof(secret), hostnm, sizeof(hostnm)) != 0) {                 log_err("rad_request: request from unknown"   	        " client %s.%d ignored\n",ipaddr2strp(addr),port);                 return;         }  authreq = radrecv( addr, port, secret, recv_buffer, result );  if (authreq == (AUTH_REQ *)NULL) {	/* malformed packet */  	return;  }  /* handle_proxy places the user name in authreq->name,   * and forwards request to a proxy server if necessary   */  if (handle_proxy(authreq) != 0) {	/* error or forwarded */  	if (authreq->flags & REQ_FREE) {  		reqfree(authreq,"rad_request");  	}  	/* otherwise authreq will be freed when proxy response is seen */  	return;  }#if defined(SMARTCARD)  if (spawn_flag == 0) {  	radrespond(authreq, fd);  	return;  }  /*   * We need to see if this is a challenge response   */  child_pid = -1;  if ((pair = get_attribute(authreq->request,PW_STATE)) != (VALUE_PAIR *)NULL) {  	buf = pair->strvalue;  	debug("rad_request: PW_STATE<%s>\n", buf);#ifdef SECURID  	/*  	 * the format for SECURID state string is  	 *  	 *	SECURID_xxxx=n  	 *  	 * xxxx is commands: next or npin or wait  	 * n is the child pid  	 */  	if (strncmp(buf, "SECURID_", 8) == 0) {  		child_pid = (int)atoi(&buf[13]);  	}#endif /* SECURID */#ifdef ACTIVCARD  	/*  	 * the format for ACTIVCARD state string is  	 *  	 *      ACTIVCARD_999...=n  	 *  	 * 999... is the challenge returned by ActivEngine  	 * n is the child pid  	 */  	if (strncmp(buf, "ACTIVCARD_", 10) == 0) {  		child_pid = (int)atoi(strchr(buf, (int)'=')+1);  	}#endif /* ACTIVCARD */  }  if (child_pid == -1) {  	radrespond(authreq, fd);  	return;  }  debug("rad_request: challenge_response from %s for child %d\n",  		req2strp(authreq), child_pid);  curreq = first_request;  while(curreq != (AUTH_REQ *)NULL) {  	if (curreq->child_pid == child_pid) {  		break;  	}  	curreq = curreq->next;  }  if (curreq == (AUTH_REQ *)NULL) {  	log_err("rad_request: child %d not found\n", child_pid);  	reqfree(authreq,"rad_request");  	return;  }  if (curreq->ipaddr != addr) {  	log_err("rad_request: error: mismatched IP addresses in request %x != %x for ID %d %d\n",  		curreq->ipaddr, addr, curreq->id, auth->id);  	reqfree(authreq,"rad_request");  	return;  }  if (curreq->udp_port != port) {  	log_err("rad_request: error: mismatched source ports in request %d != %d for ID %d %d\n",  		curreq->udp_port, port, curreq->id, auth->id);  	reqfree(authreq,"rad_request");  	return;  }  if (curreq->id == authreq->id) {  	/* This is a duplicate request - just drop it */  	log_err("rad_request: dropped duplicate ID %d\n", authreq->id);  	reqfree(authreq,"rad_request");  	return;  }  msg_key = RADIUS_MSG_KEY(child_pid);  if ((msg_id = msgget(msg_key, 0600)) == -1) {  	log_err("rad_request: error: msgget for key %x for id %d returned error %d\n",msg_key, msg_id, errno);  	reqfree(authreq,"rad_request");  	return;  }  if (msgsnd(msg_id, recv_buffer, result, IPC_NOWAIT) == -1) {  	log_err("rad_request: error: msgsnd for key %x for id %d returned error %d\n", msg_key, msg_id, errno);  	reqfree(authreq,"rad_request");  	return;  }  curreq->id = authreq->id;#else /* not SMARTCARD */  radrespond(authreq, fd);#endif /* not SMARTCARD */}/*************************************************************************  *  *	Function: radrecv  *  *	Purpose: Receive UDP client requests, build an authorization request  *		 structure, and attach attribute-value pairs contained in  *		 the request to the new structure.  *  *************************************************************************/AUTH_REQ *radrecv(UINT4	host,u_short udp_port,char* secret,u_char* buffer,int length){  u_char	*ptr;  AUTH_HDR	*auth;  int		totallen;  int		attribute;  int		attrlen;  int		vendor;  int		vsa;  int		vsattrlen;  DICT_ATTR	*attr;  UINT4		lvalue;  VALUE_PAIR	*first_pair;  VALUE_PAIR	*prev;  VALUE_PAIR	*pair;  AUTH_REQ	*authreq;  if (length < AUTH_HDR_LEN) {            /* too short to be real */                 log_err("radrecv: runt packet of %d bytes from %s/%d\n",  		length, ipaddr2strp(host), udp_port);                 return ((AUTH_REQ *)NULL);         }  /*   * Pre-allocate the new request data structure   */  authreq = reqalloc("radrecv");  auth = (AUTH_HDR *)buffer;  totallen = ntohs(auth->length);  if (totallen > length) {	/* truncated packet, ignore */  	log_err("radrecv: message from %s/%d claimed length %d, only %d bytes received\n", ipaddr2strp(host), udp_port, totallen, length);  	reqfree(authreq,"radrecv");  	return((AUTH_REQ *)NULL);  }  debug("message received from %s/%d.%d code=%d, length=%d\n",  	ipaddr2strp(host), udp_port, auth->id, auth->code, totallen);  if (debug_flag > 1) {  	hexdump((u_char*)buffer,totallen);  }  /*   * Fill header fields   */  authreq->ipaddr = host;  authreq->udp_port = udp_port;  authreq->id = auth->id;  authreq->code = auth->code;  memcpy(authreq->vector, auth->vector, AUTH_VECTOR_LEN);  strncpy(authreq->secret,secret,20);  authreq->secret[19]='\0';  /*   * Extract attribute-value pairs   */  ptr = auth->data;  length = totallen - AUTH_HDR_LEN;  first_pair = (VALUE_PAIR *)NULL;  prev = (VALUE_PAIR *)NULL;  while(length > 0) {  	attribute = *ptr++;  	attrlen = *ptr++;  	if(attrlen < 2) {  		length = 0;  		continue;  	}  	attrlen -= 2;  	if ( attrlen > AUTH_STRING_LEN ) {  		log_err("radrecv: attribute %d from %s too long, length of %d > %d\n",  			attribute, req2strp(authreq), attrlen, AUTH_STRING_LEN);  		reqfree(authreq,"radrecv");  		return((AUTH_REQ *)NULL);  	}  	pair = pairalloc("radrecv");  	if((attr = dict_attrget(attribute)) == (DICT_ATTR *)NULL) {  		snprintf(pair->name,(size_t)ID_LENGTH,"Unknown-%d",attribute);  		pair->attribute = attribute;  		pair->type = PW_TYPE_STRING;  	} else {  		strncpy(pair->name, attr->name, VALUE_PAIR_NAME_LEN-1);		pair->name[VALUE_PAIR_NAME_LEN-1]='\0';  		pair->attribute = attr->value;  		pair->type = attr->type;  	}  	if (pair->attribute == PW_VENDOR) {	  		if (attrlen < 6) {  			pair->vendor = 0;  			pair->vsattribute = 0;  			pair->type = PW_TYPE_STRING;  		} else {  			memcpy(&vendor, ptr, sizeof(int));  			vendor = ntohl(vendor);  			ptr += 4;			vsattrlen = *ptr;			if ( vendor == VENDOR_USROBOTICS ) {			  if (attrlen < 8) {   				pair->vendor = 0;  				pair->vsattribute = 0;  				pair->type = PW_TYPE_STRING;			  }			  else {  			  	memcpy(&vsa, ptr, sizeof(int));			  	vsa = ntohl(vsa);  			  	ptr += 4;  			  	attrlen -= 8;			  	length -= 8;			  }			}			else			  {  			  vsa = *ptr;  			  ptr += 2;  			  attrlen -= 6;  			  length -= 6;			  }  			pair->vendor = vendor;  			pair->vsattribute = vsa;  			if((attr = dict_vsattrget(vendor,vsa)) != NULL) {  				strncpy(pair->name, attr->name, VALUE_PAIR_NAME_LEN-1);				pair->name[VALUE_PAIR_NAME_LEN-1]='\0';  				pair->type = attr->type;  			} else {				log_debug("Attribute %d for vendor %d not found\n",vsa,vendor);  				snprintf(pair->name,(size_t)ID_LENGTH,"Vendor-Specific-%d-%d",vendor,vsa);  				pair->type = PW_TYPE_STRING;  			}  		}  	}  	switch(pair->type) {#if defined(ASCEND_BINARY)	case PW_TYPE_ABINARY:#endif  	case PW_TYPE_STRING:  		memcpy(pair->strvalue, ptr, attrlen);  		pair->strvalue[attrlen] = '\0';  		pair->lvalue = attrlen;  		debug_pair(pair);  		if(first_pair == (VALUE_PAIR *)NULL) {  			first_pair = pair;  		}  		else {  			prev->next = pair;  		}  		prev = pair;  		break;  	case PW_TYPE_INTEGER:  	case PW_TYPE_IPADDR:  	case PW_TYPE_DATE:  		memcpy(&lvalue, ptr, sizeof(UINT4));  		pair->lvalue = ntohl(lvalue);  		debug_pair(pair);  		if(first_pair == (VALUE_PAIR *)NULL) {  			first_pair = pair;  		}  		else {  			prev->next = pair;  		}  		prev = pair;  		break;  	default:  		debug("    %s (Unknown Type %d)\n",  			attr->name,attr->type);  		pairfree(pair,"radrecv");  		break;  	}  	ptr += attrlen;  	length -= attrlen + 2;  }  authreq->request = first_pair;  authreq->timestamp = now;	/* now was set in main() */  /* copy the packet */  authreq->packet = bufalloc(totallen,"radrecv");  memcpy(authreq->packet,buffer,totallen);  return(authreq);}/*************************************************************************  *  *	Function: radrespond  *  *	Purpose: Respond to supported requests  *  *		 PW_AUTHENTICATION_REQUEST - Authentication request from  *				a client network access server.  *  *************************************************************************/void radrespond(AUTH_REQ *authreq,int activefd){         if (authreq == (AUTH_REQ *)NULL) {                 return;         }  switch(authreq->code) {  case PW_AUTHENTICATION_REQUEST:  	if(spawn_flag) {  		rad_spawn_child(authreq, activefd);  	}  	else {  		rad_authenticate(authreq, activefd);  	}  	break;    default:  	log_err("unknown request type %d from %s ignored\n",  		authreq->code, req2strp(authreq));  	reqfree(authreq,"radrespond");  	break;  }}/*************************************************************************  *  *	Function: rad_spawn_child  *  *	Purpose: Spawns child processes to perform password authentication  *		 and respond to RADIUS clients.  This functions also  *		 cleans up complete child requests, and verifies that there  *		 is only one process responding to each request (duplicate  *		 requests are filtered out.  *  *************************************************************************/int rad_spawned_child_pid;void rad_spawn_child(AUTH_REQ *authreq,int activefd){  AUTH_REQ	*curreq;  AUTH_REQ	*prevreq;  UINT4		curtime;  int		request_count;  int		child_pid;#ifdef SMARTCARD  key_t		msg_key;  int		msg_id;#endif  curtime = authreq->timestamp;  request_count = 0;  curreq = first_request;  prevreq = (AUTH_REQ *)NULL;  while(curreq != (AUTH_REQ *)NULL) {  	if(curreq->child_pid == -1 &&  			curreq->timestamp + CLEANUP_DELAY <= curtime) {  		/* Request completed, delete it */  		if(prevreq == (AUTH_REQ *)NULL) {  			first_request = curreq->next;  			reqfree(curreq,"rad_spawn_child");  			curreq = first_request;  		}  		else {  			prevreq->next = curreq->next;  			reqfree(curreq,"rad_spawn_child");  			curreq = prevreq->next;  		}  	}  	else if(curreq->ipaddr == authreq->ipaddr &&  			curreq->udp_port == authreq->udp_port &&  			curreq->id == authreq->id) {  		/* This is a duplicate request - just drop it */  		log_err("dropping duplicate request from %s\n",  			req2strp(authreq));  		reqfree(authreq,"rad_spawn_child");  		return;  	}  	else {  		if(curreq->timestamp + max_request_time <= curtime &&  					curreq->child_pid != -1) {  			/* This request seems to have hung - kill it */  			child_pid = curreq->child_pid;  			log_err("sending SIGHUP to unresponsive child process %d\n",  							child_pid);  			curreq->child_pid = -1;  			kill(child_pid, SIGHUP);#ifdef SMARTCARD  			/*  			 * delete childs message queue  			 */  			msg_key = RADIUS_MSG_KEY(child_pid);  			if ((msg_id = msgget(msg_key, 0600)) != -1) {  				msgctl(msg_id, IPC_RMID, 0);  			}#endif /* SMARTCARD */  		}  		prevreq = curreq;  		curreq = curreq->next;  		request_count++;  	}  }  /* This is a new request */  if(request_count > max_requests) {  	request_count--;  	log_err("dropping request from %s; %d requests already in queue\n",  		req2strp(authreq), request_count);  	reqfree(authreq,"rad_spawn_child");  	return;  }  /* Add this request to the list */  /* authreq->timestamp already set by radrecv */  authreq->next = (AUTH_REQ *)NULL;  authreq->child_pid = -1;  if(prevreq == (AUTH_REQ *)NULL) {  	first_request = authreq;  }  else {  	prevreq->next = authreq;  }

⌨️ 快捷键说明

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