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

📄 radclient.c

📁 新的radius程序
💻 C
📖 第 1 页 / 共 2 页
字号:
		 */		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.	 */	if (rad_send(radclient->request, NULL, secret) < 0) {		fprintf(stderr, "radclient: Failed to send packet for ID %d: %s\n",			radclient->request->id, librad_errstr);	}	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: %s\n",			librad_errstr);		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");		rad_free(&reply);		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_verify(reply, radclient->request, secret) != 0) {		librad_perror("rad_verify");		totallost++;		goto packet_done; /* shared secret is incorrect */	}	if (rad_decode(reply, radclient->request, secret) != 0) {		librad_perror("rad_decode");		totallost++;		goto packet_done; /* shared secret is incorrect */	}	/* 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++;	}packet_done:	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;	int persec = 0;	int parallel = 1;	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:n:p:qr:sS:t:vx")) != 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 'i':			if (!isdigit((int) *optarg))				usage();			last_used_id = atoi(optarg);			if ((last_used_id < 0) || (last_used_id > 255)) {				usage();			}			break;		case 'n':			persec = atoi(optarg);			if (persec <= 0) usage();			break;		case 'p':			parallel = atoi(optarg);			if (parallel <= 0) usage();			break;		case 'q':			do_output = 0;			break;		case 'r':			if (!isdigit((int) *optarg))				usage();			retries = atoi(optarg);			if ((retries == 0) || (retries > 1000)) usage();			break;		case 's':			do_summary = 1;			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 't':			if (!isdigit((int) *optarg))				usage();			timeout = atof(optarg);			break;		case 'v':			printf("radclient: $Id: radclient.c,v 1.72.2.1.2.7 2007/04/07 22:22:51 aland Exp $ built on " __DATE__ " at " __TIME__ "\n");			exit(0);			break;		case 'x':			librad_debug++;			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], "challenge") == 0) {		if (server_port == 0) server_port = getport("radius");		if (server_port == 0) server_port = PW_AUTH_UDP_PORT;		packet_code = PW_ACCESS_CHALLENGE;	} 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], "coa") == 0) {		if (server_port == 0) server_port = PW_POD_UDP_PORT;		packet_code = PW_COA_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, InOrder, filename_walk, NULL) != 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 {		int n = parallel;		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, unless '-p' is specified, in			 *	which case N packets from each file			 *	are sent in parallel.			 */			if (this->filename != filename) {				filename = this->filename;				n = parallel;			}			if (n > 0) {				n--;				/*				 *	Send the current packet.				 */				send_one_packet(this);				/*				 *	Wait a little before sending				 *	the next packet, if told to.				 */				if (persec) {					struct timeval tv;					/*					 *	Don't sleep elsewhere.					 */					sleep_time = 0;					if (persec == 1) {						tv.tv_sec = 1;						tv.tv_usec = 0;					} else {						tv.tv_sec = 0;						tv.tv_usec = 1000000/persec;					}										/*					 *	Sleep for milliseconds,					 *	portably.					 *					 *	If we get an error or					 *	a signal, treat it like					 *	a normal timeout.					 */					select(0, NULL, NULL, NULL, &tv);				}				/*				 *	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 + -