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

📄 radclient.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		 */		if (radclient->tries == retries) {			assert(radclient->request->id >= 0);			/*			 *	Delete the request from the tree of			 *	outstanding requests.			 */			fr_packet_list_yank(pl, radclient->request);			fprintf(stderr, "radclient: no response from server for ID %d socket %d\n", radclient->request->id, radclient->request->sockfd);			deallocate_id(radclient);			/*			 *	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);	}	if (librad_debug > 2) print_hex(radclient->request);	return 0;}/* *	Receive one packet, maybe. */static int recv_one_packet(int wait_time){	fd_set		set;	struct timeval  tv;	radclient_t	*radclient;	RADIUS_PACKET	*reply, **request_p;	volatile int max_fd;	/* And wait for reply, timing out as necessary */	FD_ZERO(&set);	max_fd = fr_packet_list_fd_set(pl, &set);	if (max_fd < 0) exit(1); /* no sockets to listen on! */	if (wait_time <= 0) {		tv.tv_sec = 0;	} else {		tv.tv_sec = wait_time;	}	tv.tv_usec = 0;	/*	 *	No packet was received.	 */	if (select(max_fd, &set, NULL, NULL, &tv) <= 0) {		return 0;	}	/*	 *	Look for the packet.	 */	reply = fr_packet_list_recv(pl, &set);	if (!reply) {		fprintf(stderr, "radclient: received bad packet: %s\n",			librad_errstr);		return -1;	/* bad packet */	}	/*	 *	udpfromto issues.  We may have bound to "*",	 *	and we want to find the replies that are sent to	 *	(say) 127.0.0.1.	 */	reply->dst_ipaddr = client_ipaddr;	if (librad_debug > 2) print_hex(reply);	request_p = fr_packet_list_find_byreply(pl, reply);	if (!request_p) {		fprintf(stderr, "radclient: received response to request we did not send. (id=%d socket %d)\n", reply->id, reply->sockfd);		rad_free(&reply);		return -1;	/* got reply to packet we didn't send */	}	radclient = fr_packet2myptr(radclient_t, request, request_p);	/*	 *	Fails the signature validation: not a real reply.	 *	FIXME: Silently drop it and listen for another packet.	 */	if (rad_verify(reply, radclient->request, secret) < 0) {		librad_perror("rad_verify");		totallost++;		goto packet_done; /* shared secret is incorrect */	}	fr_packet_list_yank(pl, radclient->request);	if (print_filename) printf("%s:%d %d\n",				   radclient->filename,				   radclient->packet_number,				   reply->code);	deallocate_id(radclient);	radclient->reply = reply;	/*	 *	If this fails, we're out of memory.	 */	if (rad_decode(reply, radclient->request, secret) != 0) {		librad_perror("rad_decode");		totallost++;		goto packet_done;	}	/* 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->resend == resend_count) {		radclient->done = 1;	} packet_done:	rad_free(&radclient->reply);	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;	int force_af = AF_UNSPEC;	librad_debug = 0;	filename_tree = rbtree_create(filename_cmp, NULL, 0);	if (!filename_tree) {		fprintf(stderr, "radclient: Out of memory\n");		exit(1);	}	while ((c = getopt(argc, argv, "46c:d:f:Fhi:n:p:qr:sS:t:vx")) != EOF) switch(c) {		case '4':			force_af = AF_INET;			break;		case '6':			force_af = AF_INET6;			break;		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 'F':			print_filename = 1;			break;		case 'i':	/* currently broken */			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;			/*			 *	Note that sending MANY requests in			 *	parallel can over-run the kernel			 *	queues, and Linux will happily discard			 *	packets.  So even if the server responds,			 *	the client may not see the response.			 */		case 'p':			parallel = atoi(optarg);			if (parallel <= 0) usage();			break;		case 'q':			do_output = 0;			fr_log_fp = NULL; /* no output from you, either! */			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.120 2008/04/03 13:43:12 aland Exp $ built on " __DATE__ " at " __TIME__ "\n");			exit(0);			break;		case 'x':			librad_debug++;			fr_log_fp = stdout;			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;	}	/*	 *	Resolve hostname.	 */	server_ipaddr.af = force_af;	if (strcmp(argv[1], "-") != 0) {		const char *hostname = argv[1];		const char *portname = argv[1];		char buffer[256];		if (*argv[1] == '[') { /* IPv6 URL encoded */			p = strchr(argv[1], ']');			if ((size_t) (p - argv[1]) >= sizeof(buffer)) {				usage();			}			memcpy(buffer, argv[1] + 1, p - argv[1] - 1);			buffer[p - argv[1] - 1] = '\0';			hostname = buffer;			portname = p + 1;		}		p = strchr(portname, ':');		if (p && (strchr(p + 1, ':') == NULL)) {			*p = '\0';			portname = p + 1;		} else {			portname = NULL;		}		if (ip_hton(hostname, force_af, &server_ipaddr) < 0) {			fprintf(stderr, "radclient: Failed to find IP address for host %s: %s\n", hostname, strerror(errno));			exit(1);		}		/*		 *	Strip port from hostname if needed.		 */		if (portname) server_port = atoi(portname);	}	/*	 *	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();	}	/*	 *	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);	}	/*	 *	Bind to the first specified IP address and port.	 *	This means we ignore later ones.	 */	if (radclient_head->request->src_ipaddr.af == AF_UNSPEC) {		memset(&client_ipaddr, 0, sizeof(client_ipaddr));		client_ipaddr.af = server_ipaddr.af;		client_port = 0;	} else {		client_ipaddr = radclient_head->request->src_ipaddr;		client_port = radclient_head->request->src_port;	}	sockfd = fr_socket(&client_ipaddr, client_port);	if (sockfd < 0) {		fprintf(stderr, "radclient: socket: %s\n", librad_errstr);		exit(1);	}	pl = fr_packet_list_create(1);	if (!pl) {		fprintf(stderr, "radclient: Out of memory\n");		exit(1);	}	if (!fr_packet_list_socket_add(pl, sockfd)) {		fprintf(stderr, "radclient: Out of memory\n");		exit(1);	}	/*	 *	Walk over the list of packets, sanity checking	 *	everything.	 */	for (this = radclient_head; this != NULL; this = this->next) {		this->request->src_ipaddr = client_ipaddr;		this->request->src_port = client_port;		if (radclient_sane(this) != 0) {			exit(1);		}	}	/*	 *	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 (fr_packet_list_num_elements(pl) > 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);	fr_packet_list_free(pl);	dict_free();	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 + -