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

📄 radclient.c

📁 radius server在linux下的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		 *	Duplicate found.  Serious error!		 */		if (rbtree_insert(request_tree, radclient) == 0) {			assert(0 == 1);		}	} else {		/* radclient->request->id >= 0 */		time_t now = time(NULL);		/*		 *	FIXME: Accounting packets are never retried!		 *	The Acct-Delay-Time attribute is updated to		 *	reflect the delay, and the packet is re-sent		 *	from scratch!		 */		/*		 *	Not time for a retry, do so.		 */		if ((now - radclient->timestamp) < timeout) {			/*			 *	When we walk over the tree sending			 *	packets, we update the minimum time			 *	required to sleep.			 */			if ((sleep_time == -1) ||			    (sleep_time > (now - radclient->timestamp))) {				sleep_time = now - radclient->timestamp;			}			return 0;		}		/*		 *	We're not trying later, maybe the packet is done.		 */		if (radclient->tries == retries) {			rbnode_t *node;			assert(radclient->request->id >= 0);						/*			 *	Delete the request from the tree of			 *	outstanding requests.			 */			node = rbtree_find(request_tree, radclient);			assert(node != NULL);						fprintf(stderr, "radclient: no response from server for ID %d\n", radclient->request->id);			rbtree_delete(request_tree, node);						/*			 *	Normally we mark it "done" when we've received			 *	the response, but this is a special case.			 */			if (radclient->resend == resend_count) {				radclient->done = 1;			}			totallost++;			return -1;		}		/*		 *	We are trying later.		 */		radclient->timestamp = now;		radclient->tries++;	}	/*	 *	Send the packet.	 */	rad_send(radclient->request, NULL, secret);	return 0;}/* *	Receive one packet, maybe. */static int recv_one_packet(int wait_time){	fd_set		set;	struct timeval  tv;	radclient_t	myclient, *radclient;	RADIUS_PACKET	myrequest, *reply;	rbnode_t	*node;	/* And wait for reply, timing out as necessary */	FD_ZERO(&set);	FD_SET(sockfd, &set);	if (wait_time <= 0) {		tv.tv_sec = 0;	} else {		tv.tv_sec = wait_time;	}	tv.tv_usec = 0;	/*	 *	No packet was received.	 */	if (select(sockfd + 1, &set, NULL, NULL, &tv) != 1) {		return 0;	}	/*	 *	Look for the packet.	 */	reply = rad_recv(sockfd);	if (!reply) {		fprintf(stderr, "radclient: received bad packet\n");		return -1;	/* bad packet */	}	myclient.request = &myrequest;	myrequest.id = reply->id;	myrequest.dst_ipaddr = reply->src_ipaddr;	myrequest.dst_port = reply->src_port;	node = rbtree_find(request_tree, &myclient);	if (!node) {		fprintf(stderr, "radclient: received response to request we did not send.\n");		return -1;	/* got reply to packet we didn't send */	}	radclient = rbtree_node2data(request_tree, node);	assert(radclient != NULL);	rbtree_delete(request_tree, node);	assert(radclient->request->id == -1);	assert(radclient->request->data == NULL);	assert(radclient->reply == NULL);	radclient->reply = reply;	/*	 *	FIXME: Do stuff to process the reply.	 */	if (rad_decode(reply, radclient->request, secret) != 0) {		librad_perror("rad_decode");		totallost++;		return -1;	}	/* libradius debug already prints out the value pairs for us */	if (!librad_debug && do_output) {		printf("Received response ID %d, code %d, length = %d\n",		       reply->id, reply->code, reply->data_len);		vp_printlist(stdout, reply->vps);	}	if (reply->code != PW_AUTHENTICATION_REJECT) {		totalapp++;	} else {		totaldeny++;	}	if (radclient->reply) rad_free(&radclient->reply);	/*	 *	Once we've sent the packet as many times as requested,	 *	mark it done.	 */	if (radclient->resend == resend_count) {		assert((node = rbtree_find(request_tree, radclient)) == NULL);		radclient->done = 1;	}	return 0;}static int getport(const char *name){	struct	servent		*svp;	svp = getservbyname (name, "udp");	if (!svp) {		return 0;	}	return ntohs(svp->s_port);}int main(int argc, char **argv){	char *p;	int c;	const char *radius_dir = RADDBDIR;	char filesecret[256];	FILE *fp;	int do_summary = 0;	radclient_t	*this;	librad_debug = 0;	filename_tree = rbtree_create(filename_cmp, NULL, 0);	if (!filename_tree) {		fprintf(stderr, "radclient: Out of memory\n");		exit(1);	}	request_tree = rbtree_create(request_cmp, request_free, 0);	if (!request_tree) {		fprintf(stderr, "radclient: Out of memory\n");		exit(1);	}	while ((c = getopt(argc, argv, "c:d:f:hi:qst:r:S:xv")) != EOF) switch(c) {		case 'c':			if (!isdigit((int) *optarg))				usage();			resend_count = atoi(optarg);			break;		case 'd':			radius_dir = optarg;			break;		case 'f':			rbtree_insert(filename_tree, optarg);			break;		case 'q':			do_output = 0;			break;		case 'x':			librad_debug++;			break;		case 'r':			if (!isdigit((int) *optarg))				usage();			retries = atoi(optarg);			if ((retries == 0) || (retries > 1000)) usage();			break;		case 'i':			if (!isdigit((int) *optarg))				usage();			last_used_id = atoi(optarg);			if ((last_used_id < 0) || (last_used_id > 255)) {				usage();			}			break;		case 's':			do_summary = 1;			break;		case 't':			if (!isdigit((int) *optarg))				usage();			timeout = atof(optarg);			break;		case 'v':			printf("radclient: $Id: radclient.c,v 1.72.2.1 2004/06/02 15:31:53 aland Exp $ built on " __DATE__ " at " __TIME__ "\n");			exit(0);			break;               case 'S':		       fp = fopen(optarg, "r");                       if (!fp) {                               fprintf(stderr, "radclient: Error opening %s: %s\n",                                       optarg, strerror(errno));                               exit(1);                       }                       if (fgets(filesecret, sizeof(filesecret), fp) == NULL) {                               fprintf(stderr, "radclient: Error reading %s: %s\n",                                       optarg, strerror(errno));                               exit(1);                       }		       fclose(fp);                       /* truncate newline */		       p = filesecret + strlen(filesecret) - 1;		       while ((p >= filesecret) &&			      (*p < ' ')) {			       *p = '\0';			       --p;		       }                       if (strlen(filesecret) < 2) {                               fprintf(stderr, "radclient: Secret in %s is too short\n", optarg);                               exit(1);                       }                       secret = filesecret;		       break;		case 'h':		default:			usage();			break;	}	argc -= (optind - 1);	argv += (optind - 1);	if ((argc < 3)  ||	    ((secret == NULL) && (argc < 4))) {		usage();	}	if (dict_init(radius_dir, RADIUS_DICTIONARY) < 0) {		librad_perror("radclient");		return 1;	}	/*	 *	Strip port from hostname if needed.	 */	if ((p = strchr(argv[1], ':')) != NULL) {		*p++ = 0;		server_port = atoi(p);	}	/*	 *	Grab the socket.	 */	if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {		perror("radclient: socket: ");		exit(1);	}	memset(radius_id, 0, sizeof(radius_id));	/*	 *	See what kind of request we want to send.	 */	if (strcmp(argv[2], "auth") == 0) {		if (server_port == 0) server_port = getport("radius");		if (server_port == 0) server_port = PW_AUTH_UDP_PORT;		packet_code = PW_AUTHENTICATION_REQUEST;	} else if (strcmp(argv[2], "acct") == 0) {		if (server_port == 0) server_port = getport("radacct");		if (server_port == 0) server_port = PW_ACCT_UDP_PORT;		packet_code = PW_ACCOUNTING_REQUEST;		do_summary = 0;	} else if (strcmp(argv[2], "status") == 0) {		if (server_port == 0) server_port = getport("radius");		if (server_port == 0) server_port = PW_AUTH_UDP_PORT;		packet_code = PW_STATUS_SERVER;	} else if (strcmp(argv[2], "disconnect") == 0) {		if (server_port == 0) server_port = PW_POD_UDP_PORT;		packet_code = PW_DISCONNECT_REQUEST;	} else if (strcmp(argv[2], "auto") == 0) {		packet_code = -1;	} else if (isdigit((int) argv[2][0])) {		if (server_port == 0) server_port = getport("radius");		if (server_port == 0) server_port = PW_AUTH_UDP_PORT;		packet_code = atoi(argv[2]);	} else {		usage();	}	/*	 *	Resolve hostname.	 */	server_ipaddr = ip_getaddr(argv[1]);	if (server_ipaddr == INADDR_NONE) {		fprintf(stderr, "radclient: Failed to find IP address for host %s\n", argv[1]);		exit(1);	}	/*	 *	Add the secret.	 */	if (argv[3]) secret = argv[3];	/*	 *	If no '-f' is specified, we're reading from stdin.	 */	if (rbtree_num_elements(filename_tree) == 0) {		rbtree_insert(filename_tree, "-");	}	/*	 *	Walk over the list of filenames, creating the requests.	 */	if (rbtree_walk(filename_tree, filename_walk, InOrder) != 0) {		exit(1);	}	/*	 *	No packets read.  Die.	 */	if (!radclient_head) {		fprintf(stderr, "radclient: Nothing to send.\n");		exit(1);	}	/*	 *	Walk over the list of packets, sanity checking	 *	everything.	 */	for (this = radclient_head; this != NULL; this = this->next) {		if (radclient_sane(this) != 0) {			exit(1);		}	}	if (last_used_id < 0) last_used_id = getpid() & 0xff;	/*	 *	Walk over the packets to send, until	 *	we're all done.	 *	 *	FIXME: This currently busy-loops until it receives	 *	all of the packets.  It should really have some sort of	 *	send packet, get time to wait, select for time, etc.	 *	loop.	 */	do {		radclient_t *next;		const char *filename = NULL;		done = 1;		sleep_time = -1;		/*		 *	Walk over the packets, sending them.		 */		for (this = radclient_head; this != NULL; this = next) {			next = this->next;			/*			 *	If there's a packet to receive,			 *	receive it, but don't wait for a			 *	packet.			 */			recv_one_packet(0);			/*			 *	This packet is done.  Delete it.			 */			if (this->done) {				radclient_free(this);				continue;			}			/*			 *	Packets from multiple '-f' are sent			 *	in parallel.  Packets from one file			 *	are sent in series.			 */			if (this->filename != filename) {				filename = this->filename;				/*				 *	Send the current packet.				 */				send_one_packet(this);				/*				 *	If we haven't sent this packet				 *	often enough, we're not done,				 *	and we shouldn't sleep.				 */				if (this->resend < resend_count) {					done = 0;					sleep_time = 0;				}			} else { /* haven't sent this packet, we're not done */				assert(this->done == 0);				assert(this->reply == NULL);				done = 0;			}		}		/*		 *	Still have outstanding requests.		 */		if (rbtree_num_elements(request_tree) > 0) {			done = 0;		} else {			sleep_time = 0;		}		/*		 *	Nothing to do until we receive a request, so		 *	sleep until then.  Once we receive one packet,		 *	we go back, and walk through the whole list again,		 *	sending more packets (if necessary), and updating		 *	the sleep time.		 */		if (!done && (sleep_time > 0)) {			recv_one_packet(sleep_time);		}	} while (!done);	rbtree_free(filename_tree);	rbtree_free(request_tree);	if (do_summary) {		printf("\n\t   Total approved auths:  %d\n", totalapp);		printf("\t     Total denied auths:  %d\n", totaldeny);		printf("\t       Total lost auths:  %d\n", totallost);	}	return 0;}

⌨️ 快捷键说明

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