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

📄 radiusd.c

📁 This program is a RADIUS RFC-compliant daemon, which is derived from original Livingston Enterprise
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (C) 1999-2004 Francesco P. Lovergine.  * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms stated in the LICENSE file which should be * enclosed with sources. */static char rcsid[] = "$Id: radiusd.c,v 1.9.4.3 2004/08/27 21:45:16 flovergine Exp $";#define __MAIN__#include        "yard.h"#include        "global.h"static AUTH_REQ	*first_request;/* *	 */int main( int argc,char **argv ){  UINT4	then;  char	argval;  char	argnum;  int	i;  int	t;  int	pid;  fd_set	readfds;  int		status;  progname = *argv++;  argc--;  sockaddr = 0;  debug_flag = 0;  debug_mem = 0;  spawn_flag = 0;  radius_gdbm = 0;  accept_zero = 0;  do_clean = 0;  max_requests = MAX_REQUESTS;  max_request_time = MAX_REQUEST_TIME;  max_proxy_time = MAX_PROXY_TIME;  radacct_dir = RADACCT_DIR;  radius_dir = RADIUS_DIR;  alt_passwd = (char *)NULL;  signal(SIGHUP, sig_hup);  signal(SIGINT, sig_fatal);	  /* disable handler when debugging */  signal(SIGQUIT, sig_fatal);  signal(SIGILL, sig_fatal);  signal(SIGTRAP, sig_fatal);#if defined(SIGABRT)		/* SIGABRT is POSIX.1 */  signal(SIGABRT, sig_fatal);#else  signal(SIGIOT, sig_fatal);	/* SIGIOT is obsolete */#endif  signal(SIGFPE, sig_fatal);  signal(SIGTERM, sig_fatal);  signal(SIGCHLD, sig_cleanup);#if defined(SIGWINCH)  signal(SIGWINCH, sig_hup);#endif  signal(SIGUSR1, sig_usr1);  signal(SIGUSR2, sig_usr2);  for (i=0; i< RR_MAX; i++) { report[i] = 0; }  while(argc) {  	if(**argv != '-') usage();  	argval = *(*argv + 1);  	argnum = *(*argv + 2);  	argc--;  	argv++;  	switch(argval) {  	case 'a':  		if(argc == 0) usage();  		radacct_dir = *argv;  		argc--;  		argv++;  		break;  	case 'b':	/* use gdbm users file */  		radius_gdbm = 1;  		break;        case 'c':              	do_clean++;              	break;  	case 'd':  		if(argc == 0) usage();  		radius_dir = *argv;  		argc--;  		argv++;  		break;  	case 'f':  		if(argc == 0) usage();  		alt_passwd = *argv;  		argc--;  		argv++;  		break;  	case 'h':  		usage();  		break;  	case 'i':  		if(argc == 0) usage();  		sockaddr = get_ipaddr(*argv);  		argc--;  		argv++;  		break;  	case 'l':	/* change logging from syslog */  		if(argc == 0) usage();  		radius_log = *argv;  		argc--;  		argv++;  		break;  	case 'm':	/* debug memory */  		if (isdigit(argnum)) debug_mem = argnum - '0';  		else debug_mem++;  		break;  	case 'p':	/* set radius port */  		if(argc == 0) usage();  		radius_port = (u_short)atoi(*argv);  		argc--;  		argv++;  		break;  	case 'o':	/* accept all-zero accounting request authenticators */  		accept_zero = 1;  		break;  	case 'q':	/* set max queue size */  		if(argc == 0) usage();  		max_requests = (int)atoi(*argv);  		argc--;  		argv++;  		break;  	case 's':	/* spawing processes mode */  		spawn_flag = 1;  		break;  	case 't':	/* set max time out in seconds */  		if(argc == 0) usage();  		max_request_time = (int)atoi(*argv);  		argc--;  		argv++;  		break;  	case 'v':  		version();  		break;  	case 'w':	/* set proxy time in seconds */  		if(argc == 0) usage();  		max_proxy_time = (int)atoi(*argv);  		argc--;  		argv++;  		break;  	case 'x':  		if (isdigit(argnum))  		  debug_flag = argnum - '0';  		else debug_flag++;  		break;  	case 'z':  		/* debugging: -b -s -x -d . -a ra */  		radius_gdbm = 1;  		spawn_flag = 0;  		debug_flag++;  		radius_dir = ".";  		radacct_dir = "ra";  		break;#if defined(PAM)		case 'P':		usepamauth=1;		break;	case 'A':		usepamacct=1;		break;#endif  	default:  		usage();  		break;  	}  }  if (debug_flag) {  	if (radius_log == NULL) {  		/*  		 * for backward compatibility  		 * send messages to users tty  		 */  		radius_log = "/dev/tty";  	} else if (strcmp(radius_log, "syslog") == 0) {  		/*  		 * allow user to override backward compatibility  		 * and send debug to syslog  		 */  		radius_log = (char *)NULL;  	}  }  debug("initializing dictionary\n");  /* Initialize the dictionary */  if(dict_init() != 0) { rad_exit(-1); }  dict_dump();  debug("initializing configuration values\n");  /* Initialize Configuration Values */  if(config_init() != 0) { rad_exit(-1); }  /*   *	Disconnect from session   */  debug("Disconnecting from session\n");  if(debug_flag == 0) {  	pid = fork();  	if(pid < 0) {  		log_err("system error: could not fork at startup\n");  		rad_exit(-1);  	}  	if(pid > 0) {  		exit(0);  	}  }  /*   *	Disconnect from tty   */  debug("Disconnecting from tty\n");  for (t = 32; t >= 3; t--) { close(t); }  /* Show our stuff */  log_version();  if (debug_flag) { log_err("debug mode %d\n",debug_flag); }  if (debug_mem)  { log_err("memory debug mode %d\n",debug_mem); }  /* Open RADIUS socket */  sockfd = open_udpsock(&radius_port,PW_AUTH_UDP_PORT,"radius");  /* Open Accounting socket */  radacct_port = radius_port + 1;  acctfd = open_udpsock(&radacct_port,PW_ACCT_UDP_PORT,"radacct");  /*   * Open Proxy Socket.   * We send to proxy servers from this socket, so replies return to it   */  radproxy_port = radius_port + 5;  radpracct_port = radius_port + 6;  proxyfd = open_udpsock(&radproxy_port,PW_PROXY_UDP_PORT,"radius-proxy");  proxyacctfd = open_udpsock(&radpracct_port,PW_PROXYACCT_UDP_PORT,"radacct-proxy");  if (ipassinit() != 0) { log_err("ipass not in use\n"); }#ifdef ACTIVCARD  /* establish aeg session before attending to any user requests */  if (activcard_init() < 0) { log_err("activcard not in use\n"); }#endif  update_clients();  update_proxy();#ifdef VPORTS         vports_flag = vports_init();         if (vports_flag == 1 && spawn_flag == 1) {                 spawn_flag = 0;                 debug("virtual ports disable spawning\n");         }#endif /* VPORTS */  /*   * If we are able to spawn processes, we will start a child   * to listen for Accounting-Requests.  If not, we will    * listen for them ourself.   */  if(spawn_flag) {  	acct_pid = fork();  	if(acct_pid < 0) {  		log_err("could not fork to spawn accounting daemon\n");  		rad_exit(-1);  	}  	if(acct_pid > 0) {  		close(acctfd);  		acctfd = -1;  		close(proxyacctfd);  		proxyacctfd = -1;  	}  	else {  		close(sockfd);  		sockfd = -1;  		close(proxyfd);  		proxyfd = -1;  	}  }  then = 0;  /*   *	Receive user requests   */  for(;;) {  	FD_ZERO(&readfds);  	if(sockfd >= 0) { FD_SET(sockfd, &readfds); }  	if(proxyfd >= 0) { FD_SET(proxyfd, &readfds); }  	if(acctfd >= 0) { FD_SET(acctfd, &readfds); }  	if(proxyacctfd >= 0) { FD_SET(proxyacctfd, &readfds); }  	status = select(32, &readfds, NULL, NULL, (struct timeval *)NULL);  	if(status == -1) {  		if (errno == EINTR)  			continue;  		log_err("exiting after select returned error %d, %s\n",errno,strerror(errno));  		sig_fatal(101);  	}  	now = (UINT4)time((time_t *)NULL);  	if (now > then) {  		then = now;  		if(sockfd != -1) { update_clients(); }  		update_proxy();  	}  	if(proxyfd >=0 && FD_ISSET(proxyfd, &readfds)) {  		rad_proxy(proxyfd);  		report[RR_PORT3]++;  	}  	if(sockfd >= 0 && FD_ISSET(sockfd, &readfds)) {  		rad_request(sockfd);  		report[RR_PORT1]++;  	}  	if(proxyacctfd >=0 && FD_ISSET(proxyacctfd, &readfds)) {  		rad_proxy(proxyacctfd);  		report[RR_PORT4]++;  	}  	if(acctfd >=0 && FD_ISSET(acctfd, &readfds)) {  		rad_acctreq(acctfd);  		report[RR_PORT2]++;  	}  }}/*************************************************************************  *  *	Function: open_udpsock  *  *	Purpose: open desired UDP socket and return file descripter  *		 Exit program if socket is unavailable  *		 place port number used in first argument  *  *************************************************************************/int open_udpsock(u_short *port,int defport,char *service){  int		fd;  int		result;  struct	servent		*svp;  struct	sockaddr_in	*sin;  struct	sockaddr_in	salocal;  u_short       lport;  if (*port>5) { 	lport = htons(*port);   } else {  	svp = getservbyname(service, "udp");  	if (svp != (struct servent *) NULL) {  		lport = (u_short) svp->s_port;  	} else {  		lport = htons(defport);  	}  	*port = ntohs(lport);  }  debug("using udp port %d for %s\n", *port,service);  fd = socket (AF_INET, SOCK_DGRAM, 0);  if (fd < 0) {  	log_err("%s socket error %s\n", service, strerror(errno));  	rad_exit(-1);  }  sin = (struct sockaddr_in *) & salocal;  memset ((char *) sin, '\0', sizeof (salocal));  sin->sin_family = AF_INET;  if (sockaddr != 0) {  	sin->sin_addr.s_addr = htonl(sockaddr);  } else {  	sin->sin_addr.s_addr = INADDR_ANY;  }  sin->sin_port = lport;  result = bind (fd, (struct sockaddr *)&salocal, sizeof (*sin));  if (result < 0) {  	log_err("%s bind error %s\n", service, strerror(errno));  	rad_exit(-1);  }  return fd;}/*************************************************************************  *  *	Function: send_packet  *  *	Purpose: Send RADIUS UDP packet  *  *************************************************************************/void send_packet(int fd, UINT4 ipaddr, u_short port, char * buffer, int length){  AUTH_HDR		*auth;  struct	sockaddr_in	saremote;  struct	sockaddr_in	*sin;  sin = (struct sockaddr_in *) &saremote;         memset ((char *) sin, '\0', sizeof (saremote));  sin->sin_family = AF_INET;  sin->sin_addr.s_addr = htonl(ipaddr);  sin->sin_port = htons(port);  auth = (AUTH_HDR *)buffer;  debug("message sent to %s/%d.%d code=%d, length=%d\n",  	ipaddr2strp(ipaddr), port, auth->id, auth->code, length);  if (debug_flag > 1) {  	hexdump((u_char*)buffer,length);  }  /* Send it */  sendto(fd, buffer, (int)length, (int)0,  	(struct sockaddr *)&saremote, sizeof(struct sockaddr_in));}/*************************************************************************  *  *	Function: rad_request  *  *	Purpose: Receive UDP client requests  *  *************************************************************************/void rad_request(int fd){  AUTH_REQ		*authreq;  UINT4			addr;  char			secret[20];  char			hostnm[128];  int			result;  size_t			salen;  struct	sockaddr_in	*sin;  u_short			port;#if defined(SMARTCARD)  int			child_pid;  AUTH_HDR		*auth;  AUTH_REQ		*curreq;  VALUE_PAIR		*pair;  key_t			msg_key;

⌨️ 快捷键说明

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